New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to select by index within .select()
command
#757
Comments
Your options may have duplicate labels, but they have different values so you can use the value, rather than the label text in You could select the first instance of "France" with Using the value here to be more specific about which match you want makes your test deterministic. Hope this helps! |
Of course but the list is generated via Angular. The value might change. |
That does present a bit of a problem. Here is a workaround you can use for now: cy.get('#country')
.find('option[label="France"]') // this will return both elements
.then($els => $els.get(1).setAttribute('selected', "selected")) // set the selected attribute on the desired option
.parent() // change the subject back to the select
.trigger('change') // trigger change event so event handlers will pick it up I did a quick test where the drop down selection lead to another UI change with a handler for the I did that with: cy.get('#country')
.find('option[selected="selected"]')
.then($el => $el.get(0).removeAttribute('selected')) So everything together looks like: // remove current selection
cy.get('#country')
.find('option[selected="selected"]')
.then($el => $el.get(0).removeAttribute('selected'))
// Manually set desired selection
cy.get('#country')
.find('option[label="France"]')
.then($els => $els.get(1).setAttribute('selected', "selected"))
.parent()
.trigger('change') |
Haven't tried this but you could probably clean this up by doing... // Manually set desired selection
cy.get('#country').then(($select) => {
const opt = $select.find('option[label="France"]')
$select.val(opt.attr('value'))
return $select
}).trigger('change') |
Hey @dhoko, did the suggestions above solve your issue? |
I didn't debug my tests yet, I will try monday. I think it should solve it yes. I can create a custom command from the snippet. |
I tried this one -> #757 (comment) it worked. Thx. |
Even though this isssue is closed. I still think a select by index is required. Double list entries (both in value as label) is quite common as for long lists people tend to add the most used options as preferred option on top as well (same as in the example). |
@brian-mann your answer is an absolute lifesaver. I'm using Vue with Cypress and it's been nearly impossible to figure out how to use my selects - it's due to my selects having objects as their values in the code. Works great for everything but testing - until your answer. Sorta wish Cypress just let us tell it to act like a normal user and "click here" and then "click here". It doesn't let you do that on selects, and it makes things pretty tough. Thanks for your answer. |
Will reopen as feature to add 'select by index' to |
This comment has been minimized.
This comment has been minimized.
That workaround helped me, thanks! |
This definitely feels like it shouldn't need a workaround. There is nothing wrong with having options with duplicate values and labels. |
.select()
command
cy.get('#country')
.find('option[label="France"]').then(elements => {
const france = elements[0].getAttribute('value');
cy.get('#country')
.select(france);
}); |
Hey @jennifer-shehane, the lack of select by index has been annoying me so I'd like to take this issue. Would we want to add an option for index, and then default to 0? It looks like the check at line 109 could be changed to handle this pretty easily. |
@jennifer-shehane Some select tags fields on closed platforms are auto generated and out of developer control. The platform I am testing list the same values twice in select fields causing an error below. Whats the status on index based selection? I believe @tylerlinquata is willing to fix. @tylerlinquata have you opened a pull request yet? |
+1 to the select by index feature. I'm testing a select that is populated with data from an API that changes every call, so I can't select by value. |
I think this would basically accept a new argument Syntax.select(value)
.select(values)
.select(index)
.select(value, options)
.select(values, options)
.select(index, options) Argument
A number indicating the index to find the We would be open to a PR (that is fully tested). The code can be found here: https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/cy/commands/actions/select.coffee#L12 Check out our contributing doc. |
I share implemented solution selectDropDownList(cy.get('#selectedRoomNo'),4)
function selectDropDownList(dropDownList, value) {
dropDownList.then(($select) => {
debugger
$select.find('option[value="' + $select.val() + '"]')[0].removeAttribute('selected')
const opt = $select.find('option[value="' + value + '"]')
$select.val(opt[0].value)
opt[0].setAttribute('selected', '')
return $select
}).trigger('change')
} |
This is especially useful for my current usecase:
|
Take a look at https://glebbahmutov.com/cypress-examples/7.4.0/recipes/selected-value.html#selecting-option-by-index where I use the following to select by index // every child of <select> is an <option> element
cy.get('select')
.children()
.eq(1)
.then(($option) => {
const value = $option.attr('value')
// if we want to select the oranges,
// let's use the value we got
cy.get('select').select(value)
}) |
This worked for me cy.get('select').find('option[data-name="sort"]').then($el =>
$el.get(0).setAttribute("selected", "selected")
).parent().trigger("change") |
What is the reason that cy.select() does not support duplicate options? If text and value are the same, then Cypress should just select the first instance. As mentioned before, duplicating entries is a common pattern. E.g. in a countries list where the most used countries appear on top and in the full list below. Selecting by index would then be the workaround but it would be flaky because the order or number of options might be different. The workaround with the jQuery selectors did not work for me in a React project. Maybe because React uses its own event system. |
I agree with sbaechler. I think the solution is not to add index selection, but rather allow select() to specify if it is expecting duplicates and which duplicate should be chosen. |
I'm writing against a select box where the selected option is shown as the default selected element, but is disabled. The same value is shown selectable lower down in the list. In order to select the option, I need to somehow specify that I want the non-disabled one, otherwise I get an error.
|
Released in This comment thread has been locked. If you are still experiencing this issue after upgrading to |
#4239
"_from": "cypress@^1.0.1", "_id": "cypress@1.0.2",
Current behavior:
Desired behavior:
I can select this option, via an index inside the argument option.
How to reproduce:
Test code:
Additional Info (images, stack traces, etc)
I tried to create the patch myself (it seems the error is here ->
cypress/packages/driver/src/cy/commands/actions/select.coffee
Line 50 in 0e0f75c
PS: Cypress is awesome❤️
The text was updated successfully, but these errors were encountered: