Skip to content

Commit d7c0753

Browse files
committed
feat: Add no-get-by-title rule
Fixes #196
1 parent 3ccac8a commit d7c0753

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,21 @@ command line option.\
124124
|| 🔧 | | [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 |
125125
|| | | [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 |
126126
|| | 💡 | [no-element-handle](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-element-handle.md) | Disallow usage of element handles |
127-
|| | | [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` |
127+
|| | | [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()` |
128128
|| | 💡 | [no-focused-test](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-focused-test.md) | Disallow usage of `.only` annotation |
129129
|| | | [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 |
130130
|| | | [no-nested-step](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-nested-step.md) | Disallow nested `test.step()` methods |
131131
|| | | [no-networkidle](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-networkidle.md) | Disallow usage of the `networkidle` option |
132132
| | | | [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 |
133-
|| | | [no-page-pause](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-page-pause.md) | Disallow using `page.pause` |
133+
|| | | [no-page-pause](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-page-pause.md) | Disallow using `page.pause()` |
134+
| | 🔧 | | [no-get-by-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-get-by-title.md) | Disallow using `getByTitle()` |
134135
| | | | [no-raw-locators](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-raw-locators.md) | Disallow using raw locators |
135136
|| 🔧 | | [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 |
136137
| | | | [no-restricted-matchers](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-restricted-matchers.md) | Disallow specific matchers & modifiers |
137138
|| | 💡 | [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 |
138139
|| 🔧 | | [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 |
139-
|| | 💡 | [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` |
140-
|| | 💡 | [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` |
140+
|| | 💡 | [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()` |
141+
|| | 💡 | [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()` |
141142
| | | 💡 | [prefer-strict-equal](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-strict-equal.md) | Suggest using `toStrictEqual()` |
142143
| | 🔧 | | [prefer-lowercase-title](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-lowercase-title.md) | Enforce lowercase test names |
143144
| | 🔧 | | [prefer-to-be](https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/prefer-to-be.md) | Suggest using `toBe()` |

docs/rules/no-get-by-title.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Disallow using `getByTitle()` (`no-get-by-title`)
2+
3+
The HTML `title` attribute does not provide a fully accessible tooltip for
4+
elements so relying on it to identify elements can hide accessibility issues in
5+
your code. This rule helps to prevent that by disallowing use of the
6+
`getByTitle` method.
7+
8+
## Rule Details
9+
10+
Example of **incorrect** code for this rule:
11+
12+
```javascript
13+
await page.getByTitle('Delete product').click();
14+
```
15+
16+
Example of **correct** code for this rule:
17+
18+
```javascript
19+
await page.getByRole('button', { name: 'Delete product' }).click();
20+
```

src/rules/no-get-by-title.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Rule } from 'eslint';
2+
import { isPageMethod } from '../utils/ast';
3+
4+
export default {
5+
create(context) {
6+
return {
7+
CallExpression(node) {
8+
if (isPageMethod(node, 'getByTitle')) {
9+
context.report({ messageId: 'noGetByTitle', node });
10+
}
11+
},
12+
};
13+
},
14+
meta: {
15+
docs: {
16+
category: 'Best Practices',
17+
description: 'Disallows the usage of getByTitle()',
18+
recommended: false,
19+
url: 'https://github.com/playwright-community/eslint-plugin-playwright/tree/main/docs/rules/no-get-by-title.md',
20+
},
21+
messages: {
22+
noGetByTitle:
23+
'The HTML title attribute is not an accessible name. Prefer getByRole() or getByLabelText() instead.',
24+
},
25+
type: 'suggestion',
26+
},
27+
} as Rule.RuleModule;

test/spec/no-get-by-title.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import rule from '../../src/rules/no-get-by-title';
2+
import { runRuleTester, test } from '../utils/rule-tester';
3+
4+
const messageId = 'noGetByTitle';
5+
6+
runRuleTester('no-get-by-title', rule, {
7+
invalid: [
8+
{
9+
code: test('await page.getByTitle("lorem ipsum")'),
10+
errors: [{ column: 34, endColumn: 64, line: 1, messageId }],
11+
},
12+
{
13+
code: test('await this.page.getByTitle("lorem ipsum")'),
14+
errors: [{ column: 34, endColumn: 69, line: 1, messageId }],
15+
},
16+
],
17+
valid: [
18+
test('await page.locator("[title=lorem ipsum]")'),
19+
test('await page.getByRole("button")'),
20+
],
21+
});

0 commit comments

Comments
 (0)