reactjsreact-testing-library

Jest and React Testing Library, how to test if an element is hidden?


I have a popover showing on Hover and I want to test it with Jest and React Testing Library to see if the element is hidden by default.

When I test manualy everything is ok by not when I test it with RTL.

I tried using not.toBeInTheDocument and not.toBeVisible but it seems that the element is always present in the DOM, any idea of how could I remove it from the DOM

JSX code:

<label
  htmlFor="terms_and_conditions"
  className="terms_and_conditions_box"
>
  I agree with{" "}
  <span className="terms_and_conditions_text" style={{ color: "blue" }}>
    Terms and conditions
  </span>
  <div className="pop_over">No ice cream will be delivered</div>
</label>

CSS code:

.terms_and_conditions_text:hover + .pop_over {
  display: block;
}

.pop_over {
  background: rgb(199, 196, 196);
  padding: 2rem;
  width: 14rem;
  border-radius: 15px;
  position: absolute;
  right: -18rem;
  top: -2rem;
  display: none;
}

TEST code:

test("popover responds to hover", () => {
  render(<SummaryForm />);

  //* popover initially is hidden
  const nullPopover = screen.queryByText(/No ice cream will be delivered/i);
  expect(nullPopover).not.toBeInTheDocument();
});

Solution

  • I have reproduced your code and for me the test does not work with toBeInTheDocument, but works with toBeVisible as long as display: none is there.

    Here is the code of my test file, the first test does not pass, the second passes:

    import React from "react";
    import { render, screen } from "@testing-library/react";
    import "@testing-library/jest-dom/extend-expect";
    import SummaryForm from "./App";
    
    describe("popover responds to hover", () => {
      test("popover initially is hidden (test with toBeInTheDocument)", () => {
        render(<SummaryForm />);
        const nullPopover = screen.queryByText(/No ice cream will be delivered/i);
        expect(nullPopover).not.toBeInTheDocument();
      });
    
      test("popover initially is hidden (test with toBeVisible)", () => {
        render(<SummaryForm />);
        const nullPopover = screen.queryByText(/No ice cream will be delivered/i);
        expect(nullPopover).not.toBeVisible();
      });
    });
    

    And here is the codesandbox where you can see it in action.