Home > Back-end >  Querying the React root element in React Testing Library
Querying the React root element in React Testing Library

Time:01-23

In my React component, a div with the id #keys goes from display: none to display: flex when you press / while focusing on document.

I wrote a test for that using Jest and React Testing Library:

App.tsx:

return (
    <div id="keys" style={{ display: isInputFocused ? 'flex' : 'none' }}>
        <input
            type="text"
            ref={inputRef}
            onChange={handleInputChange}
            onBlur={handleInputBlur}
            value={inputValue}
        />
        <!-- more elements -->
    </div>
);

App.test.tsx:

test('`input` is visible after pressing `/`', () => {
    render(<App />);
    fireEvent.keyDown(document, { key: '/' });

    const input = screen.getByRole('textbox', { hidden: true });

    expect(input).toBeVisible();
});

As you can see, in my test, I'm querying the input inside #keys instead of #keys. If I want to query #keys in the RTL way, I have to add role or data-testid to #keys.

Question 1: That's the best way to query #keys? So that I'm testing the visibility of #keys instead of the input inside it? (Without having to add role or data-testid to it?)

Question 2: Or maybe according to RTL's philosophy, I'm not supposed to be testing #keys but the input inside it?

CodePudding user response:

1 - You can still use "normal" dom queries in RTL although it is not recommended as mentioned in the docs:

const { container } = render(<MyComponent />)
const keys = container.querySelector('#keys');

You can also use parentElement or parentNode but I think that falls under the same category as above

const keys = screen.getByRole('textbox').parentElement;

2 - Like you suspected, RTL's philosophy is querying and testing elements that are visible and matter to the users of your app which means that if you are unable to query those elements with high priority queries you either don't need to test them or you need to improve their accessibility:

RTL docs (from the first link I shared)

Note that using this as an escape hatch to query by class or id is not recommended because they are invisible to the user.

Your keys element is just a container and doesn't have any significance to the end user, on the other hand the inputs inside of it are the elements the user is going to be interacting with, which means they should be the ones being tested for behavior and visibility.

  • Related