jest-dom: `toBeVisible` not working as expected with `visibility` property
@testing-library/jest-dom
version: v5.1.1@testing-library/react
version: v9.4.0node
version: v12.14.1npm
(oryarn
) version: v1.21.1
Relevant code or config:
import styled from 'styled-components';
const Container = styled.div`
visibility: hidden;
&:hover {
visibility: visible;
}
> input:checked {
visibility: visible;
}
`;
const { getByTestId } = render(
<Container>
<input data-testid="checkbox" type="checkbox" checked />
</Container>
);
expect(getByTestId('checkbox')).toBeVisible();
What you did:
Tried to test a checkbox that must be visible when it has been checked with toBeVisible
.
What happened:
Even though the checkbox is visible toBeVisible
throws an error because it detects that the parent has visibility: hidden
.
Reproduction:
https://codesandbox.io/s/kind-rain-62otm?fontsize=14&hidenavigation=1&previewwindow=tests&theme=dark
Problem description:
My code has a checkbox that must be visible when the user checks it. The visibility property is perfect for this because it overrides its parents’ values.
So, if the checkbox has visibility: visible
property, it will be shown regardless of the parent value.
Suggested solution:
Not sure 😦 will come up with something if this is really an issue.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 25
- Comments: 38 (17 by maintainers)
Commits related to this issue
- test(modal): fix invalid test case https://github.com/testing-library/jest-dom/issues/209 — committed to sungik-choi/bezier-react by sungik-choi 6 months ago
Perfect. This is indeed a bug.
We’re currently assuming that
visibility
acts likedisplay
. Whiledisplay: none
hides any child even if they do setdisplay: block
,visibility: hidden
can be overridden. The difference betweendisplay
andvisibility
is thatvisibility
is an inherited CSS property whiledisplay
is not.We need to account for that now that JSDOM implements CSS inheritance.
Here’s an absolutely minimal example of how
.toBeVisible()
is failing for me, with inline SVG:Also in Code Sandbox.
My best guess is that this is a bug in jsdom itself, because the computed style for
visibility
ofmy-element
ends up beingvisible
here: https://github.com/testing-library/jest-dom/blob/main/src/to-be-visible.js#L6Same problem here with opacity.
@MarcoLeko you may be experiencing an additional issue where styles from a stylesheet are not loaded automatically in jest/jsdom test env where you load and test the component in isolation. Check this comment and let me know if that helps. To confirm if the stylesheet is loaded, can you confirm that you can assert
toHaveStyles
with other properties that should be there no matter what? For instance, based on the example in the SO question, does this assertion passes if you add it to your test right after rendering?I’ve got a PR ready that fixes this issue: https://github.com/testing-library/jest-dom/pull/428
Oh ok, sorry. The signal here got lost between all the noise of styled components and the concern about stylesheets being loaded or not.
Indeed, it is a mistake that we treat parent lack of visibility as final, when in fact visibility, as opposed to
display: none
, can be overridden by child elements.Is there any progress on this? I am also facing the same issue and put up a question with all relevant infos here: https://stackoverflow.com/questions/64026278/react-jest-rtl-check-if-element-is-not-visible
Btw. react testing library only reacts to styling changes when, I am using inline-styling in the react comp.
It’s working in styled-component v5.2.1, see this issue