Skip to content

Commit

Permalink
feat: recommend prefer-screen-queries
Browse files Browse the repository at this point in the history
  • Loading branch information
nickserv committed Jun 17, 2020
1 parent 185180a commit 877751f
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
[![Tweet][tweet-badge]][tweet-url]

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

## Installation
Expand Down Expand Up @@ -145,7 +147,7 @@ To enable this configuration use the `extends` property in your
| [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than just `getBy*` queries | | |
| [prefer-find-by](docs/rules/prefer-find-by.md) | Suggest using `findBy*` methods instead of the `waitFor` + `getBy` queries | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | ![fixable-badge][] |
| [prefer-presence-queries](docs/rules/prefer-presence-queries.md) | Enforce specific queries when checking element is present or not | | |
| [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using screen while using queries | | |
| [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using screen while using queries | ![recommended-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | |
| [prefer-wait-for](docs/rules/prefer-wait-for.md) | Use `waitFor` instead of deprecated wait methods | | ![fixable-badge][] |

[build-badge]: https://img.shields.io/travis/testing-library/eslint-plugin-testing-library?style=flat-square
Expand Down Expand Up @@ -212,6 +214,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
1 change: 1 addition & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const recommendedRules = {
'testing-library/await-async-utils': 'error',
'testing-library/no-await-sync-query': 'error',
'testing-library/prefer-find-by': 'error',
'testing-library/prefer-screen-queries': 'error',
};

export = {
Expand Down
32 changes: 21 additions & 11 deletions lib/rules/prefer-screen-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
docs: {
description: 'Suggest using screen while using queries',
category: 'Best Practices',
recommended: false,
recommended: 'error',
},
messages: {
preferScreenQueries:
Expand All @@ -46,28 +46,39 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
const queriesRegex = new RegExp(ALL_QUERIES_COMBINATIONS_REGEXP);
const queriesDestructuredInWithinDeclaration: string[] = [];
// use an array as within might be used more than once in a test
const withinDeclaredVariables : string[] = []
const withinDeclaredVariables: string[] = [];

return {
VariableDeclarator(node) {
const isWithinFunction = isCallExpression(node.init) && isIdentifier(node.init.callee) && node.init.callee.name === 'within';
const isWithinFunction =
isCallExpression(node.init) &&
isIdentifier(node.init.callee) &&
node.init.callee.name === 'within';

if (!isWithinFunction) {
return
return;
}

if (isObjectPattern(node.id)) {
// save the destructured query methods
const identifiers = node.id.properties
.filter(property => isProperty(property) && isIdentifier(property.key) && queriesRegex.test(property.key.name))
.map((property: TSESTree.Property) => (property.key as TSESTree.Identifier).name);
.filter(
property =>
isProperty(property) &&
isIdentifier(property.key) &&
queriesRegex.test(property.key.name)
)
.map(
(property: TSESTree.Property) =>
(property.key as TSESTree.Identifier).name
);

queriesDestructuredInWithinDeclaration.push(...identifiers);
return
return;
}

if (isIdentifier(node.id)) {
withinDeclaredVariables.push(node.id.name)
withinDeclaredVariables.push(node.id.name);
}
},
[`CallExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
Expand All @@ -84,16 +95,15 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
[`MemberExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
node: TSESTree.Identifier
) {

function isIdentifierAllowed(name: string) {
return ['screen', ...withinDeclaredVariables].includes(name)
return ['screen', ...withinDeclaredVariables].includes(name);
}

if (
isIdentifier(node) &&
isMemberExpression(node.parent) &&
isCallExpression(node.parent.object) &&
isIdentifier(node.parent.object.callee) &&
isIdentifier(node.parent.object.callee) &&
node.parent.object.callee.name !== 'within'
) {
reportInvalidUsage(node);
Expand Down
4 changes: 4 additions & 0 deletions tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Object {
"angular",
],
"testing-library/prefer-find-by": "error",
"testing-library/prefer-screen-queries": "error",
},
}
`;
Expand All @@ -34,6 +35,7 @@ Object {
"react",
],
"testing-library/prefer-find-by": "error",
"testing-library/prefer-screen-queries": "error",
},
}
`;
Expand All @@ -48,6 +50,7 @@ Object {
"testing-library/await-async-utils": "error",
"testing-library/no-await-sync-query": "error",
"testing-library/prefer-find-by": "error",
"testing-library/prefer-screen-queries": "error",
},
}
`;
Expand All @@ -68,6 +71,7 @@ Object {
"vue",
],
"testing-library/prefer-find-by": "error",
"testing-library/prefer-screen-queries": "error",
},
}
`;

0 comments on commit 877751f

Please sign in to comment.