-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
toBeVisible
not working as expected with visibility
property
#209
Comments
The codesandbox does not use any of the code you described. Don't forget to save and freeze the codesandbox after submission. I suspect this is an issue with |
@eps1lon thanks for letting me know, just included a test example there. |
Perfect. This is indeed a bug. We're currently assuming that We need to account for that now that JSDOM implements CSS inheritance. |
I've tried to implement but I think JSDOM CSS inheritance doesn't work correctly. By default all elements have <section style="display: block; visibility: hidden">
<p>Hello <strong>World</strong></p>
</section>
|
Which jsdom version are you using? It should be working with |
For |
I prefer additional tests over changing existing ones. This way we make sure we don't regress. |
The problem is that implementing this functionality as if the inheritance works will break these tests because it relies on inline styles instead of declared ones. |
Write two tests then and comment the wrong one properly so that it is obvious that it will break once jsdom is fixed. |
I don't currently have time to set up a sandbox repro, but this same assertion is failing for me when Stylesheet (imported directly into component definition file): .Dialog {
opacity: 0;
// ...
.Dialog--open {
opacity: 1;
// ...
}
} And test output failure (verified other classes not setting
|
Is there any update on this, or a workaround. I've posted a CodeSandbox with minimal code on StackOverflow reproducing the issue |
That stackoverflow question is about |
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. |
@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 expect(screen.getByTestId('backdrop')).toHaveStyle({ position: 'absolute' }) |
It's working in styled-component v5.2.1, see this issue |
Thanks for letting us know @tatinacher. I'll close this issue now. |
Hey 👋, I think there's been a mistake. This issue has nothing to do with styled-components (only my example). As you can see in the CodeSandbox, I've updated all the dependencies and it seems that the issue persists. |
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 |
Not sure i got same bug here or no But seem due to this issue, Below is my code : import styled from "styled-components";
const Container = styled.a`
display: flex;
width: 50px;
height: 50px;
background-color: #0f0;
&:hover {
background-color: #f00;
}
`;
const HoverVisibleElement = styled.button`
padding: 0px;
margin: 0px;
outline: 0px;
border: 0px;
width: 10px;
height: 10px;
background-color: #00f;
visibility: hidden;
${Container}:hover & {
visibility: visible;
}
`;
export default function App() {
return (
<Container>
<HoverVisibleElement />
</Container>
);
} In browser it working well by hover then button become visible and unhover it hidden. But in test below: import App from "./App";
import "@testing-library/jest-dom/extend-expect";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/userEvent";
it("Show button when hover link", async () => {
render(<App />);
expect(screen.queryByRole("button")).toBeNull();
userEvent.hover(screen.getByRole("link"));
await expect(screen.findByRole("button")).resolves.toBeVisible();
}); it would fail because |
Here is a simple test to reproduce this bug import styled from "@emotion/styled";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
const Container = styled("div")`
position: relative;
&:hover {
& .child {
visibility: visible;
}
}
`;
const Child = styled("div")`
visibility: hidden;
`;
function Test() {
return (
<Container data-testid="container">
<p>Test</p>
<Child className="child" data-testid="child">
Child
</Child>
</Container>
);
}
it("doesn't detect style changes applied from a parent to child", async () => {
render(<Test />);
const container = screen.getByTestId("container");
expect(container).toBeInTheDocument();
/*
these two lines passes the assertion
which confirms that styles are loaded
*/
expect(screen.getByTestId("child")).not.toBeVisible();
expect(screen.getByTestId("child")).toHaveStyle({
visibility: "hidden",
});
/*
when container is hovered, it applies the styles to the child
using CSS descendant selector.
*/
userEvent.hover(container);
/*
JSDOM not picking up styles applied to child through CSS descendant selector,
so the child is not visible
*/
expect(await screen.findByTestId("child")).toBeVisible(); // <--- only this line fails
}); |
I've got a PR ready that fixes this issue: #428 |
BTW, @codewaseem, your example is not related to this issue. It does not involve the I believe your example is suffering from the issue that CSS from styled-components or emotion are not loaded in the DOM in the context of jest tests. |
@gnapse , thanks for your response! I have updated my example to use expect(screen.getByTestId("child")).not.toBeVisible();
expect(screen.getByTestId("child")).toHaveStyle({
visibility: "hidden",
}); which confirms styles are loaded. Only the last line fails. I think the issue is, styles that are applied to a child using css descendent selector are not being detected. This is regardless of specific property. UPDATE: This is working in pure css setup in codesandbox. There might be some issue in my configuration or emotion. |
If it's something that you can reproduce regardless of it being related to the |
Sorry, I see this issue is still in open. Any update about this issue? |
Here's an absolutely minimal example of how document.body.innerHTML = `
<svg>
<g id="my-element" visibility="hidden" />
</svg>`;
// yep, this assertion fails.
expect(document.getElementById('my-element')).not.toBeVisible(); Also in Code Sandbox. My best guess is that this is a bug in jsdom itself, because the computed style for |
Same problem here with opacity. |
I am using const Button = forwardRef(({ isLoading, children }, ref) => {
return (
<button className={cn("[&.btn-is-loading>[data-slot=children]]:invisible", isLoading && "btn-is-loading")}>
{isLoading ? (
<span
data-slot="children"
children={children}
/>
) : (
children
)}
</button>
);
});
it("should hide children content when loading", () => {
render(<Button isLoading>children</Button>);
const content = screen.getByText("children", { selector: '[data-slot="children"]' });
expect(content).not.toBeVisible();
}); does anyone have any idea what I might have done wrong? |
Are you certain that the CSS generated from tailwind CSS classes is loaded and attached to the |
Can you debug it further, but adding something along these lines to your test? const element = screen.getByText("children", { selector: '[data-slot="children"]' })
// Get the window associated with the element
const elementWindow = element.ownerDocument.defaultView;
// Now you can use the window's getComputedStyle method
const computedStyles = elementWindow.getComputedStyle(element);
console.log('styles', computedStyles)
console.log('visibility', computedStyles.visibility) |
it does not see the element visibility as
is there a way to check the generated class names in the element document? |
As suspected, the CSS generated from tailwind CSS classes is not attached to the document in which the components are mounted during the tests. Without that CSS code being attached to the This is a known limitation. And unfortunately, due to the various ways in which CSS can be loaded in the document at run time (CSS-in-JS, CSS generated at build time, etc.) this falls out of jest-dom's scope. Not much we can do. |
then, is there any workaround or a recommended way to test the element visibility? {isLoading ? (
<span
data-slot="children"
style={{
visibility: "hidden"
}}
children={children}
/>
) : (
children
)} but the icon is a user-provided component and it only has a data-att selector smth like: <svg
data-slot="icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<!--icon-->
</svg> so to toggle icon visibility, I am selecting the element using data-att and class name: .some_class [data-slot=icon]:invisible {
visibility: "hidden";
} what is your workaround to be sure the icon is invisible? |
Maybe you can trust that the CSS is ok, and test for the presence or absence of the relevant class names instead? expect(element).toHaveClass('visible')
expect(element).toHaveClass('invisible') This would not be a true end-to-end test, as it won't test that the CSS to truly make the visibility change effective is there, but since you're using tailwind (which automatically takes care of loading any CSS for any of its classes that you end up using) then that'd be good enough. Is it? |
You can also remove unused dom elements and use |
@testing-library/jest-dom
version: v5.1.1@testing-library/react
version: v9.4.0node
version: v12.14.1npm
(oryarn
) version: v1.21.1Relevant code or config:
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 hasvisibility: 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.
The text was updated successfully, but these errors were encountered: