10

I am trying to trigger a MUI Select using Cypress but I cannot get it to work.

I have read the MUI SelectInput source and it is clear they are triggering on "mousedown" event. I have profiled a click and seen that this is true. However, calling cy.find(input).trigger('mousedown', { force: true }) doesn't trigger the popup, nor does cy.find('label').trigger('mousedown', { force: true }), nor does grabbing any of the containing div elements and triggering mousedown on them.

If I go to the MUI example page: https://material-ui.com/components/selects/ and I inspect the DOM there and look at the elements, none of them have an onmousedown handler, and grabbing them as globals and calling temp<n>.dispatchEvent(new MouseEvent('mousedown')) doesn't trigger the popup to open. So I cannot figure out where the mousedown handler is being hooked.

What am I missing?

Thanks in advance.

2
  • In our Cypress tests, we use findByText (from Cypress Testing Library) and do cy.findByText("Text of the Select label or current selected value").click().findByText("Text of option we want to select").click(). Commented Dec 18, 2020 at 21:31
  • 3
    If it can help anyone, here is a workaround inspired from this thread to select the first element in the dropdown using the keyboard : cy.get('div.MuiSelect-root').first().type('{downarrow}{enter}') Commented Jun 18, 2021 at 14:06

6 Answers 6

9

For Cypress to fill out a Material-UI React Select component, this worked for me:

cy.get('#fooID') .parent() .click() .get('ul > li[data-value="FooBar"]') .click(); 

Replacing:

  • Foo with your MUI Select component Id
  • FooBar with the text you want selected in your dropdown bar.

This post helped point me in the right direction.

In a Material-UI React Select component the ID of the form label is wrapped/controlled by an outer div. So .get('#fooID') grabs the inner label by ID, .parent().click() clicks the root component div to reveal the dropdown, and .get('ul > li[data-value="FooBar"]').click() finds & clicks the correct item in the dropdown bar.

Sign up to request clarification or add additional context in comments.

Comments

3

Cypress documentation recommends to assign a unique data-cy prop to the elements that Cypress should interact with, so you should do that for both the select box and its options.

See the example below (assuming you're still using Material-UI v4):

The Select component:

<TextField select data-cy={`input-fruits`} defaultValue='' > { [`apple`,`banana`,`orange`].map((fruit, index) => ( <MenuItem key={`item-${index}`} value={fruit} data-cy={`select-option-${fruit}`} > {fruit} </MenuItem> )) } </TextField> 

The Cypress test:

it("should change value of select box", () => { /** Confirm that the select box is empty by default */ cy.get(`[data-cy = "input-fruits"]`).should(`have.value`, ``); /** Click on the select box, then on the option */ cy.get(`[data-cy = "input-fruits"]`).click(); cy.get(`[data-cy = "select-option-orange"]`).click(); /** Assert the new value of the select box */ cy.get(`[data-cy = "input-fruits"]`).should(`have.value`, `orange`); }); 

Comments

2

If you create select using TextField with name="myselect"

https://mui.com/material-ui/react-text-field/#select

<TextField name="myselect" select label="Select" value={currency} onChange={handleChange} helperText="Please select your currency" > {currencies.map((option) => ( <MenuItem key={option.value} value={option.value}> {option.label} </MenuItem> ))} </TextField> 

where options:

const currencies = [ { value: 'USD', label: '$', }, { value: 'EUR', label: '€', }, ]; 

Use can select option via only label:

cy.get('[name="myselect"]').parent().click(); cy.get('[id="menu-myselect"] li[role="option"]').contains("€").click(); 

Dropdown gets autogenerated id based on TextField name with prefix menu-

Comments

0

this one works for me, imagine the default text is Organization on your select and you want to choose SUN from dropdown

cy.findByText('Organization').type('SUN{enter}'); 

Comments

0
 it("should change check items per page and change it", () => { const select = '[data-testid="pagination-select"]' cy.get(select).children('input[aria-hidden="true"]').should('have.value', '10'); /** Click on the select box, then on the option */ cy.get(select).click(); cy.get('ul[role="listbox"]').children('li[data-value="8"]').click() cy.get(select).children('input[aria-hidden="true"]').should('have.value', '8'); cy.get('[data-testid="deputy-list"]').children().its('length').should('be.equal', 8) }); 

Comments

0

for me on MUI, worked this one:

cy.contains('[role="option"]', 'City').click();

So first we find a element with text "City" and with role Option and then click it

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.