UNPKG

eslint-plugin-testing-library

Version:

ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library

355 lines (274 loc) 107 kB
<div align="center"> <a href="https://eslint.org/"> <img width="150" height="150" src="https://raw.githubusercontent.com/eslint/eslint/main/docs/src/static/favicon.png"> </a> <a href="https://testing-library.com/"> <img width="150" height="150" src="https://raw.githubusercontent.com/testing-library/dom-testing-library/master/other/octopus.png"> </a> <h1>eslint-plugin-testing-library</h1> <p>ESLint plugin to follow best practices and anticipate common mistakes when writing tests with Testing Library</p> </div> --- [![Package version][version-badge]][version-url] [![eslint-remote-tester][eslint-remote-tester-badge]][eslint-remote-tester-workflow] [![eslint-plugin-testing-library][package-health-badge]][package-health-url] [![codecov](https://codecov.io/gh/testing-library/eslint-plugin-testing-library/graph/badge.svg?token=IJd6ZogYPm)](https://codecov.io/gh/testing-library/eslint-plugin-testing-library) [![MIT License][license-badge]][license-url] <br /> [![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] [![All Contributors][all-contributors-badge]](#contributors-) ## Prerequisites To use this plugin, you must have [Node.js](https://nodejs.org/en/) (`^18.18.0`, `^20.9.0`, or `>=21.1.0`) installed. ## Installation You'll first need to [install ESLint](https://eslint.org/docs/latest/use/getting-started). Next, install `eslint-plugin-testing-library`: ```shell $ pnpm add --save-dev eslint-plugin-testing-library # or $ npm install --save-dev eslint-plugin-testing-library # or $ yarn add --dev eslint-plugin-testing-library ``` **Note:** If you installed ESLint globally (using the `-g` flag) then you must also install `eslint-plugin-testing-library` globally. ## Migrating You can find detailed guides for migrating `eslint-plugin-testing-library` in the [migration guide docs](docs/migration-guides): - [Migration guide for v4](docs/migration-guides/v4.md) - [Migration guide for v5](docs/migration-guides/v5.md) - [Migration guide for v6](docs/migration-guides/v6.md) - [Migration guide for v7](docs/migration-guides/v7.md) ## Usage Add `testing-library` to the plugins section of your `.eslintrc.js` configuration file. You can omit the `eslint-plugin-` prefix: ```js module.exports = { plugins: ['testing-library'], }; ``` Then configure the rules you want to use within `rules` property of your `.eslintrc`: ```js module.exports = { rules: { 'testing-library/await-async-queries': 'error', 'testing-library/no-await-sync-queries': 'error', 'testing-library/no-debugging-utils': 'warn', 'testing-library/no-dom-import': 'off', }, }; ``` ### Run the plugin only against test files With the default setup mentioned before, `eslint-plugin-testing-library` will be run against your whole codebase. If you want to run this plugin only against your tests files, you have the following options: #### ESLint `overrides` One way of restricting ESLint config by file patterns is by using [ESLint `overrides`](https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-based-on-glob-patterns). Assuming you are using the same pattern for your test files as [Jest by default](https://jestjs.io/docs/configuration#testmatch-arraystring), the following config would run `eslint-plugin-testing-library` only against your test files: ```js // .eslintrc.js module.exports = { // 1) Here we have our usual config which applies to the whole project, so we don't put testing-library preset here. extends: ['airbnb', 'plugin:prettier/recommended'], // 2) We load other plugins than eslint-plugin-testing-library globally if we want to. plugins: ['react-hooks'], overrides: [ { // 3) Now we enable eslint-plugin-testing-library rules or preset only for matching testing files! files: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'], extends: ['plugin:testing-library/react'], }, ], }; ``` #### ESLint Cascading and Hierarchy Another approach for customizing ESLint config by paths is through [ESLint Cascading and Hierarchy](https://eslint.org/docs/user-guide/configuring/configuration-files#cascading-and-hierarchy). This is useful if all your tests are placed under the same folder, so you can place there another `.eslintrc` where you enable `eslint-plugin-testing-library` for applying it only to the files under such folder, rather than enabling it on your global `.eslintrc` which would apply to your whole project. ## Shareable configurations > [!NOTE] > > `eslint.config.js` compatible versions of configs are available prefixed with > `flat/`, though most of the plugin documentation still currently uses > `.eslintrc` syntax. > > Refer to the > [ESLint documentation on the new configuration file format](https://eslint.org/docs/latest/use/configure/configuration-files-new) > for more. This plugin exports several recommended configurations that enforce good practices for specific Testing Library packages. You can find more info about enabled rules in the [Supported Rules section](#supported-rules), under the `Configurations` column. Since each one of these configurations is aimed at a particular Testing Library package, they are not extendable between them, so you should use only one of them at once per `.eslintrc` file. For example, if you want to enable recommended configuration for React, you don't need to combine it somehow with DOM one: ```js // ❌ Don't do this module.exports = { extends: ['plugin:testing-library/dom', 'plugin:testing-library/react'], }; ``` ```js // ✅ Just do this instead module.exports = { extends: ['plugin:testing-library/react'], }; ``` ### DOM Testing Library Enforces recommended rules for DOM Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/dom'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/dom']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/dom'], }, ]; ``` ### Angular Enforces recommended rules for Angular Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/angular'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/angular']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/angular'], }, ]; ``` ### React Enforces recommended rules for React Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/react'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/react']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/react'], }, ]; ``` ### Vue Enforces recommended rules for Vue Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/vue'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/vue']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/vue'], }, ]; ``` ### Svelte Enforces recommended rules for Svelte Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/svelte'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/svelte']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/svelte'], }, ]; ``` ### Marko Enforces recommended rules for Marko Testing Library. To enable this configuration use the `extends` property in your `.eslintrc.js` config file: ```js module.exports = { extends: ['plugin:testing-library/marko'], }; ``` To enable this configuration with `eslint.config.js`, use `testingLibrary.configs['flat/marko']`: ```js const testingLibrary = require('eslint-plugin-testing-library'); module.exports = [ { files: [ /* glob matching your test files */ ], ...testingLibrary.configs['flat/marko'], }, ]; ``` ## Supported Rules > Remember that all rules from this plugin are prefixed by `"testing-library/"` <!-- begin auto-generated rules list --> 💼 Configurations enabled in.\ ⚠️ Configurations set to warn in.\ ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) Set in the `angular` configuration.\ ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) Set in the `dom` configuration.\ ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) Set in the `marko` configuration.\ ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) Set in the `react` configuration.\ ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) Set in the `svelte` configuration.\ ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) Set in the `vue` configuration.\ 🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix). | Name                            | Description | 💼 | ⚠️ | 🔧 | | :------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-- | | [await-async-events](docs/rules/await-async-events.md) | Enforce promises from async event methods are handled | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [await-async-queries](docs/rules/await-async-queries.md) | Enforce promises from async queries to be handled | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [await-async-utils](docs/rules/await-async-utils.md) | Enforce promises from async utils to be awaited properly | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [consistent-data-testid](docs/rules/consistent-data-testid.md) | Ensures consistent usage of `data-testid` | | | | | [no-await-sync-events](docs/rules/no-await-sync-events.md) | Disallow unnecessary `await` for sync events | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) | | | | [no-await-sync-queries](docs/rules/no-await-sync-queries.md) | Disallow unnecessary `await` for sync queries | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [no-container](docs/rules/no-container.md) | Disallow the use of `container` methods | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [no-debugging-utils](docs/rules/no-debugging-utils.md) | Disallow the use of debugging utilities like `debug` | | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | [no-dom-import](docs/rules/no-dom-import.md) | Disallow importing from DOM Testing Library | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [no-global-regexp-flag-in-query](docs/rules/no-global-regexp-flag-in-query.md) | Disallow the use of the global RegExp flag (/g) in queries | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [no-manual-cleanup](docs/rules/no-manual-cleanup.md) | Disallow the use of `cleanup` | ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [no-node-access](docs/rules/no-node-access.md) | Disallow direct Node access | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [no-promise-in-fire-event](docs/rules/no-promise-in-fire-event.md) | Disallow the use of promises passed to a `fireEvent` method | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [no-render-in-lifecycle](docs/rules/no-render-in-lifecycle.md) | Disallow the use of `render` in testing frameworks setup functions | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [no-test-id-queries](docs/rules/no-test-id-queries.md) | Ensure no `data-testid` queries are used | | | | | [no-unnecessary-act](docs/rules/no-unnecessary-act.md) | Disallow wrapping Testing Library utils or empty callbacks in `act` | ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) | | | | [no-wait-for-multiple-assertions](docs/rules/no-wait-for-multiple-assertions.md) | Disallow the use of multiple `expect` calls inside `waitFor` | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [no-wait-for-side-effects](docs/rules/no-wait-for-side-effects.md) | Disallow the use of side effects in `waitFor` | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [no-wait-for-snapshot](docs/rules/no-wait-for-snapshot.md) | Ensures no snapshot is generated inside of a `waitFor` call | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | | | [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than standalone queries | | | | | [prefer-find-by](docs/rules/prefer-find-by.md) | Suggest using `find(All)By*` query instead of `waitFor` + `get(All)By*` to wait for elements | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) | | 🔧 | | [prefer-implicit-assert](docs/rules/prefer-implicit-assert.md) | Suggest using implicit assertions for getBy* & findBy* queries | | | | | [prefer-presence-queries](docs/rules/prefer-presence-queries.md) | Ensure appropriate `get*`/`query*` queries are used with their respective matchers | ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoC