111

say I have the HTML:

<select name="subject" data-testid="contact-us-subject-field">
  <option value="What is this regarding?">What is this regarding?</option>
  <option value="Partnerships">Partnerships</option>
  <option value="Careers">Careers</option>
  <option value="Press">Press</option>
  <option value="Other">Other</option>
</select>

Selecting an option with a known value, such as 'Careers' is as easy as:

cy.get('[data-testid="contact-us-subject-field"]').select('Careers');

How do I select the nth option in this field, regardless of its value?

12 Answers 12

147

Update

As pointed out by @dpstree in the comments, this doesn't answer the original question. Please see more recent answers for a complete solution.

Original

By using eq

cy.get('tbody>tr').eq(0)    // Yield first 'tr' in 'tbody'
cy.get('ul>li').eq(4)       // Yield fifth 'li' in 'ul'
Sign up to request clarification or add additional context in comments.

7 Comments

Is eq an abbreviation? What does it mean?
As mentioned by the documentation page I linked, the term comes from jQuery. So you may be interested in this post
This doesn't select anything. It does demonstrate the .eq() syntax that is needed as part of the solution, but misses the important context of needing to manipulate the select. See Robert or Miguel's solution below.
My word, you're right, I must have read the question too quickly. Will edit to point this out.
Just remember that if you save this selection to a variable, it won't work. const mySelection = cy.get('tbody>tr') ; mySelection.eq(0); mySelection.eq(1) --> the will be no second element. You need to call a selection function again
|
57

In the particular context of selecting the nth option, this may be appropriate:

cy.get('select[name=subject] > option')
  .eq(3)
  .then(element => cy.get('select[name=subject]').select(element.val()))

1 Comment

Exactly what I was looking for, please note that soon there might be an easier solution github.com/cypress-io/cypress/issues/757. Small suggestion for @Robert to use cy.wrap() + parents() to not duplicate the selector: .eq(2).then(($el) => cy.wrap($el).parent('select').select($el.val())).
28

Based on solution from Miguel Rueda, but using prevSubject option:

Cypress.Commands.add(
  'selectNth',
  { prevSubject: 'element' },
  (subject, pos) => {
    cy.wrap(subject)
      .children('option')
      .eq(pos)
      .then(e => {
        cy.wrap(subject).select(e.val())
      })
  }
)

Usage:

cy.get('[name=assignedTo]').selectNth(2)

Explanation:

  • Using children('option') and .eq(pos) traverse children of select to specific element.
  • Call select method with value of selected element.

Comments

24

You can now select an option by index within the .select(index) command:

cy.get('select').select(0)        // selects by index (yields first option) ie "What is this regarding?"
cy.get('select').select([0, 1])   // select an array of indexes

This should be easy now with the release of cypress v8.5.0. See documentation for more.

1 Comment

And what if I have a dynamic selectbox and want to select last option and don't know its name or value?
11

I had the same problem and solved it by creating a custom cypress command. No as pretty as I would like, but it did the job.

Cypress.Commands.add("selectNth", (select, pos) => {
  cy.get(`${select} option +option`)
    .eq(pos)
    .then( e => {
       cy.get(select)
         .select(e.val())
    })
})

then I used in the test as such

    cy.viewport(375, 667)
      .selectNth("customSelector", 3)

The option +option part was the only way I could find to get the full list of options inside a select and it's currently the bit of code i'm trying to work arround although it works fine.

Comments

8

since the working answers are using then anyways, eq or something fancier is redundant with array indexing...

// to click on the 1st button
cy.get('button').then($elements => {cy.wrap($elements[0]).click();});
// to click on the 4th tr
cy.get('tr').then($elements => {cy.wrap($elements[3]).click();}); 
// to click on the last div:
cy.get('div').then($elements => {cy.wrap($elements[$elements.length - 1]).click();});

1 Comment

finally, one that works. in my case: cy.wrap($recordings[0]).findByRole('button', { name: 'Remove' }).click({ force: true })
3

Let's assume you wanna select 2nd option, you can do that simply by this

cy.get("select option").eq(2)

just keep in mind that cy.get() works like jquery's $().

1 Comment

Index number starts on 0. If you want the 2nd element, then you do this: cy.get("select option").eq(1)
3

Find dropdown using ID or Class -

cy.get('#ID').contains("dowpdown placeholder or name").click();

After Click dropdown result dropdown element will popup, find that result ID or Class using inspect element, Then -

cy.get('#result-ID').children().first().click();

This will click on the first element of the dropdown.

1 Comment

How can I get the second instead of .first()? Thanks!
1

You can also rely on the :nth-child css pseudo-class:

cy.get("[data-testid="contact-us-subject-field"] option:nth-child(2)").click();

It's probably less flexible than using the cypress constructs but it is nice and clean. (And doesn't make me crawl through the cypress docs)

Comments

0

Capture all the elements in the drop-down using a selector. Get the length. Use math.random() to randomly get a number. Select the option at the index.

cy.get("ul > li").as("options")
cy
.get("@options")
.its('length')
.then(len => Math.floor(Math.random() * Math.floor(len)))
.then((index) => {
cy.get("@options").eq(index).click()
})

Comments

0

if you are looking a value to select then you cannot use .eq(), you need to use .contains() .eq() is only for numbers(indexes)

Example: cy.get(dropdownOptions).contains(some_value).click()

Comments

0

If you look for the nth option in the select dropdown, for example, in case the data is dynamically changed and you want to select the nth one, whatever the content may be, you can use this syntax:

App

<select name="mySelect">
  <option value="option_1">option 1</option>
  <option value="option_2">option 2</option>
  ...
  <option value="option_n">option n</option>
  ...
</select>

Spec

cy.get("[name='mySelect'] option:nth-of-type(n)")
.invoke("text")
.then((text) => {
  cy.get("[name='mySelect']").select(text);
});

And note that n is the order of the option that you want to select. The count start from 1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.