From c1003309343b7f28d4c4e74d27e2f2f48e2c9272 Mon Sep 17 00:00:00 2001 From: timdeschryver <28659384+timdeschryver@users.noreply.github.com> Date: Wed, 25 Mar 2020 19:45:21 +0100 Subject: [PATCH 1/2] feat(prefer-screen-queries): add prefer-screen-queries Closes #95 --- README.md | 1 + docs/rules/prefer-screen-queries.md | 28 +++++++++++++ lib/index.js | 1 + lib/rules/prefer-screen-queries.js | 40 +++++++++++++++++++ lib/utils.js | 4 +- tests/lib/rules/prefer-screen-queries.js | 50 ++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 docs/rules/prefer-screen-queries.md create mode 100644 lib/rules/prefer-screen-queries.js create mode 100644 tests/lib/rules/prefer-screen-queries.js diff --git a/README.md b/README.md index 350ec79b..e2d8dd10 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ To enable this configuration use the `extends` property in your | [no-wait-for-empty-callback](docs/rules/no-wait-for-empty-callback.md) | Disallow empty callbacks for `waitFor` and `waitForElementToBeRemoved` | | | | [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than just `getBy*` queries | | | | [prefer-wait-for](docs/rules/prefer-wait-for.md) | Use `waitFor` instead of deprecated wait methods | | ![fixable-badge][] | +| [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using screen while using queries | | | [build-badge]: https://img.shields.io/travis/testing-library/eslint-plugin-testing-library?style=flat-square [build-url]: https://travis-ci.org/testing-library/eslint-plugin-testing-library diff --git a/docs/rules/prefer-screen-queries.md b/docs/rules/prefer-screen-queries.md new file mode 100644 index 00000000..336f60b1 --- /dev/null +++ b/docs/rules/prefer-screen-queries.md @@ -0,0 +1,28 @@ +# Suggest using screen while using queries (prefer-screen-queries) + +## Rule Details + +This works better with autocomplete and makes each test a little simpler. + +Examples of **incorrect** code for this rule: + +```js +// calling a query from the `render` method +const { getByText } = render(); +getByText('foo'); + +const utils = render(); +utils.getByText('foo'); +``` + +Examples of **correct** code for this rule: + +```js +import { screen } from '@testing-library/any-framework'; + +screen.getByText('foo'); +``` + +## Further Reading + +- [`screen` documentation](https://testing-library.com/docs/dom-testing-library/api-queries#screen) diff --git a/lib/index.js b/lib/index.js index 4589eb2c..6b518007 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,6 +13,7 @@ const rules = { 'no-wait-for-empty-callback': require('./rules/no-wait-for-empty-callback'), 'prefer-explicit-assert': require('./rules/prefer-explicit-assert'), 'prefer-wait-for': require('./rules/prefer-wait-for'), + 'prefer-screen-queries': require('./rules/prefer-screen-queries'), }; const recommendedRules = { diff --git a/lib/rules/prefer-screen-queries.js b/lib/rules/prefer-screen-queries.js new file mode 100644 index 00000000..7aa86155 --- /dev/null +++ b/lib/rules/prefer-screen-queries.js @@ -0,0 +1,40 @@ +'use strict'; + +const { getDocsUrl, ALL_QUERIES_COMBINATIONS } = require('../utils'); + +const ALL_QUERIES_COMBINATIONS_REGEXP = ALL_QUERIES_COMBINATIONS.join('|'); + +module.exports = { + meta: { + type: 'suggestion', + docs: { + description: 'Suggest using screen while using queries', + category: 'Best Practices', + recommended: false, + url: getDocsUrl('prefer-screen-queries'), + }, + messages: { + preferScreenQueries: + 'Use screen to query DOM elements, `screen.{{ name }}`', + }, + fixable: null, + schema: [], + }, + + create: function(context) { + function reportInvalidUsage(node) { + context.report({ + node, + messageId: 'preferScreenQueries', + data: { + name: node.name, + }, + }); + } + + return { + [`CallExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`]: reportInvalidUsage, + [`MemberExpression[object.name!="screen"] > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`]: reportInvalidUsage, + }; + }, +}; diff --git a/lib/utils.js b/lib/utils.js index ad332a44..4cccecfc 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -44,8 +44,8 @@ const ASYNC_QUERIES_COMBINATIONS = combineQueries( ); const ALL_QUERIES_COMBINATIONS = [ - SYNC_QUERIES_COMBINATIONS, - ASYNC_QUERIES_COMBINATIONS, + ...SYNC_QUERIES_COMBINATIONS, + ...ASYNC_QUERIES_COMBINATIONS, ]; const ASYNC_UTILS = [ diff --git a/tests/lib/rules/prefer-screen-queries.js b/tests/lib/rules/prefer-screen-queries.js new file mode 100644 index 00000000..a0f5ebef --- /dev/null +++ b/tests/lib/rules/prefer-screen-queries.js @@ -0,0 +1,50 @@ +'use strict'; + +const rule = require('../../../lib/rules/prefer-screen-queries'); +const { ALL_QUERIES_COMBINATIONS } = require('../../../lib/utils'); +const RuleTester = require('eslint').RuleTester; + +// ------------------------------------------------------------------------------ +// Tests +// ------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } }); +ruleTester.run('prefer-screen-queries', rule, { + valid: [ + ...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({ + code: `screen.${queryMethod}()`, + })), + { + code: `otherFunctionShouldNotThrow()`, + }, + { + code: `component.otherFunctionShouldNotThrow()`, + }, + ], + + invalid: [ + ...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({ + code: `${queryMethod}()`, + errors: [ + { + messageId: 'preferScreenQueries', + data: { + name: queryMethod, + }, + }, + ], + })), + + ...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({ + code: `component.${queryMethod}()`, + errors: [ + { + messageId: 'preferScreenQueries', + data: { + name: queryMethod, + }, + }, + ], + })), + ], +}); From b4114157a3a2f0bd488f6fb2f8db0ae8681bcaad Mon Sep 17 00:00:00 2001 From: timdeschryver <28659384+timdeschryver@users.noreply.github.com> Date: Thu, 26 Mar 2020 18:51:20 +0100 Subject: [PATCH 2/2] docs: review changes --- README.md | 2 +- docs/rules/prefer-screen-queries.md | 4 +++- lib/index.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e2d8dd10..e834f74d 100644 --- a/README.md +++ b/README.md @@ -147,8 +147,8 @@ To enable this configuration use the `extends` property in your | [no-manual-cleanup](docs/rules/no-manual-cleanup.md) | Disallow the use of `cleanup` | | | | [no-wait-for-empty-callback](docs/rules/no-wait-for-empty-callback.md) | Disallow empty callbacks for `waitFor` and `waitForElementToBeRemoved` | | | | [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than just `getBy*` queries | | | -| [prefer-wait-for](docs/rules/prefer-wait-for.md) | Use `waitFor` instead of deprecated wait methods | | ![fixable-badge][] | | [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using screen while using queries | | | +| [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 [build-url]: https://travis-ci.org/testing-library/eslint-plugin-testing-library diff --git a/docs/rules/prefer-screen-queries.md b/docs/rules/prefer-screen-queries.md index 336f60b1..3fd22976 100644 --- a/docs/rules/prefer-screen-queries.md +++ b/docs/rules/prefer-screen-queries.md @@ -2,7 +2,8 @@ ## Rule Details -This works better with autocomplete and makes each test a little simpler. +DOM Testing Library (and other Testing Library frameworks built on top of it) exports a `screen` object which has every query (and a `debug` method). This works better with autocomplete and makes each test a little simpler to write and maintain. +This rule aims to force writing tests using queries directly from `screen` object rather than destructuring them from `render` result. Examples of **incorrect** code for this rule: @@ -20,6 +21,7 @@ Examples of **correct** code for this rule: ```js import { screen } from '@testing-library/any-framework'; +render(); screen.getByText('foo'); ``` diff --git a/lib/index.js b/lib/index.js index 6b518007..d5874718 100644 --- a/lib/index.js +++ b/lib/index.js @@ -12,8 +12,8 @@ const rules = { 'no-manual-cleanup': require('./rules/no-manual-cleanup'), 'no-wait-for-empty-callback': require('./rules/no-wait-for-empty-callback'), 'prefer-explicit-assert': require('./rules/prefer-explicit-assert'), - 'prefer-wait-for': require('./rules/prefer-wait-for'), 'prefer-screen-queries': require('./rules/prefer-screen-queries'), + 'prefer-wait-for': require('./rules/prefer-wait-for'), }; const recommendedRules = {