cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.66k stars 3.16k forks source link

A way to select the first matching option when the select element contains multiple options with the same label or value #29823

Open esetnik opened 1 month ago

esetnik commented 1 month ago

What would you like?

There's no obvious way to select the option 'NREMT' when the options list contains multiple elements with the same label for example below:

<select>
<option value="">Select Certification</option>
<option value="74">NREMT</option>
<option value="73">State EMS Certification</option>
<option value="76">AHA ACLS (ALS only)</option>
<option value="78">AHA ACLS (Experienced Provider)</option>
<option value="74">NREMT</option>
</select>

Current:

  cy.get('select').select('NREMT');

Desired option: Introduce an option to .select() which allows for the first matching option to be selected when multiple matches are detected. This could be made false by default which is typically the expected behavior for most <select> elements that shouldn't contain duplicate matches and which would preserve the current behavior of generating an error.

  cy.get('select').select('NREMT', {multipleMatchesAllowed: true});

Workaround we are using:

  cy.get('select')
    .then(($select) => {
      cy.wrap($select)
        .find('option') // Find all options within the select element
        .contains(name) // Find the option that contains the specified name
        .first()
        .should('exist') // Ensure the option exists
        .then(($option) => {
          cy.wrap($select).select($option.index()); // Select the option by its index
        });
    });

Why is this needed?

This is a valid use case for a <select> element to contain duplicate options. There's currently no way to tell cypress that it should select the first matching instance. Currently cypress fails with an error:

cy.select() matched more than one option by value or text: NREMT

Other

jennifer-shehane commented 1 month ago

You can pass a Number to .select() to select a specific index. But yah, there’s no way to query multiple options then choose to select a subset of those.

esetnik commented 1 month ago

You can pass a Number to .select() to select a specific index. But yah, there’s no way to query multiple options then choose to select a subset of those.

@jennifer-shehane I don't think that's exactly what we're looking for. We're looking for a way to ignore the error when multiple elements match the text or value of an option in the select. There's a valid use case for having duplicate entries in a select list, e.g. a list of countries with USA listed both at the top of the list as well as in alphabetical order. This is done commonly as a convenience in forms. Cypress should be able to select "USA" even if it appears twice in the list. Currently there's no way to do so without resorting to hacks.