MCPcopy Index your code
hub / github.com/testing-library/jest-dom

github.com/testing-library/jest-dom @v6.9.1 sqlite

repository ↗ · DeepWiki ↗ · release v6.9.1 ↗
184 symbols 666 edges 96 files 32 documented · 17% 284 cross-repo links
README

jest-dom

owl

Custom jest matchers to test the state of the DOM


[![Build Status][build-badge]][build] [![Code Coverage][coverage-badge]][coverage] [![version][version-badge]][package] [![downloads][downloads-badge]][npmtrends] [![MIT License][license-badge]][license]

All Contributors [![PRs Welcome][prs-badge]][prs] [![Code of Conduct][coc-badge]][coc] [![Discord][discord-badge]][discord]

[![Watch on GitHub][github-watch-badge]][github-watch] [![Star on GitHub][github-star-badge]][github-star] [![Tweet][twitter-badge]][twitter]

The problem

You want to use [jest][] to write tests that assert various things about the state of a DOM. As part of that goal, you want to avoid all the repetitive patterns that arise in doing so. Checking for an element's attributes, its text content, its css classes, you name it.

This solution

The @testing-library/jest-dom library provides a set of custom jest matchers that you can use to extend jest. These will make your tests more declarative, clear to read and to maintain.

Table of Contents

Installation

This module is distributed via [npm][npm] which is bundled with [node][node] and should be installed as one of your project's devDependencies:

npm install --save-dev @testing-library/jest-dom

or

for installation with yarn package manager.

yarn add --dev @testing-library/jest-dom

Note: We also recommend installing the jest-dom eslint plugin which provides auto-fixable lint rules that prevent false positive tests and improve test readability by ensuring you are using the right matchers in your tests. More details can be found at eslint-plugin-jest-dom.

Usage

Import @testing-library/jest-dom once (for instance in your tests setup file) and you're good to go:

// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom'

// In jest.config.js add (if you haven't already)
setupFilesAfterEnv: ['<rootDir>/jest-setup.js']

With @jest/globals

If you are using @jest/globals with injectGlobals: false, you will need to use a different import in your tests setup file:

// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom/jest-globals'

With Vitest

If you are using vitest, this module will work as-is, but you will need to use a different import in your tests setup file. This file should be added to the setupFiles property in your vitest config:

// In your own vitest-setup.js (or any other name)
import '@testing-library/jest-dom/vitest'

// In vitest.config.js add (if you haven't already)
setupFiles: ['./vitest-setup.js']

Also, depending on your local setup, you may need to update your tsconfig.json:

  // In tsconfig.json
  "compilerOptions": {
    ...
    "types": ["vitest/globals", "@testing-library/jest-dom"]
  },
  "include": [
    ...
    "./vitest-setup.ts"
  ],

With TypeScript

If you're using TypeScript, make sure your setup file is a .ts and not a .js to include the necessary types.

You will also need to include your setup file in your tsconfig.json if you haven't already:

  // In tsconfig.json
  "include": [
    ...
    "./jest-setup.ts"
  ],

With another Jest-compatible expect

If you are using a different test runner that is compatible with Jest's expect interface, it might be possible to use it with this library:

import * as matchers from '@testing-library/jest-dom/matchers'
import {expect} from 'my-test-runner/expect'

expect.extend(matchers)

Custom matchers

@testing-library/jest-dom can work with any library or framework that returns DOM elements from queries. The custom matcher examples below are written using matchers from @testing-library's suite of libraries (e.g. getByTestId, queryByTestId, getByText, etc.)

toBeDisabled

toBeDisabled()

This allows you to check whether an element is disabled from the user's perspective. According to the specification, the following elements can be disabled: button, input, select, textarea, optgroup, option, fieldset, and custom elements.

This custom matcher considers an element as disabled if the element is among the types of elements that can be disabled (listed above), and the disabled attribute is present. It will also consider the element as disabled if it's inside a parent form element that supports being disabled and has the disabled attribute present.

Examples

<button data-testid="button" type="submit" disabled>submit</button>
<fieldset disabled><input type="text" data-testid="input" /></fieldset>
<a href="https://github.com/testing-library/jest-dom/raw/v6.9.1/" disabled>link</a>
expect(getByTestId('button')).toBeDisabled()
expect(getByTestId('input')).toBeDisabled()
expect(getByText('link')).not.toBeDisabled()

This custom matcher does not take into account the presence or absence of the aria-disabled attribute. For more on why this is the case, check #144.


toBeEnabled

toBeEnabled()

This allows you to check whether an element is not disabled from the user's perspective.

It works like not.toBeDisabled(). Use this matcher to avoid double negation in your tests.

This custom matcher does not take into account the presence or absence of the aria-disabled attribute. For more on why this is the case, check #144.


toBeEmptyDOMElement

toBeEmptyDOMElement()

This allows you to assert whether an element has no visible content for the user. It ignores comments but will fail if the element contains white-space.

Examples

<span data-testid="not-empty"><span data-testid="empty"></span></span>
<span data-testid="with-whitespace"> </span>
<span data-testid="with-comment"></span>
expect(getByTestId('empty')).toBeEmptyDOMElement()
expect(getByTestId('not-empty')).not.toBeEmptyDOMElement()
expect(getByTestId('with-whitespace')).not.toBeEmptyDOMElement()

toBeInTheDocument

toBeInTheDocument()

This allows you to assert whether an element is present in the document or not.

Examples

