testing-library / cypress-testing-library

🐅 Simple and complete custom Cypress commands and utilities that encourage good testing practices.
http://npm.im/@testing-library/cypress
MIT License
1.8k stars 153 forks source link

The findByRole does not match the expectation #178

Closed nemonemi closed 3 years ago

nemonemi commented 3 years ago

Relevant code or config

// doesn't work
    cy.getIframeBody()
      .findByRole('button', { name: /Hover me!/ })
      .should('exist');

// works
    cy.getIframeBody()
      .findByText(/Hover me!/)
      .should('exist');

// Iframe custom command
// https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/
Cypress.Commands.add('getIframeBody', () => {
  // get the iframe > document > body
  // and retry until the body element is not empty
  return (
    cy
      .get('#storybook-preview-iframe')
      .its('0.contentDocument.body')
      .should('not.be.empty')
      // wraps "body" DOM element to allow
      // chaining more Cypress commands, like ".find(...)"
      // https://on.cypress.io/wrap
      .then(cy.wrap)
  );
});

What you did: I'm asserting that the button exists.

What happened: It works when I query for it by text, but not by role.

image

Reproduction repository:

Problem description: The problem is that it finds the button and registers that its title is its name. I was expecting that the content of the button would be the identifier.

Also, if I would select the button with findByText and trigger mouseover, it works:

    cy.getIframeBody()
      .findByText(/Hover me!/)
      .trigger('mouseover');

    cy.getIframeBody()
      .findByRole('button', { name: /Hover me!/ })
      .trigger('mouseover');

but not if I try to verify if the button exist with .should('exist') or .should('be.visible'), which I find strange a behavior.

Meemaw commented 3 years ago

I've been having issues with using cypress-testing-library queries inside iframes as well.

nemonemi commented 3 years ago

This issue has nothing to do with the cypress-testing-library. I have ended up solving the iframe problem by defining a custom command which accesses said iframe and returns it as a chainable selector. Here's a blog post from Cypress talking about it, and the piece of code that I've used. Hope this helps.

https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/

Cypress.Commands.add('getIframeBody', () => {
  // get the iframe > document > body
  // and retry until the body element is not empty
  return (
    cy
      .get('#storybook-preview-iframe')
      .its('0.contentDocument.body')
      .should('not.be.empty')
      // wraps "body" DOM element to allow
      // chaining more Cypress commands, like ".find(...)"
      // https://on.cypress.io/wrap
      .then(cy.wrap)
  );
});

And then consume it like this:

cy.getIframeBody()
      .findByText(/This is a snackbar with a string message/)
      .should('exist');