@testing-library/jest-dom

repository·main·Indexed 26 days ago

https://github.com/testing-library/jest-dom

Custom Jest matchers to test the state of the DOM in a declarative and readable way. Provides specialized assertions such as toBeInTheDocument, toBeVisible, toBeDisabled, toHaveClass, and toHaveTextContent. Supports integration with standard Jest, @jest/globals, Vitest, and other Jest-compatible expect runners.

Tokens
9.3K
Snippets
35
Records
55
Agent score
89%

What's inside @testing-library/jest-dom

  1. Configure @testing-library/jest-dom with TypeScript

    main

    When using TypeScript, ensure your setup file uses the .ts extension instead of .js to include the necessary types. You must also include the setup file in the include array of your tsconfig.json.

    // In tsconfig.json
    "include": [
      ...
      "./jest-setup.ts"
    ]
  2. Use @testing-library/jest-dom with other Jest-compatible expect runners

    main

    If using a test runner compatible with Jest's expect interface, you can manually extend expect using the matchers exported from @testing-library/jest-dom/matchers.

    import * as matchers from '@testing-library/jest-dom/matchers'
    import {expect} from 'my-test-runner/expect'
    
    expect.extend(matchers)
  3. Install @testing-library/jest-dom

    main

    Install @testing-library/jest-dom as a development dependency using npm or yarn. It is also recommended to install eslint-plugin-jest-dom to improve test readability and prevent false positives via auto-fixable lint rules.

    npm install --save-dev @testing-library/jest-dom
    
    # or
    
    yarn add --dev @testing-library/jest-dom
  4. Configure @testing-library/jest-dom with Vitest

    main

    To use with Vitest, import @testing-library/jest-dom/vitest in your Vitest setup file and add that file to the setupFiles property in your vitest.config.js. If using TypeScript, update your tsconfig.json to include the necessary types and the setup file.

    // 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']
    // In tsconfig.json
    "compilerOptions": {
      ...
      "types": ["vitest/globals", "@testing-library/jest-dom"]
    },
    "include": [
      ...
      "./vitest-setup.ts"
    ]
  5. Configure @testing-library/jest-dom for standard Jest

    main

    To use the custom matchers, import @testing-library/jest-dom in your Jest setup file (e.g., jest-setup.js) and ensure that file is registered in your jest.config.js under the setupFilesAfterEnv property.

    // 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']
  6. Configure @testing-library/jest-dom with @jest/globals

    main

    If you are using @jest/globals with injectGlobals: false, use the specific entry point @testing-library/jest-dom/jest-globals in your Jest setup file.

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

    main
    To use the custom matchers provided by @testing-library/jest-dom in your Jest environment, import the package. The library automatically calls expect.extend() with its collection of matchers upon being imported, making them available for use in your tests.
  8. Check displayed values with `toHaveDisplayValue`

    main

    Use toHaveDisplayValue to check the value that is actually visible to the end user in a form element.

    • Supported elements: <input>, <select>, and <textarea> (excluding checkbox/radio types).
    • Arguments: Accepts a string, RegExp, or an array of string | RegExp.
    const input = screen.getByLabelText('First name')
    const textarea = screen.getByLabelText('Description')
    const selectSingle = screen.getByLabelText('Fruit')
    const selectMultiple = screen.getByLabelText('Fruits')
    
    expect(input).toHaveDisplayValue('Luca')
    expect(input).toHaveDisplayValue(/Luc/)
    expect(textarea).toHaveDisplayValue('An example description here.')
    expect(textarea).toHaveDisplayValue(/example/)
    expect(selectSingle).toHaveDisplayValue('Select a fruit...')
    expect(selectSingle).toHaveDisplayValue(/Select/)
    expect(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana'])
  9. Assert descendant presence with `toContainAnyBy*` and `toContainOneBy*`

    main

    These matchers allow you to assert whether an element contains descendants using Testing Library queries. They are useful when toBeInTheDocument is not specific enough, as they scope the query to a specific part of the DOM and produce clear pass/fail results instead of throwing when an element is absent.

    Matcher Logic

    Matcher0 matches1 match>1 matches
    toContainOneBy...
    not.toContainOneBy...
    toContainAnyBy...
    not.toContainAnyBy...

    Supported Queries

    All query options supported by @testing-library/dom (e.g. exact, name, selector) are passed through to the underlying query.

    • toContainAnyByAltText / toContainOneByAltText
    • toContainAnyByDisplayValue / toContainOneByDisplayValue
    • toContainAnyByLabelText / toContainOneByLabelText
    • toContainAnyByPlaceholderText / toContainOneByPlaceholderText
    • toContainAnyByRole / toContainOneByRole
    • toContainAnyByTestId / toContainOneByTestId
    • toContainAnyByText / toContainOneByText
    • toContainAnyByTitle / toContainOneByTitle

    Using document.body as the container is equivalent to screen.getBy*.

    const results = getByRole('region', {name: 'search results'})
    const related = getByRole('region', {name: 'related articles'})
    
    // passes: one or more listitem elements in the results section
    expect(results).toContainAnyByRole('listitem')
    
    // passes: exactly one heading in the related section
    expect(related).toContainOneByRole('heading', {name: 'Related article'})
    
    // fails: there are two listitems, not one
    expect(results).not.toContainOneByRole('listitem')
    
    // fails: no heading in the results section
    expect(related).not.toContainAnyByRole('heading')
  10. Assert text selection with `toHaveSelection`

    main

    Use toHaveSelection to assert that text or part of the text is selected within an element (such as an input of type text, a textarea, or elements like p, span, or div).

    Note: The expected selection must be a string; it does not support checking selection range indices.

  11. Check error messages with `toHaveErrorMessage` (Deprecated)

    main

    Use toHaveErrorMessage to check if an element has an ARIA error message.

    Warning: This matcher is deprecated. Prefer toHaveAccessibleErrorMessage instead.

    • Matching: A string argument performs a whole case-sensitive match. Use RegExp for case-insensitive or partial matches, or expect.stringContaining() for partial matches.
    • Requirements: Authors must use aria-invalid in conjunction with aria-errormessage.
    const timeInput = getByLabel('startTime')
    
    expect(timeInput).toHaveErrorMessage(
      'Invalid time: the time must be between 9:00 AM and 5:00 PM',
    )
    expect(timeInput).toHaveErrorMessage(/invalid time/i) // to partially match
    expect(timeInput).toHaveErrorMessage(expect.stringContaining('Invalid time')) // to partially match
    expect(timeInput).not.toHaveErrorMessage('Pikachu!')