Dom Testing library
dom-testing-library is the project used by react-testing-library to query components. react-testing-library re-exports all dom-testing-library utilities so, in the next examples, we will import from @testing-library/react instead of @testing-library/dom.
Queries
the main concept of dom-testing-library are queries, a set of utilities to find elements in the DOM. The queries are divided into three categories with different features, each category offers the same query in two versions, to query a single element and to query all matching elements.
getBy queries
getBy* queries return the first matching node found
and have two important features
- throw an error if no elements match (allow to make expectations without using expect directly)
- throw if more than one match is found (use
getAllBy*queries if you expect more elements matching).
An example:
import React from "react";
import { render } from "@testing-library/react";
function App() {
return (
<div>
<h1>Hello!</h1>
</div>
);
}
test("render app", () => {
const { getByText } = render(<App />);
getByText("Hello!");
});
queryBy queries
queryBy* queries return the first matching node found, and return null if no elements match (like document.querySelector). This is useful for asserting that an element is not present in the document.
Remember that they throws if more than one match is found (use queryAllBy* queries instead).
An example:
import React from "react";
import { render } from "@testing-library/react";
function App() {
return (
<div>
<h1>Hello!</h1>
</div>
);
}
test("render app", () => {
const { queryByText } = render(<App />);
const h1 = queryByText("Hello!");
expect(h1).toHaveTextContent("Hello!");
expect(queryByText("Goodbye!")).not.toBeInTheDocument();
});
findBy Queries
findBy* queries return a promise which resolves when an element is found which matches the given query
- will reject after 4500 ms is no matches occur
- is the combination of
getByand the utilitywaitForElement - will reject if no element is found
- will reject if more than one element is found, to find more than one element, then use
findAllBy*queries
example
import React from "react";
import { render } from "@testing-library/react";
function App() {
const [text, setText] = React.useState("start");
React.useEffect(() => {
setTimeout(() => {
setText("finish");
}, 500);
}, [text]);
return (
<div>
<h1>{text}</h1>
</div>
);
}
test("render app", async () => {
const { getByText, findByText } = render(<App />);
getByText("start");
await findByText("finish");
});
Other Utilities
wait
Calling await wait(callback) will call the callback until it resolves, rejects, or the timeout fires.
Mutation API
Some utilities based on the MutationObserver API are available to deal with cases where we have to wait for DOM elements to appear, disappear, or change.
A waitForElementToBeRemoved example:
import React from "react";
import { render, waitForElementToBeRemoved } from "@testing-library/react";
function App() {
const [show, setShow] = React.useState(true);
React.useEffect(() => {
setTimeout(() => {
setShow(false);
}, 500);
}, []);
return <div>{show ? <h1>hello</h1> : null}</div>;
}
test("render app", async () => {
const { getByText } = render(<App />);
await waitForElementToBeRemoved(() => getByText("hello"));
});
Author: Jaga Santagostino