testing-library / dom-testing-library

🐙 Simple and complete DOM testing utilities that encourage good testing practices.
https://testing-library.com/dom
MIT License
3.26k stars 467 forks source link

getByAltText() does not work in Jest if another query executes before it #1129

Closed martenmatrix closed 2 years ago

martenmatrix commented 2 years ago

Relevant code or config:

import { render, screen } from '@testing-library/react';

render(
    (
        <>
            <h2>Test</h2>
            <img alt="a cool project 1 being used" />
        </>
    )
);

test('get the heading', () => {
    screen.getByRole('heading');
}); // if this test is skipped the other will succeed

test('get the image by alt text', () => {
    screen.getByAltText(/a cool project 1 being used/i);
});

What you did:

I've created two tests that both query an element from the rendered body. It is important that the test which gets the element by a role is before the test which gets its element by the text contained in the alt attribute.

What happened:

If the test which uses getByRole is skipped or runs after the test using getByAltText() nothing happens.

However, if all tests run, getByAltText() fails with the following error message. It is important that the test using getByAllText() runs after another test using a query.

    TestingLibraryElementError: Unable to find an element with the alt text: /a cool project 1 being used/i

    Ignored nodes: comments, <script />, <style />
    <body />

      15 |
      16 | test('get the image by alt text', () => {
    > 17 |     screen.getByAltText(/a cool project 1 being used/i);
         |            ^
      18 | });

      at Object.getElementError (node_modules/@testing-library/dom/dist/config.js:38:19)
      at node_modules/@testing-library/dom/dist/query-helpers.js:90:38
      at node_modules/@testing-library/dom/dist/query-helpers.js:62:17
      at getByAltText (node_modules/@testing-library/dom/dist/query-helpers.js:111:19)
      at Object.<anonymous> (src/__tests__/delete.test.js:17:12)

Reproduction:

  1. npx create-react-app@5.0.0
  2. Create a file called name.test.js and paste the code above
  3. Run npm test name.test.js

Problem description:

The test fails because it is unable to find the element, however, the element exists and is also shown when running screen.debug().

Suggested solution:

I'm sorry. :(

timdeschryver commented 2 years ago

React Testing Library has an auto-cleanup (cleanup) that runs after every test. It's better to call the render method in every test suite, instead of one single time.

test('get the heading', () => {
  render(
    <>
      <h2>Test</h2>
      <img alt="a cool project 1 being used" />
    </>,
  )

  screen.getByRole('heading')
})

test('get the image by alt text', () => {
  render(
    <>
      <h2>Test</h2>
      <img alt="a cool project 1 being used" />
    </>,
  )

  screen.getByAltText(/a cool project 1 being used/i)
})

Or, add multiple asserts in a single suite:

test('get the heading', () => {
  render(
    <>
      <h2>Test</h2>
      <img alt="a cool project 1 being used" />
    </>,
  )

  screen.getByRole('heading')
  screen.getByAltText(/a cool project 1 being used/i)
})
martenmatrix commented 2 years ago

Sorry and thanks!