How to trigger Material UI Select in Cypress

Viewed 4327

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.

3 Answers

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.

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

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}');
Related