cypress-testing-library icon indicating copy to clipboard operation
cypress-testing-library copied to clipboard

Queries match elements inside the <head /> part of the document

Open gnapse opened this issue 5 years ago • 6 comments

  • cypress-testing-library version: 5.3.0

Relevant code or config

<html>
  <head>
    <title>Hello world</title>
  </head>
  <body>
    <h1>Hello world</h1>
  </body>
</html>
cy.findByText('Hello world')

What you did

Find an element by its text content.

What happened

Since the document title element in the head area also matches, the query tells me that it found more than one element with the expected text content.

Problem description

The queries are using the entire document as the container.

Suggested solution

Maybe the queries should use the body as the container. Elements in the head area cannot be interacted with and are generally not visible to the user. Except maybe for the title, but there should be more declarative ways to check for it than findByText.

gnapse avatar Mar 27 '20 19:03 gnapse

Hi @gnapse

As far as I know, to only find the h1 in the body, you could do something like: cy.findByText(/hello world/i, { selector: 'h1' }).should('exist'); (The second param, 'options', is what's important here)

However, this kinda becomes testing implementation details because if you were to change the <h1> tag to a <h2> tag, your test would fail (which we would not want).

Maybe @kentcdodds has a better suggestion 😅...

Thanks, Pranjal

pranjaljately avatar May 29 '20 14:05 pranjaljately

Thanks @pranjaljately!

This would be best:

cy.findByRole('heading', {name: /hello world/i }).should('exist')

That would work regardless of the level of heading. It's also more semantically correct 🤘

kentcdodds avatar May 29 '20 15:05 kentcdodds

As for the assertion that queries should be scoped to the body, I'm curious how Cypress does this... I'm pretty sure they scope to the whole document.

kentcdodds avatar May 29 '20 15:05 kentcdodds

Awesome! Just learnt something new 😁

Thanks, @kentcdodds

pranjaljately avatar May 29 '20 15:05 pranjaljately

Indeed, the findByRole is the best approach, and a natural workaround. I started using it almost exclusively recently, after I filed this issue.

However, I'd still argue the issue remains, as the other queries are still valid queries, and a findByText(...) when a role query is not possible will still possibly yield the page title as a false positive.

gnapse avatar May 29 '20 16:05 gnapse

Well... Maybe we should do this then: https://github.com/testing-library/dom-testing-library/issues/593

kentcdodds avatar May 29 '20 17:05 kentcdodds