# Cypress Testing Library: DOM Queries Through Cypress Commands

> Cypress Testing Library adapts DOM Testing Library queries to Cypress command chains, including retry behavior and assertions. It suits Cypress test suites that prefer accessible, user-facing queries over selectors tied directly to markup.

**testing-library/cypress-testing-library** — 🐅 Simple and complete custom Cypress commands and utilities that encourage good testing practices.

- Repository: https://github.com/testing-library/cypress-testing-library
- Website: http://npm.im/@testing-library/cypress
- Stars: 1,822 · Forks: 157
- Language: JavaScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/testing-library-cypress-testing-library

## Why Cypress Testing Library Exists

Cypress Testing Library addresses a specific mismatch between two testing interfaces. DOM Testing Library queries elements by visible text, labels, roles, and other user-facing properties, while Cypress commands normally operate on elements selected from the page's markup. A Cypress test written around `cy.get('form')`, `cy.get('button')`, or a long selector chain can pass even when the interface becomes difficult or inaccessible to use.

This package is for Cypress developers who want to express test intent through DOM Testing Library queries without leaving the Cypress command queue. Its commands are useful in end-to-end tests that verify what a person can read, click, or otherwise interact with. The package does not replace Cypress, provide a browser runner, or change how Cypress executes a spec. It adds commands to Cypress' existing `cy` object.

The README describes access to the useful `findBy` and `findAllBy` methods from DOM Testing Library. This is narrower than an exact drop-in replacement for the DOM package. In particular, the query and multiple-result commands that retain DOM Testing Library's `query*` and `get*` names are not exposed. The available interface instead maps onto Cypress retry and assertion behavior.

## Command Registration and Query Flow

Registration imports the entry point named `add-commands`, which extends Cypress' `cy` command object. After that import, a test can issue chained queries such as `findAllByText` or `findByText`. The repository includes an `add-commands.js` entry file, while the package metadata identifies `dist/index.js` as the main module and publishes `types/*.d.ts` alongside it.

The data flow has an important adaptation at the Cypress boundary. Cypress commonly yields jQuery elements, whereas DOM Testing Library expects DOM nodes. According to the README, Cypress Testing Library supports both forms. When a query is chained from a collection, the command takes the first DOM node from that collection's subject and passes it as the DOM Testing Library `container`. A query chained from a form therefore searches within that form rather than beginning from the whole page.

The `find*` commands do not retain the Promise API of DOM Testing Library. They delegate to corresponding `get*` behavior and depend on Cypress' built-in retryability. Errors raised by those queries are forwarded as Cypress errors, allowing a later Cypress assertion or action to participate in command retry. This is the central technical compromise: the package exposes Testing Library query semantics, but execution follows Cypress' queue and retry model.

## Installing and Registering Cypress Commands

The package is distributed through npm and is intended to be installed as a development dependency. Node and npm version requirements are declared in `package.json`, while Cypress itself is a peer dependency. Install the package at the project root:

```bash
npm install --save-dev @testing-library/cypress
```

After installation, add the command registration import to the Cypress support commands file. The README specifically names `cypress/support/commands.js`:

```javascript
import '@testing-library/cypress/add-commands'
```

That import is the enabling step. Merely installing the npm package does not add the commands to every spec. Cypress must also load the support file through the project's existing Cypress support configuration, although the README excerpt does not provide that setup.

TypeScript projects add both Cypress and this package to the `types` array in `tsconfig.json`:

```json
{
  "compilerOptions": {
    "types": ["cypress", "@testing-library/cypress"]
  }
}
```

JavaScript projects using VS Code can include Cypress and local Cypress JavaScript files in a root-level `jsconfig.json`:

```json
{
  "include": ["node_modules/cypress", "./cypress/**/*.js"]
}
```

These editor settings are separate from runtime command registration. The JavaScript configuration assists code completion, while `add-commands` adds the commands.

## A First Cypress Test with findAllByText

A first use can stay within the examples documented in `cypress/e2e/find.cy.js`. Start with text that is present in the rendered interface, then append a Cypress assertion:

```javascript
cy.findAllByText('Button Text').should('exist')
```

This is a `findAll` query, so the command can resolve more than one matching element. The assertion merely requires that a match exists. Absence should also be expressed through a Cypress assertion:

```javascript
cy.findAllByText('Non-existing Button text').should('not.exist')
```

The README's example uses the capitalization `Non-existing Button Text`. Preserve the actual UI text when adapting the test. A query can accept DOM Testing Library options, including its documented query timeout behavior:

```javascript
cy.findAllByLabelText('Label text', {timeout: 7000}).should('exist')
```

Actions remain Cypress actions. A query that returns one item can be followed directly by `click`:

```javascript
cy.findAllByText('Jackie Chan').click()
```

Cypress fails the action if more than one element is returned. That behavior does not mean the query itself requires a single result. It means the subsequent action receives an invalid subject. To enforce uniqueness explicitly, use either an existence assertion with `findByText` or a length assertion with `findAllByText`:

```javascript
cy.findByText('Some Text').should('exist')
```

