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.