Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: playwright-community/eslint-plugin-playwright
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.6.0
Choose a base ref
...
head repository: playwright-community/eslint-plugin-playwright
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.6.1
Choose a head ref
  • 3 commits
  • 3 files changed
  • 3 contributors

Commits on Apr 9, 2024

  1. Sort docs

    mskelton committed Apr 9, 2024
    Copy the full SHA
    72e8acb View commit details

Commits on Apr 11, 2024

  1. docs: fix usage guide flat recommended rules (#283)

    MatchuPitchu authored Apr 11, 2024
    Copy the full SHA
    1fe2c5e View commit details

Commits on Apr 20, 2024

  1. fix(prefer-web-first-assertions): Support variable reassignment (#287)

    An631 authored Apr 20, 2024
    Copy the full SHA
    b0fb7cd View commit details
Showing with 335 additions and 17 deletions.
  1. +8 −8 README.md
  2. +267 −0 src/rules/prefer-web-first-assertions.test.ts
  3. +60 −9 src/rules/prefer-web-first-assertions.ts
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ import playwright from 'eslint-plugin-playwright'

export default [
{
...playwright.configs['flat/playwright'],
...playwright.configs['flat/recommended'],
files: ['tests/**'],
},
{
@@ -174,37 +174,37 @@ CLI option\
| [no-eval](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-eval.md) | Disallow usage of `page.$eval()` and `page.$$eval()` || | |
| [no-focused-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-focused-test.md) | Disallow usage of `.only` annotation || | 💡 |
| [no-force-option](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-force-option.md) | Disallow usage of the `{ force: true }` option || | |
| [no-get-by-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-get-by-title.md) | Disallow using `getByTitle()` | | 🔧 | |
| [no-hooks](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-hooks.md) | Disallow setup and teardown hooks | | | |
| [no-nested-step](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-nested-step.md) | Disallow nested `test.step()` methods || | |
| [no-networkidle](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-networkidle.md) | Disallow usage of the `networkidle` option || | |
| [no-nth-methods](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-nth-methods.md) | Disallow usage of `first()`, `last()`, and `nth()` methods | | | |
| [no-page-pause](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-page-pause.md) | Disallow using `page.pause()` || | |
| [no-unsafe-references](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-unsafe-references.md) | Prevent unsafe variable references in `page.evaluate()` || 🔧 | |
| [no-get-by-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-get-by-title.md) | Disallow using `getByTitle()` | | 🔧 | |
| [no-raw-locators](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-raw-locators.md) | Disallow using raw locators | | | |
| [no-useless-await](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-useless-await.md) | Disallow unnecessary `await`s for Playwright methods || 🔧 | |
| [no-restricted-matchers](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-restricted-matchers.md) | Disallow specific matchers & modifiers | | | |
| [no-skipped-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-skipped-test.md) | Disallow usage of the `.skip` annotation || | 💡 |
| [no-standalone-expect](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-standalone-expect.md) | Disallow using expect outside of `test` blocks || | |
| [no-unsafe-references](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-unsafe-references.md) | Prevent unsafe variable references in `page.evaluate()` || 🔧 | |
| [no-useless-await](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-useless-await.md) | Disallow unnecessary `await`s for Playwright methods || 🔧 | |
| [no-useless-not](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-useless-not.md) | Disallow usage of `not` matchers when a specific matcher exists || 🔧 | |
| [no-wait-for-selector](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-selector.md) | Disallow usage of `page.waitForSelector()` || | 💡 |
| [no-wait-for-timeout](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-wait-for-timeout.md) | Disallow usage of `page.waitForTimeout()` || | 💡 |
| [prefer-comparison-matcher](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | 🔧 | |
| [prefer-equality-matcher](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | | 💡 |
| [prefer-hooks-in-order](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-hooks-in-order.md) | Prefer having hooks in a consistent order | | | |
| [prefer-hooks-on-top](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-hooks-on-top.md) | Suggest having hooks before any test cases | | | |
| [prefer-strict-equal](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-strict-equal.md) | Suggest using `toStrictEqual()` | | | 💡 |
| [prefer-lowercase-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-lowercase-title.md) | Enforce lowercase test names | | 🔧 | |
| [prefer-strict-equal](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-strict-equal.md) | Suggest using `toStrictEqual()` | | | 💡 |
| [prefer-to-be](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-be.md) | Suggest using `toBe()` | | 🔧 | |
| [prefer-to-contain](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-contain.md) | Suggest using `toContain()` | | 🔧 | |
| [prefer-to-have-count](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-have-count.md) | Suggest using `toHaveCount()` | | 🔧 | |
| [prefer-to-have-length](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-have-length.md) | Suggest using `toHaveLength()` | | 🔧 | |
| [prefer-web-first-assertions](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-web-first-assertions.md) | Suggest using web first assertions || 🔧 | |
| [require-hook](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-hook.md) | Require setup and teardown code to be within a hook | | | |
| [require-top-level-describe](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-top-level-describe.md) | Require test cases and hooks to be inside a `test.describe` block | | | |
| [require-soft-assertions](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-soft-assertions.md) | Require assertions to use `expect.soft()` | | 🔧 | |
| [require-to-throw-message](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-to-throw-message.md) | Require a message for `toThrow()` | | | |
| [require-top-level-describe](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-top-level-describe.md) | Require test cases and hooks to be inside a `test.describe` block | | | |
| [valid-describe-callback](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-describe-callback.md) | Enforce valid `describe()` callback || | |
| [valid-expect](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-expect.md) | Enforce valid `expect()` usage || | |
| [valid-expect-in-promise](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-expect-in-promise.md) | Require promises that have expectations in their chain to be valid || | |
| [valid-expect](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-expect.md) | Enforce valid `expect()` usage || | |
| [valid-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/valid-title.md) | Enforce valid titles || 🔧 | |
| [require-to-throw-message](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/require-to-throw-message.md) | Require a message for `toThrow()` | | | |
267 changes: 267 additions & 0 deletions src/rules/prefer-web-first-assertions.test.ts
Original file line number Diff line number Diff line change
@@ -33,6 +33,90 @@ runRuleTester('prefer-web-first-assertions', rule, {
],
output: test('await expect(page.locator(".tweet")).toBeHidden()'),
},
{
code: test(`
const unrelatedAssignment = 'unrelated'
const isTweetVisible = await page.locator(".tweet").isVisible()
expect(isTweetVisible).toBe(true)
`),
output: test(`

Check warning on line 42 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 42 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 42 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const unrelatedAssignment = 'unrelated'
const isTweetVisible = page.locator(".tweet")
await expect(isTweetVisible).toBeVisible()
`),
errors: [
{
column: 9,
data: { matcher: 'toBeVisible', method: 'isVisible' },
endColumn: 31,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
const unrelatedAssignment = 'unrelated'
const isTweetVisible = await page.locator(".tweet").isVisible()
expect(isTweetVisible).toBe(false)
`),
output: test(`

Check warning on line 63 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 63 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 63 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const unrelatedAssignment = 'unrelated'
const isTweetVisible = page.locator(".tweet")
await expect(isTweetVisible).toBeHidden()
`),
errors: [
{
column: 9,
data: { matcher: 'toBeHidden', method: 'isVisible' },
endColumn: 31,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
const locatorFoo = page.locator(".foo")
const isBarVisible = await locatorFoo.locator(".bar").isVisible()
expect(isBarVisible).toBe(false)
`),
output: test(`

Check warning on line 84 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 84 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 84 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const locatorFoo = page.locator(".foo")
const isBarVisible = locatorFoo.locator(".bar")
await expect(isBarVisible).toBeHidden()
`),
errors: [
{
column: 9,
data: { matcher: 'toBeHidden', method: 'isVisible' },
endColumn: 29,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
const locatorFoo = page.locator(".foo")
const isBarVisible = await locatorFoo.locator(".bar").isVisible()
expect(isBarVisible).toBe(true)
`),
output: test(`

Check warning on line 105 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 105 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 105 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const locatorFoo = page.locator(".foo")
const isBarVisible = locatorFoo.locator(".bar")
await expect(isBarVisible).toBeVisible()
`),
errors: [
{
column: 9,
data: { matcher: 'toBeVisible', method: 'isVisible' },
endColumn: 29,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(
'expect(await page.locator(".tweet").isVisible()).toEqual(true)',
@@ -301,6 +385,150 @@ runRuleTester('prefer-web-first-assertions', rule, {
],
output: test('await expect(foo).not.toHaveText("bar")'),
},
{
code: test(`
const fooLocator = page.locator('.fooClass');
const fooLocatorText = await fooLocator.textContent();
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 394 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 394 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 394 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const fooLocator = page.locator('.fooClass');
const fooLocatorText = fooLocator;
await expect(fooLocatorText).toHaveText('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
const fooLocator = page.locator('.fooClass');
let fooLocatorText = await fooLocator.textContent();
expect(fooLocatorText).toEqual('foo');
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 417 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 417 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 417 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const fooLocator = page.locator('.fooClass');
let fooLocatorText = fooLocator;
await expect(fooLocatorText).toHaveText('foo');
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
let fooLocatorText;
const fooLocator = page.locator('.fooClass');
fooLocatorText = 'Unrelated';
fooLocatorText = await fooLocator.textContent();
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 442 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 442 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 442 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
let fooLocatorText;
const fooLocator = page.locator('.fooClass');
fooLocatorText = 'Unrelated';
fooLocatorText = fooLocator;
await expect(fooLocatorText).toHaveText('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 6,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
let fooLocatorText;
let fooLocatorText2;
const fooLocator = page.locator('.fooClass');
fooLocatorText = await fooLocator.textContent();
fooLocatorText2 = await fooLocator.textContent();
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 468 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 468 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 468 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
let fooLocatorText;
let fooLocatorText2;
const fooLocator = page.locator('.fooClass');
fooLocatorText = fooLocator;
fooLocatorText2 = await fooLocator.textContent();
await expect(fooLocatorText).toHaveText('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 7,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
let fooLocatorText;
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo');
fooLocatorText = await page.locator('.fooClass').textContent();
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 494 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 494 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 494 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
let fooLocatorText;
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo');
fooLocatorText = page.locator('.fooClass');
await expect(fooLocatorText).toHaveText('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 6,
messageId: 'useWebFirstAssertion',
},
],
},
{
code: test(`
const unrelatedAssignment = "unrelated";
const fooLocatorText = await page.locator('.foo').textContent();
expect(fooLocatorText).toEqual('foo');
`),
output: test(`

Check warning on line 517 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (16.x)

Object properties should be sorted alphabetically

Check warning on line 517 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (18.x)

Object properties should be sorted alphabetically

Check warning on line 517 in src/rules/prefer-web-first-assertions.test.ts

GitHub Actions / test (20.x)

Object properties should be sorted alphabetically
const unrelatedAssignment = "unrelated";
const fooLocatorText = page.locator('.foo');
await expect(fooLocatorText).toHaveText('foo');
`),
errors: [
{
column: 9,
data: { matcher: 'toHaveText', method: 'textContent' },
endColumn: 31,
line: 4,
messageId: 'useWebFirstAssertion',
},
],
},

// isChecked
{
@@ -736,5 +964,44 @@ runRuleTester('prefer-web-first-assertions', rule, {
expect(myValue).toBeVisible();
`),
},
{
code: test(`
let fooLocatorText;
const fooLocator = page.locator('.fooClass');
fooLocatorText = await fooLocator.textContent();
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo');
`),
},
{
code: test(`
let fooLocatorText;
let fooLocatorText2;
const fooLocator = page.locator('.fooClass');
fooLocatorText = 'foo';
fooLocatorText2 = await fooLocator.textContent();
expect(fooLocatorText).toEqual('foo');
`),
},
{
code: test(`
let fooLocatorText;
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo')
const fooLocator = page.locator('.fooClass');
fooLocatorText = fooLocator;
expect(fooLocatorText).toHaveText('foo');
`),
},
{
code: test(`
const fooLocator = page.locator('.fooClass');
let fooLocatorText;
fooLocatorText = fooLocator;
expect(fooLocatorText).toHaveText('foo');
fooLocatorText = 'foo';
expect(fooLocatorText).toEqual('foo')
`),
},
],
})
Loading