The first command fails when multiple elements match. The following form expresses the same cardinality check directly:

```javascript
cy.findAllByText('Some Text').should('have.length', 1)
```

## Cardinality Rules That Differ from Cypress

The most consequential limitation is the split between `find*` and `findAll*`. A `findAll*` command may select multiple elements, which aligns with Cypress commands that can yield collections. A `find*` command fails when more than one element matches. The README presents this as compatibility with other Testing Library implementations rather than a rule copied from native Cypress behavior.

This distinction affects both test design and error diagnosis. Chaining `.click()` onto a `findAll*` result does not prove that the query found exactly one match. The click succeeds when one subject is available and fails when the action receives several subjects. Tests that care about uniqueness need an explicit assertion, such as `should('have.length', 1)`, or a `findBy*` command.

The absence case follows the same Cypress-centered approach. Instead of a `queryBy*` command returning `null`, the project expects `should('not.exist')`. The package also does not expose `get*` commands under their DOM Testing Library names. Developers familiar with the DOM package therefore need to read the Cypress-facing command list rather than assume every familiar method is present. The repository's `types/index.d.ts` is identified by the README as the location for command definitions.

## testIdAttribute Configuration and DOM Coupling

The package delegates broader DOM Testing Library configuration to a `configure` export. The README's example changes the test ID attribute from `data-testId` to `data-test-id`:

```javascript
import {configure} from '@testing-library/cypress'
configure({testIdAttribute: 'data-test-id'})
```

This import is shown for a Cypress support index file, while command registration remains a separate concern. Projects should not assume that configuring the package automatically registers its commands. The two operations address different concerns: registration adds Cypress commands, and configuration changes how DOM Testing Library interprets configured selectors.

The README states that `configure` accepts all configurations listed in DOM Testing Library's API configuration documentation. That makes the underlying DOM library the reference for supported options. It does not mean every DOM query or command name is exposed through Cypress Testing Library. The available Cypress command surface remains constrained to the `findBy`, `findAllBy`, configuration, and registration behavior described here.

For tests that prefer stable hooks, `testIdAttribute` offers a controlled escape from visible content. For tests intended to verify accessible interaction, queries by text or label text are still useful. Mixing both approaches can be sensible, but the package does not prescribe when a suite should prefer one over the other.

## Cypress Selectors, DOM Testing Library, and Maintenance

The real alternative is to use Cypress' built-in selection and action commands without this adapter. The practical difference is the query model. `cy.get` operates directly in the Cypress command queue, while Cypress Testing Library registers DOM Testing Library-derived query commands that select by user-facing properties and convert Cypress subjects into DOM nodes. Cypress Testing Library is therefore appropriate when query intent and consistency with other Testing Library APIs matter. Built-in Cypress commands are the simpler choice when a suite already has a deliberate selector policy or needs only a small number of direct selections.

Another apparent alternative, calling DOM Testing Library directly, does not preserve the same execution behavior in a Cypress spec. The README says this package relies on Cypress retryability and forwards query errors, while DOM Testing Library's `find*` methods use a Promise API. This distinction matters in tests that wait for delayed interface changes.

The repository is not archived, and its last push was on 2026-04-29. The recent release list includes `v10.1.3` on 2026-04-29, `v10.1.0` on 2025-09-02, and `v10.0.3` on 2025-01-21. The package declares `node >=12`, `npm >=6`, and `cypress >=12` as a peer dependency. Upgrade cost includes checking Cypress compatibility, TypeScript command definitions, and support-file imports. The project uses the MIT license, so the source is permissively licensed, subject to the license text's conditions.

## Conclusion

Adopt Cypress Testing Library when the team already uses Cypress and wants its end-to-end tests to follow accessible, user-facing query patterns. Do not choose it for projects that do not meet its Cypress peer dependency or expect the Promise-based behavior of DOM Testing Library directly. Check command registration, testIdAttribute configuration, and the exact query cardinality rules in the first test migration.

## FAQ

### How do I install Cypress Testing Library?

Install `@testing-library/cypress` as a development dependency with `npm install --save-dev @testing-library/cypress`, then import `@testing-library/cypress/add-commands` from the Cypress support commands file.

### Does Cypress Testing Library support queryBy and getBy commands?

No. The README says `query*` and `get*` queries are not supported. Absence should be checked with `should('not.exist')`, while `find*` commands forward to `get*` behavior internally and use Cypress retryability.

### What is the difference between findByText and findAllByText in Cypress Testing Library?

`findByText` fails when more than one matching element exists. `findAllByText` can return several elements, although a later Cypress action such as `.click()` will fail if the collection contains more than one subject.

## Sources

- [License: MIT](https://github.com/testing-library/cypress-testing-library/blob/main/LICENSE)
- [Project website](http://npm.im/@testing-library/cypress)
- [README](https://github.com/testing-library/cypress-testing-library/blob/main/README.md)
- [Releases](https://github.com/testing-library/cypress-testing-library/releases)
- [testing-library/cypress-testing-library on GitHub](https://github.com/testing-library/cypress-testing-library)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/testing-library-cypress-testing-library