<span data-testid="html-element"><span>Html Element</span></span>
<svg data-testid="svg-element"></svg>
expect(
  getByTestId(document.documentElement, 'html-element'),
).toBeInTheDocument()
expect(getByTestId(document.documentElement, 'svg-element')).toBeInTheDocument()
expect(
  queryByTestId(document.documentElement, 'does-not-exist'),
).not.toBeInTheDocument()

Note: This matcher does not find detached elements. The element must be added to the document to be found by toBeInTheDocument. If you desire to search in a detached element please use: toContainElement


toBeInvalid

toBeInvalid()

This allows you to check if an element, is currently invalid.

An element is invalid if it has an aria-invalid attribute with no value or a value of "true", or if the result of checkValidity() is false.

Examples

<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />

<form data-testid="valid-form">
  <input />
</form>

<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('no-aria-invalid')).not.toBeInvalid()
expect(getByTestId('aria-invalid')).toBeInvalid()
expect(getByTestId('aria-invalid-value')).toBeInvalid()
expect(getByTestId('aria-invalid-false')).not.toBeInvalid()

expect(getByTestId('valid-form')).not.toBeInvalid()
expect(getByTestId('invalid-form')).toBeInvalid()

toBeRequired

toBeRequired()

This allows you to check if a form element is currently required.

An element is required if it is having a required or aria-required="true" attribute.

Examples

<input data-testid="required-input" required />
<input data-testid="aria-required-input" aria-required="true" />
<input data-testid="conflicted-input" required aria-required="false" />
<input data-testid="aria-not-required-input" aria-required="false" />
<input data-testid="optional-input" />
<input data-testid="unsupported-type" type="image" required />
<select data-testid="select" required></select>
<textarea data-testid="textarea" required></textarea>










expect(getByTestId('required-input')).toBeRequired()
expect(getByTestId('aria-required-input')).toBeRequired()
expect(getByTestId('conflicted-input')).toBeRequired()
expect(getByTestId('aria-not-required-input')).not.toBeRequired()
expect(getByTestId('optional-input')).not.toBeRequired()
expect(getByTestId('unsupported-type')).not.toBeRequired()
expect(getByTestId('select')).toBeRequired()
expect(getByTestId('textarea')).toBeRequired()
expect(getByTestId('supported-role')).not.toBeRequired()
expect(getByTestId('supported-role-aria')).toBeRequired()

toBeValid

toBeValid()

This allows you to check if the value of an element, is currently valid.

An element is valid if it has no aria-invalid attributes or an attribute value of "false". The result of checkValidity() must also be true if it's a form element.

Examples

<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />

<form data-testid="valid-form">
  <input />
</form>

<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('no-aria-invalid')).toBeValid()
expect(getByTestId('aria-invalid')).not.toBeValid()
expect(getByTestId('aria-invalid-value')).not.toBeValid()
expect(getByTestId('aria-invalid-false')).toBeValid()

expect(getByTestId('valid-form')).toBeValid()
expect(getByTestId('invalid-form')).not.toBeValid()

toBeVisible

toBeVisible()

This allows you to check if an

Extension points exported contracts — how you extend this code

TestingLibraryMatchers (Interface)
(no doc)
types/matchers.d.ts
Matchers (Interface)
(no doc)
types/jest.d.ts
Matchers (Interface)
(no doc)
types/jest-globals.d.ts
Assertion (Interface)
(no doc)
types/vitest.d.ts
MatcherReturnType (Interface)
(no doc)
types/matchers-standalone.d.ts
Matchers (Interface)
(no doc)
types/bun.d.ts
AsymmetricMatchersContaining (Interface)
(no doc)
types/vitest.d.ts
OverloadedMatchers (Interface)
(no doc)
types/matchers-standalone.d.ts

Core symbols most depended-on inside this repo

toHaveAccessibleName
called by 121
types/matchers.d.ts
toHaveClass
called by 112
types/matchers.d.ts
toHaveValue
called by 96
types/matchers.d.ts
toHaveDisplayValue
called by 73
types/matchers.d.ts
toBeVisible
called by 68
types/matchers.d.ts
toHaveAccessibleDescription
called by 68
types/matchers.d.ts
toHaveErrorMessage
called by 66
types/matchers.d.ts
toHaveTextContent
called by 65
types/matchers.d.ts

Shape

Function 123
Method 39
Class 14
Interface 8

Languages

TypeScript100%

Modules by API surface

types/matchers.d.ts34 symbols
src/utils.js28 symbols
src/to-be-disabled.js9 symbols
src/to-have-role.js8 symbols
src/__tests__/to-have-form-values.js8 symbols
src/to-be-checked.js7 symbols
src/to-have-style.js5 symbols
src/to-have-form-values.js5 symbols
src/to-be-invalid.js5 symbols
src/to-have-class.js4 symbols
src/to-be-visible.js4 symbols
src/to-be-required.js4 symbols

Dependencies from manifests, versioned

@adobe/css-tools4.4.0 · 1×
@jest/globals29.6.2 · 1×
@rollup/plugin-commonjs25.0.4 · 1×
@types/bunlatest · 1×
@types/weblatest · 1×
aria-query5.0.0 · 1×
css.escape1.5.1 · 1×
dom-accessibility-api0.6.3 · 1×
expect29.6.2 · 1×
jest-environment-jsdom-sixteen1.0.3 · 1×
jest-watch-select-projects2.0.0 · 1×
jsdom16.2.1 · 1×

For agents

$ claude mcp add jest-dom \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact