Skip to content

Commit

Permalink
feat: Add no-get-by-title rule
Browse files Browse the repository at this point in the history
Fixes #196
  • Loading branch information
mskelton committed Feb 11, 2024
1 parent 3ccac8a commit d7c0753
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 4 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,21 @@ command line option.\
|| 🔧 | | [missing-playwright-await](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/missing-playwright-await.md) | Enforce Playwright APIs to be awaited |
|| | | [no-conditional-in-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-conditional-in-test.md) | Disallow conditional logic in tests |
|| | 💡 | [no-element-handle](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-element-handle.md) | Disallow usage of element handles |
|| | | [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-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-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-page-pause](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-page-pause.md) | Disallow using `page.pause()` |
| | 🔧 | | [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-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` |
|| | 💡 | [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-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-to-be](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-be.md) | Suggest using `toBe()` |
Expand Down
20 changes: 20 additions & 0 deletions docs/rules/no-get-by-title.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Disallow using `getByTitle()` (`no-get-by-title`)

The HTML `title` attribute does not provide a fully accessible tooltip for
elements so relying on it to identify elements can hide accessibility issues in
your code. This rule helps to prevent that by disallowing use of the
`getByTitle` method.

## Rule Details

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

```javascript
await page.getByTitle('Delete product').click();
```

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

```javascript
await page.getByRole('button', { name: 'Delete product' }).click();
```
27 changes: 27 additions & 0 deletions src/rules/no-get-by-title.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Rule } from 'eslint';
import { isPageMethod } from '../utils/ast';

export default {
create(context) {
return {
CallExpression(node) {
if (isPageMethod(node, 'getByTitle')) {
context.report({ messageId: 'noGetByTitle', node });
}
},
};
},
meta: {
docs: {
category: 'Best Practices',
description: 'Disallows the usage of getByTitle()',
recommended: false,
url: 'https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-get-by-title.md',
},
messages: {
noGetByTitle:
'The HTML title attribute is not an accessible name. Prefer getByRole() or getByLabelText() instead.',
},
type: 'suggestion',
},
} as Rule.RuleModule;
21 changes: 21 additions & 0 deletions test/spec/no-get-by-title.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import rule from '../../src/rules/no-get-by-title';
import { runRuleTester, test } from '../utils/rule-tester';

const messageId = 'noGetByTitle';

runRuleTester('no-get-by-title', rule, {
invalid: [
{
code: test('await page.getByTitle("lorem ipsum")'),
errors: [{ column: 34, endColumn: 64, line: 1, messageId }],
},
{
code: test('await this.page.getByTitle("lorem ipsum")'),
errors: [{ column: 34, endColumn: 69, line: 1, messageId }],
},
],
valid: [
test('await page.locator("[title=lorem ipsum]")'),
test('await page.getByRole("button")'),
],
});

0 comments on commit d7c0753

Please sign in to comment.