ByText finds children of hidden elements
See original GitHub issue@testing-library/react
version: 11.1.0- Testing Framework and version:
I am using the built-in testing tools that come with
create-react-app
@testing-library/jest-dom
: 5.11.4@testing-library/user-event
: 12.1.10react-scripts
: 4.0.3jest
: 26.6.0 (hoisted fromreact-scripts
) - DOM Environment:
jsdom
: 16.4.0
Relevant code or config:
Consider this collapsible element with aria-hidden attribute that displays children props
<div
aria-hidden={isCollapsed}
className={isCollapsed ? "hide" : "show"}
>
{children}
</div>
This assertion fails
expect(screen.queryByText("children")).toBeNull();
What you did:
When using screen.queryByText("children")
I expected not to find hidden elements that specify aria-hidden={isCollapsed}
attribute.
However, when running the test I could see that the element was found.
What happened:
I got the following failed test:
● collapses and expands children
expect(received).toBeNull()
Received: <div aria-hidden="true" class="hide">children</div>
5 | test('collapses and expands children', () => {
6 | render(<Collapsible>children</Collapsible>)
> 7 | expect(screen.queryByText("children")).toBeNull();
| ^
8 |
9 | userEvent.click(screen.getByRole("button", { name: "Expand" }));
10 | expect(screen.getByText("children")).toBeInTheDocument();
at Object.<anonymous> (src/__tests__/index.test.js:7:42)
Reproduction:
I reproduced this issue in this repo: https://github.com/mancristiana/dom-testing-library-template
Problem description:
Since the findByRole
query supports this scenario, I expected this would be true for other queries.
The current behavior is a problem because it does not reflect the way a user would interact with our application. In this concrete example, a hidden element would not appear for the user, whereas our test finds it in the dom tree.
Suggested solution:
Seeing how this behavior is supported for ByRole
queries I suggest implementing something similar for ByText
query.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:5
- Comments:6 (4 by maintainers)
It is not always possible to use the
byRole
. Consider this scenario where we have two matching paragraphs in the document containing ‘TEXT’.The first one with
class="visuallyHidden"
might inside a section with aria-live polite optimized for screen readers, whereas the other one witharia-hidden="true"
appears visually, but is hidden from screen readers.I would expect that
expect(screen.getByText('TEXT')).toBeInTheDocument();
finds only one paragraph.Thanks for the feedback but we’re not going to implement this.
ByRole
already does what you want and has specified behavior. Just consideringaria-hidden
inByText
is just fragmenting how “a11y tree inclusion” is computed in this library and causes surprising behavior. Considering a11y tree inclusion just likeByRole
does comes with perf drawbacks outlined in https://github.com/testing-library/dom-testing-library/issues/929#issuecomment-817086144.Before, people would need to know whether a query considers a11y tree inclusion or not. Now they would also need to know how a11y tree inclusion is computed depending on the query.