Skip to content

Commit

Permalink
feat: add prefer-user-facing-locators rule
Browse files Browse the repository at this point in the history
  • Loading branch information
Haberkamp committed Aug 11, 2023
1 parent aca762e commit f9bb9d3
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
26 changes: 26 additions & 0 deletions docs/rules/prefer-user-facing-locators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Disallow using `page.locator` (`prefer-user-facing-locators`)

Prefer using user-facing locators over `page.locator` to make tests more robust.

Check out the [Playwright documentation](https://playwright.dev/docs/locators)
for more information.

## Rule Details

Example of **incorrect** code for this rule:

```javascript
await page.locator('button').click();
```

Example of **correct** code for this rule:

```javascript
await page.getByRole('button').click();
```

```javascript
await page.getByRole('button', {
name: 'Submit',
});
```
28 changes: 28 additions & 0 deletions src/rules/prefer-user-facing-locators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Rule } from 'eslint';
import { isPageMethod } from '../utils/ast';

export default {
create(context) {
return {
CallExpression(node) {
if (isPageMethod(node, 'locator')) {
context.report({ messageId: 'preferUserFacingLocators', node });
}
},
};
},
meta: {
docs: {
category: 'Best Practices',
description:
'Enforces the usage of user facing locators over page.locator()',
recommended: true,
url: 'https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-user-facing-locators.md',
},
messages: {
preferUserFacingLocators:
'Usage of page.locator() detected. Prefer user facing locators over page.locator()',
},
type: 'problem',
},
} as Rule.RuleModule;
44 changes: 44 additions & 0 deletions test/spec/prefer-user-facing-locators.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import rule from '../../src/rules/prefer-user-facing-locators';
import { runRuleTester, test } from '../utils/rule-tester';

const messageId = 'preferUserFacingLocators';

runRuleTester('prefer-user-facing-locators', rule, {
invalid: [
{
code: test('await page.locator()'),
errors: [{ column: 34, endColumn: 48, line: 1, messageId }],
},
{
code: test('await this.page.locator()'),
errors: [{ column: 34, endColumn: 53, line: 1, messageId }],
},
{
code: test("await page.locator('.btn')"),
errors: [{ column: 34, endColumn: 54, line: 1, messageId }],
},
{
code: test('await page["locator"](".btn")'),
errors: [{ column: 34, endColumn: 57, line: 1, messageId }],
},
{
code: test('await page[`locator`](".btn")'),
errors: [{ column: 34, endColumn: 57, line: 1, messageId }],
},
],
valid: [
test('await page.click()'),
test('await this.page.click()'),
test('await page["hover"]()'),
test('await page[`check`]()'),

// Preferred user facing locators
test('await page.getByText("lorem ipsum")'),
test('await page.getByLabel(/Email/)'),
test('await page.getByRole("button", { name: /submit/i })'),
test('await page.getByTestId("my-test-button").click()'),
test(
'await page.getByRole("button").filter({ hasText: "Add to cart" }).click()'
),
],
});

0 comments on commit f9bb9d3

Please sign in to comment.