'How can I get Cypress to interact with the Material-UI Rating component?

I'm trying to use Cypress to test a form that includes the Material-UI Rating component, but I can't find a way to get it to select a rating. As a stripped down example, I have the following React component:

const TestRating = () => {
  const [value, setValue] = useState(null);
  return (
    <>
      <Rating name='testrating' onChange={(event, newValue) => setValue(newValue)} />
      <div>The value is {value}</div>
    </>
  );
};

In a normal browser this behaves as expected, updating the text in the div when you click on a star.

I've tried all sorts of different ways to interact with the Rating in Cypress, but all have failed. In particular:

cy.contains('label', '5 Stars').click();       // Appears to act like a hover, making the stars fill in but not updating the value
cy.get('[value="5"]').click();                 // Fails because the element is hidden from view
cy.findByLabelText('5 Stars').click();         // Fails because the element is hidden from view
cy.get('.MuiRating-icon').last().click();      // Fails because the element has CSS pointer-events: none
cy.get('[value="5"]').click({ force: true });  // Appears to have no effect

I've tried using .realMouseDown() and realClick() from cypress-real-events but this hasn't helped - in all cases the event doesn't seem to do anything. From the same library I also did this:

cy.realPress('Tab');
cy.realType('{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}');

which also acted like hovering, in that it fills in the stars but doesn't change the value.

In a lot of the cases where Cypress is doing a .click() it's registering it to a point at the top-left corner of the Rating, quite far away from the 5th star. Presumably Material-UI is hiding the input elements up here.

Is it possible to get Cypress to work with the Rating component, and if so, how?



Solution 1:[1]

I had the same problem. I think I solved with:

cy.get(".MuiRating-visuallyHidden").first().click({force: true})

The force: true on clicking was necessary because I got an error saying that "the element is being covered by another element".

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Elanor