reactjsreact-testing-library

Get by HTML element with React Testing Library?


I'm using the getByTestId function in React Testing Library:

const button = wrapper.getByTestId("button");
expect(heading.textContent).toBe("something");

Is it possible / advisable to search for HTML elements instead? So something like this:

const button = wrapper.getByHTML("button");
const heading = wrapper.getByHTML("h1");

Solution

  • I'm not sure what wrapper is in this case. But to answer your two questions: yes it's possible to get by HTML element and no, it's not advisable.

    This is how you would do it:

    // Possible but not advisable
    const { container } = render(<MyComponent />)
    // `container` is just a DOM node
    const button = container.querySelector('button')
    

    Since you get back a DOM node you can use all the normal DOM APIs such as querySelector.

    Now, why is this not advisable. A big selling point of react-testing-library is that you test your components as a user does. This means not relying on implementation details. For instance, you don't have direct access to a component's state.

    Writing tests this way is a bit harder but allows you to write more robust tests.

    In your case, I would argue that the underlying HTML is an implementation detail. What happens if you change your HTML structure so that the h1 is now an h2 or a div? The test will break. If instead, you look at these elements by text the tag becomes irrelevant.

    In some cases, the normal query helpers are not enough. For those events you can use a data-testid and use getByTestId.