ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library
[![Build status][build-badge]][build-url]
[![Package version][version-badge]][version-url]
[![MIT License][license-badge]][license-url]
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
[![PRs Welcome][pr-badge]][pr-url]
[![Watch on Github][gh-watchers-badge]][gh-watchers-url]
[![Star on Github][gh-stars-badge]][gh-stars-url]
[![Tweet][tweet-badge]][tweet-url]
[![All Contributors](https://img.shields.io/badge/all_contributors-35-orange.svg?style=flat-square)](#contributors-)
## Installation
You'll first need to install [ESLint](http://eslint.org):
```
$ npm i eslint --save-dev
```
Next, install `eslint-plugin-testing-library`:
```
$ npm install eslint-plugin-testing-library --save-dev
```
**Note:** If you installed ESLint globally (using the `-g` flag) then you must also install `eslint-plugin-testing-library` globally.
## Usage
Add `testing-library` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
```json
{
"plugins": ["testing-library"]
}
```
Then configure the rules you want to use under the rules section.
```json
{
"rules": {
"testing-library/await-async-query": "error",
"testing-library/no-await-sync-query": "error",
"testing-library/no-debug": "warn"
}
}
```
## Shareable configurations
### Recommended
This plugin exports a recommended configuration that enforces good
Testing Library practices _(you can find more info about enabled rules in
the [Supported Rules section](#supported-rules) within the `Configurations` column)_.
To enable this configuration use the `extends` property in your
`.eslintrc` config file:
```json
{
"extends": ["plugin:testing-library/recommended"]
}
```
### Frameworks
Starting from the premise that
[DOM Testing Library](https://testing-library.com/docs/dom-testing-library/intro)
is the base for the rest of Testing Library frameworks wrappers, this
plugin also exports different configuration for those frameworks that
enforces good practices for specific rules that only apply to them _(you
can find more info about enabled rules in
the [Supported Rules section](#supported-rules) within the `Configurations` column)_.
**Note that frameworks configurations enable their specific rules +
recommended rules.**
Available frameworks configurations are:
#### Angular
To enable this configuration use the `extends` property in your
`.eslintrc` config file:
```json
{
"extends": ["plugin:testing-library/angular"]
}
```
#### React
To enable this configuration use the `extends` property in your
`.eslintrc` config file:
```json
{
"extends": ["plugin:testing-library/react"]
}
```
#### Vue
To enable this configuration use the `extends` property in your
`.eslintrc` config file:
```json
{
"extends": ["plugin:testing-library/vue"]
}
```
## Supported Rules
| Rule | Description | Configurations | Fixable |
| ---------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------ |
| [await-async-query](docs/rules/await-async-query.md) | Enforce async queries to have proper `await` | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | |
| [await-async-utils](docs/rules/await-async-utils.md) | Enforce async utils to be awaited properly | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | |
| [await-fire-event](docs/rules/await-fire-event.md) | Enforce async fire event methods to be awaited | ![vue-badge][] | |
| [consistent-data-testid](docs/rules/consistent-data-testid.md) | Ensure `data-testid` values match a provided regex. | | |
| [no-await-sync-events](docs/rules/no-await-sync-events.md) | Disallow unnecessary `await` for sync events | | |
| [no-await-sync-query](docs/rules/no-await-sync-query.md) | Disallow unnecessary `await` for sync queries | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | |
| [no-debug](docs/rules/no-debug.md) | Disallow the use of `debug` | ![angular-badge][] ![react-badge][] ![vue-badge][] | |
| [no-dom-import](docs/rules/no-dom-import.md) | Disallow importing from DOM Testing Library | ![angular-badge][] ![react-badge][] ![vue-badge][] | ![fixable-badge][] |
| [no-manual-cleanup](docs/rules/no-manual-cleanup.md) | Disallow the use of `cleanup` | | |
| [no-render-in-setup](docs/rules/no-render-in-setup.md) | Disallow the use of `render` in setup functions | | |
| [no-wait-for-empty-callback](docs/rules/no-wait-for-empty-callback.md) | Disallow empty callbacks for `waitFor` and `waitForElementToBeRemoved` | | |
| [no-wait-for-snapshot](docs/rules/no-wait-for-snapshot.md) | Ensures no snapshot is generated inside of a `waitFor` call | | |
| [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than just `getBy*` queries | | |
| [prefer-find-by](docs/rules/prefer-find-by.md) | Suggest using `findBy*` methods instead of the `waitFor` + `getBy` queries | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | ![fixable-badge][] |
| [prefer-presence-queries](docs/rules/prefer-presence-queries.md) | Enforce specific queries when checking element is present or not | | |
| [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using screen while using queries | | |
| [prefer-wait-for](docs/rules/prefer-wait-for.md) | Use `waitFor` instead of deprecated wait methods | | ![fixable-badge][] |
[build-badge]: https://github.com/testing-library/eslint-plugin-testing-library/actions/workflows/pipeline.yml/badge.svg
[build-url]: https://github.com/testing-library/eslint-plugin-testing-library/actions/workflows/pipeline.yml
[version-badge]: https://img.shields.io/npm/v/eslint-plugin-testing-library?style=flat-square
[version-url]: https://www.npmjs.com/package/eslint-plugin-testing-library
[license-badge]: https://img.shields.io/npm/l/eslint-plugin-testing-library?style=flat-square
[license-url]: https://github.com/belco90/eslint-plugin-testing-library/blob/main/license
[pr-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[pr-url]: http://makeapullrequest.com
[gh-watchers-badge]: https://img.shields.io/github/watchers/Belco90/eslint-plugin-testing-library?style=social
[gh-watchers-url]: https://github.com/belco90/eslint-plugin-testing-library/watchers
[gh-stars-badge]: https://img.shields.io/github/stars/Belco90/eslint-plugin-testing-library?style=social
[gh-stars-url]: https://github.com/belco90/eslint-plugin-testing-library/stargazers
[tweet-badge]: https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Fgithub.com%2FBelco90%2Feslint-plugin-testing-library
[tweet-url]: https://twitter.com/intent/tweet?url=https%3a%2f%2fgithub.com%2fbelco90%2feslint-plugin-testing-library&text=check%20out%20eslint-plugin-testing-library%20by%20@belcodev
[recommended-badge]: https://img.shields.io/badge/recommended-lightgrey?style=flat-square
[fixable-badge]: https://img.shields.io/badge/fixable-success?style=flat-square
[angular-badge]: https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black
[react-badge]: https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black
[vue-badge]: https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black
## Contributors β¨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):