How can I test the Material-UI tooltip with cypress?

Viewed 459

We use tooltips a lot and I wanted to use the tooltip text to find elements. This works fine the first time, as the tooltip text is just in the title in the element. But on mouse over the title proprerty is removed and a new tooltip element is added at the bottom of the page. After issueing a click on the element, the mouse stays over it and the next time I can't find it by the title.

Without mouse over:

<span class="" title="Save changes">
   ...
</span>

with mouse over:

<span class="" aria-describedby="mui-97465">
   ...
</span>
...
<div role="tooltip" class="MuiTooltip-popper" id="mui-97465" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(3063px, 116px, 0px);" x-placement="bottom">
    <div class="MuiTooltip-tooltip MuiTooltip-tooltipPlacementBottom" style="opacity: 1; transform: none; transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 133ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;">
       Save changes
    </div>
</div>

I tried building my own command, but that doesn't work either:

Cypress.Commands.add("findByTooltip", (text) => {
  cy.get("body")
    .then(($body) => {
      $body.find(`[title="${text}"]`).length > 0;
    })
    .then((byTitle) => {
      byTitle
        ? cy.findByTitle(text)
        : cy
            .findByRole("tooltip")
            .contains(text)
            .its("id")
            .then((id) => cy.get(`[aria-describedby=${id}]`));
    });
});

Has anyone done something like this?

1 Answers

This part is missing a return value

.then(($body) => {
  $body.find(`[title="${text}"]`).length > 0;
})

so either

.then(($body) => {
  return $body.find(`[title="${text}"]`).length > 0;
})

or remove the brackets for "implied return"

.then(($body) => $body.find(`[title="${text}"]`).length > 0 )

I'm not sure title="Save Changes" is on the page DOM, at least the one MUI example is missing that attribute.

I would go for the aria-label

.then(($body) => $body.find(`[aria-label="${text}"]`).length > 0 )

To make the tooltip show, you need a hover of some kind. The most reliable seems to be cypress-real-events

cy.get((`[aria-label="${text}"]`)).realHover();
cy.findByRole("tooltip")
  .contains(text)
  .its("id")
  .then((id) => cy.get(`[aria-describedby=${id}]`))
Related