Proposal for jest assertions based on @testing-library/dom
queries. Below is a fictitious README if it were packaged seperately.
Unofficial @testing-library/dom
assertions for Jest that complement @testing-library/jest-dom
and make this advice easier to follow:
Advice: If you want to assert that something exists, make that assertion explicit.
Install this library with its peer dependency using a package manager such as yarn:
yarn add --dev @testing-library/jest-dom-query @testing-library/dom
Import the main module for side effects within a test suite. Alternatively, import it once for all suites using the setupFilesAfterEnv
option.
import "@testing-library/jest-dom-query";
Pass a container element to expect
and assert on the existence of child elements.
const dialog = screen.getByRole("dialog");
expect(dialog).toContainOneByRole("heading", {
name: "Greetings"
});
For an equivalent of testing library's screen
, pass document
as the container.
expect(document).not.toContainAnyByRole("dialog");
Each of the eight core queries supported by @testing-library/dom
have equivalent single and multiple element assertions. The arguments for each are identical to @testing-library/dom
, assuming the container has already been passed to expect
.
Please see the testing library documentation for more information about available options. For example: ByRole
The positive toContainOneBy...
assertions pass when there is precisely one matching element. The negative not.toContainOneBy...
assertions pass when there are zero or more than one matching elements.
The positive toContainAnyBy...
assertions pass when there are one or more matching elements. The negative not.toContainAnyBy...
assertions pass when there are zero matching elements.
Type of Query | 0 Matches | 1 Match | >1 Matches |
---|---|---|---|
Single Element | |||
toContainOneBy... |
❌ | ✅ | ❌ |
not.toContainOneBy... |
✅ | ❌ | ✅ |
Multiple Elements | |||
toContainAnyBy... |
❌ | ✅ | ✅ |
not.toContainAnyBy... |
✅ | ❌ | ❌ |
The testing library family contains extensibility for advanced features such as adding custom queries. These are supported by this library using the createQueryMatcher
named export, which is the exact tool used internally for all standard matchers.
Once custom queries have been defined (see official example), TypeScript users can use declaration merging to add new matchers to jests's expect
function. For example, assuming a customQueries.ts
module has already been defined:
// customQueryMatchers.d.ts
declare namespace jest {
type CustomQueryArgs = DomQueryArgs<typeof import("./customQueries").queryAllBySample>;
interface CustomQueryMatchers<R = any> {
toContainAnyBySample(...args: CustomQueryArgs): R;
toContainOneBySample(...args: CustomQueryArgs): R;
}
interface Matchers<R> extends CustomQueryMatchers<R> {}
}
Then use the createQueryMatcher
for the real implementations:
// customMatchers.ts
import {createQueryMatcher} from "@testing-library/jest-dom-query";
import {queryAllBySample} from "./customQueries";
const customMatchers: Record<keyof jest.CustomQueryMatchers, jest.CustomMatcher> = {
toContainAnyBySample: createQueryMatcher({
matcherType: "any",
query: queryAllBySample,
queryName: "custom query"
}),
toContainOneBySample: createQueryMatcher({
matcherType: "one",
query: queryAllBySample,
queryName: "custom query"
})
};
expect.extend(customMatchers);
Finally, import the module for side effects in a test suite (or shared setup file) and use custom matchers to assert as needed.
// testSuite.ts
import "./customMatchers";
it("should be awesome", function () {
// Rendering here
expect(document).toContainOneBySample("sample1");
expect(document).not.toContainAnyBySample("sample2");
});