如何选择 n 项内选择元素在柏树?

如果我有 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>

选择一个具有已知价值的选项,比如“职业”,就像下面这样简单:

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

如何选择该字段中的第 n 个选项,即它的值的 无论如何

121986 次浏览

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'

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()))

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.

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.

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 $().

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()
})

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();});

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.

Update 2021

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.

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)