ESLint plugin for Playwright testing.
npm install eslint-plugin-playwright


ESLint plugin for Playwright.
npm
``bash`
npm install -D eslint-plugin-playwright
Yarn
`bash`
yarn add -D eslint-plugin-playwright
pnpm
`bash`
pnpm add -D eslint-plugin-playwright
The recommended setup is to use the files field to target only Playwright testtests
files. In the examples below, this is done by targeting files in the files
directory and only applying the Playwright rules to those files. In your
project, you may need to change the field to match your Playwright test
file patterns.
Flat config
(eslint.config.js)
`javascript
import { defineConfig } from '@eslint/config'
import playwright from 'eslint-plugin-playwright'
export default defineConfig([
{
files: ['tests/**'],
extends: [playwright.configs['flat/recommended']],
rules: {
// Customize Playwright rules
// ...
},
},
])
`
Legacy config
(.eslintrc)
`json`
{
"overrides": [
{
"files": "tests/**",
"extends": "plugin:playwright/recommended"
}
]
}
If you import Playwright globals (e.g. test, expect) with a custom name, you
can configure this plugin to be aware of these additional names.
`json`
{
"settings": {
"playwright": {
"globalAliases": {
"test": ["myTest"],
"expect": ["myExpect"]
}
}
}
}
You can customize the error messages for rules using the
settings.playwright.messages property. This is useful if you would like to
increase the verbosity of error messages or provide additional context.
Only the message ids you define in this setting will be overridden, so any other
messages will use the default message defined by the plugin.
`json`
{
"settings": {
"playwright": {
"messages": {
"conditionalExpect": "Avoid conditional expects as they can lead to false positives"
}
}
}
}
ā
Set in the recommended configuration\--fix
š§ Automatically fixable by the
CLI option\
š” Manually fixable by
editor suggestions
| Rule | Description | ā
| š§ | š” |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | :-: | :-: | :-: |
| consistent-spacing-between-blocks | Enforce consistent spacing between test blocks | ā
| š§ | |
| expect-expect | Enforce assertion to be made in a test body | ā
| | |
| max-expects | Enforces a maximum number assertion calls in a test body | | | |
| max-nested-describe | Enforces a maximum depth to nested describe calls | ā
| | |
| missing-playwright-await | Enforce Playwright APIs to be awaited | ā
| š§ | |
| no-commented-out-tests | Disallow commented out tests | | | |
| no-conditional-expect | Disallow calling expect conditionally | ā
| | |page.$eval()
| no-conditional-in-test | Disallow conditional logic in tests | ā
| | |
| no-duplicate-hooks | Disallow duplicate setup and teardown hooks | | | |
| no-element-handle | Disallow usage of element handles | ā
| | š” |
| no-eval | Disallow usage of and page.$$eval() | ā
| | |.only
| no-focused-test | Disallow usage of annotation | ā
| | š” |{ force: true }
| no-force-option | Disallow usage of the option | ā
| | |getByTitle()
| no-get-by-title | Disallow using | | š§ | |test.step()
| no-hooks | Disallow setup and teardown hooks | | | |
| no-nested-step | Disallow nested methods | ā
| | |networkidle
| no-networkidle | Disallow usage of the option | ā
| | |first()
| no-nth-methods | Disallow usage of , last(), and nth() methods | | | |page.pause()
| no-page-pause | Disallow using | ā
| | |.skip
| no-raw-locators | Disallow using raw locators | | | |
| no-restricted-locators | Disallow specific locator methods | | | |
| no-restricted-matchers | Disallow specific matchers & modifiers | | | |
| no-skipped-test | Disallow usage of the annotation | ā
| | š” |.slow
| no-slowed-test | Disallow usage of the annotation | | | š” |test
| no-standalone-expect | Disallow using expect outside of blocks | ā
| | |page.evaluate()
| no-unsafe-references | Prevent unsafe variable references in | ā
| š§ | |await
| no-unused-locators | Disallow usage of page locators that are not used | ā
| | |
| no-useless-await | Disallow unnecessary s for Playwright methods | ā
| š§ | |not
| no-useless-not | Disallow usage of matchers when a specific matcher exists | ā
| š§ | |page.waitForNavigation()
| no-wait-for-navigation | Disallow usage of | ā
| | š” |page.waitForSelector()
| no-wait-for-selector | Disallow usage of | ā
| | š” |page.waitForTimeout()
| no-wait-for-timeout | Disallow usage of | ā
| | š” |page.locator()
| prefer-comparison-matcher | Suggest using the built-in comparison matchers | | š§ | |
| prefer-equality-matcher | Suggest using the built-in equality matchers | | | š” |
| prefer-hooks-in-order | Prefer having hooks in a consistent order | | | |
| prefer-hooks-on-top | Suggest having hooks before any test cases | | | |
| prefer-lowercase-title | Enforce lowercase test names | | š§ | |
| prefer-native-locators | Suggest built-in locators over | | š§ | |toStrictEqual()
| prefer-locator | Suggest locators over page methods | | | |
| prefer-strict-equal | Suggest using | | | š” |toBe()
| prefer-to-be | Suggest using | | š§ | |toContain()
| prefer-to-contain | Suggest using | | š§ | |toHaveCount()
| prefer-to-have-count | Suggest using | | š§ | |toHaveLength()
| prefer-to-have-length | Suggest using | | š§ | |expect.soft()
| prefer-web-first-assertions | Suggest using web first assertions | ā
| š§ | |
| require-hook | Require setup and teardown code to be within a hook | | | |
| require-soft-assertions | Require assertions to use | | š§ | |toThrow()
| require-to-throw-message | Require a message for | | | |test.describe
| require-top-level-describe | Require test cases and hooks to be inside a block | | | |describe()
| valid-describe-callback | Enforce valid callback | ā
| | |expect()` usage | ā
| | |
| valid-expect-in-promise | Require promises that have expectations in their chain to be valid | ā
| | |
| valid-expect | Enforce valid
| valid-title | Enforce valid titles | ā
| š§ | |
| valid-test-tags | Enforce valid tag format in test blocks | ā
| | |