Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

eslint-plugin-playwright

ESLint plugin for Playwright testing.

readme

ESLint Plugin Playwright

Test npm semantic-release

ESLint plugin for Playwright.

Installation

npm

npm install -D eslint-plugin-playwright

Yarn

yarn add -D eslint-plugin-playwright

pnpm

pnpm add -D eslint-plugin-playwright

Usage

The recommended setup is to use the files field to target only Playwright test files. In the examples below, this is done by targeting files in the tests directory and only applying the Playwright rules to those files. In your project, you may need to change the files field to match your Playwright test file patterns.

Flat config (eslint.config.js)

import playwright from 'eslint-plugin-playwright'

export default [
  {
    ...playwright.configs['flat/recommended'],
    files: ['tests/**'],
    rules: {
      ...playwright.configs['flat/recommended'].rules,
      // Customize Playwright rules
      // ...
    },
  },
]

Legacy config (.eslintrc)

{
  "overrides": [
    {
      "files": "tests/**",
      "extends": "plugin:playwright/recommended"
    }
  ]
}

Settings

Aliased Playwright Globals

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.

{
  "settings": {
    "playwright": {
      "globalAliases": {
        "test": ["myTest"],
        "expect": ["myExpect"]
      }
    }
  }
}

Custom Messages

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.

{
  "settings": {
    "playwright": {
      "messages": {
        "conditionalExpect": "Avoid conditional expects as they can lead to false positives"
      }
    }
  }
}

Rules

✅ Set in the recommended configuration\ 🔧 Automatically fixable by the --fix CLI option\ 💡 Manually fixable by editor suggestions

Rule Description 🔧 💡
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 |
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 page.$eval() and page.$$eval() |
no-focused-test Disallow usage of .only annotation | 💡
no-force-option Disallow usage of the { force: true } option |
no-get-by-title Disallow using getByTitle() | 🔧
no-hooks Disallow setup and teardown hooks |
no-nested-step Disallow nested test.step() methods |
no-networkidle Disallow usage of the networkidle option |
no-nth-methods Disallow usage of first(), last(), and nth() methods |
no-page-pause Disallow using page.pause() |
no-raw-locators Disallow using raw locators |
no-restricted-matchers Disallow specific matchers & modifiers |
no-skipped-test Disallow usage of the .skip annotation | 💡
no-slowed-test Disallow usage of the .slow annotation | 💡
no-standalone-expect Disallow using expect outside of test blocks |
no-unsafe-references Prevent unsafe variable references in page.evaluate() 🔧
no-useless-await Disallow unnecessary awaits for Playwright methods 🔧
no-useless-not Disallow usage of not matchers when a specific matcher exists 🔧
no-wait-for-selector Disallow usage of page.waitForSelector() | 💡
no-wait-for-timeout Disallow usage of page.waitForTimeout() | 💡
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 page.locator() | 🔧
prefer-locator Suggest locators over page methods |
prefer-strict-equal Suggest using toStrictEqual() | 💡
prefer-to-be Suggest using toBe() | 🔧
prefer-to-contain Suggest using toContain() | 🔧
prefer-to-have-count Suggest using toHaveCount() | 🔧
prefer-to-have-length Suggest using toHaveLength() | 🔧
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 expect.soft() | 🔧
require-to-throw-message Require a message for toThrow() |
require-top-level-describe Require test cases and hooks to be inside a test.describe block |
valid-describe-callback Enforce valid describe() callback |
valid-expect-in-promise Require promises that have expectations in their chain to be valid |
valid-expect Enforce valid expect() usage |
valid-title Enforce valid titles 🔧

changelog