How can I test whether or not a React component is visible in the DOM when that component is hidden using a CSS transition with transform: scale(0)
?
jest-dom
has a .toBeVisible()
matcher, but this doesn't work because transform: scale(0)
is not one of the supported visible/hidden triggers. Per the docs:
An element is visible if all the following conditions are met:
- it is present in the document
- it does not have its css property
display
set tonone
- it does not have its css property
visibility
set to eitherhidden
orcollapse
- it does not have its css property
opacity
set to 0- its parent element is also visible (and so on up to the top of the DOM tree)
- it does not have the
hidden
attribute- if
<details />
it has theopen
attribute
I am not using the hidden
attribute because it interfered with my transition animations. I am using aria-hidden
, but that is also not one of the supported triggers.
The simplified version of my component is basically this. I am using Tailwind CSS for the transform and the transition.
import React from "react";
import clsx from "clsx";
const MyComponent = ({isSelected = true, text}) => (
<div
className={clsx(
isSelected ? "transform scale-1" : "transform scale-0",
"transition-all duration-500"
)}
aria-hidden={!isSelected}
>
<span>{text}</span>
</div>
)
I could potentially check for hidden elements with:
toHaveClass("scale-0")
toHaveAttribute("aria-hidden", true)
But unlike toBeVisible
, which evaluates the entire parent tree, these matchers only look at the element itself.
If I use getByText
from react-testing-library
then I am accessing the <span>
inside the <div>
rather than the <div>
which I want to be examining. So this doesn't work:
import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import { MyComponent } from "./MyComponent";
it("is visible when isSelected={true}", () => {
const {getByText} = render(
<MyComponent
isSelected={true}
text="Hello World"
/>
);
expect(getByText("Hello World")).toHaveClass("scale-1");
});
What's the best way to approach this?