diff --git a/docs/rules/prefer-find-by.md b/docs/rules/prefer-find-by.md index 7187dc37..fd152ee6 100644 --- a/docs/rules/prefer-find-by.md +++ b/docs/rules/prefer-find-by.md @@ -1,11 +1,11 @@ # Suggest using `findBy*` methods instead of the `waitFor` + `getBy` queries (`testing-library/prefer-find-by`) -findBy* queries are a simple combination of getBy* queries and waitFor. The findBy\* queries accept the waitFor options as the last argument. (i.e. screen.findByText('text', queryOptions, waitForOptions)) +`findBy*` queries are a simple combination of `getBy*` queries and `waitFor`. The `findBy*` queries accept the `waitFor` options as the last argument. (i.e. `screen.findByText('text', queryOptions, waitForOptions)`) ## Rule details This rule aims to use `findBy*` or `findAllBy*` queries to wait for elements, rather than using `waitFor`, or the deprecated methods `waitForElement` and `wait`. -This rule analyzes those cases where `waitFor` is used with just one query method, in the form of an arrow function with only one statement (that is, without a block of statements). Given the callback could be more complex, this rule does not consider function callbacks or arrow functions with blocks of code +This rule analyzes those cases where `waitFor` is used with just one query method, in the form of an arrow function with only one statement (that is, without a block of statements). Given the callback could be more complex, this rule does not consider function callbacks or arrow functions with blocks of code. Examples of **incorrect** code for this rule @@ -78,7 +78,7 @@ await waitFor(() => expect(getAllByText('bar')).toBeDisabled()); ## When Not To Use It -- Not encouraging use of findBy shortcut from testing library best practices +- Not encouraging use of `findBy` shortcut from testing library best practices ## Further Reading diff --git a/lib/rules/prefer-find-by.ts b/lib/rules/prefer-find-by.ts index 084afef0..6c096cdb 100644 --- a/lib/rules/prefer-find-by.ts +++ b/lib/rules/prefer-find-by.ts @@ -5,6 +5,7 @@ import { isArrowFunctionExpression, isCallExpression, isMemberExpression, + isObjectExpression, isObjectPattern, isProperty, } from '../node-utils'; @@ -366,6 +367,13 @@ export default createTestingLibraryRule({ return; } + // if there is a second argument to AwaitExpression, it is the options + const waitOptions = node.arguments[1]; + let waitOptionsSourceCode = ''; + if (isObjectExpression(waitOptions)) { + waitOptionsSourceCode = `, ${sourceCode.getText(waitOptions)}`; + } + const queryVariant = getFindByQueryVariant(fullQueryMethod); const callArguments = getQueryArguments(argument.body); const queryMethod = fullQueryMethod.split('By')[1]; @@ -389,7 +397,7 @@ export default createTestingLibraryRule({ } const newCode = `${caller}.${queryVariant}${queryMethod}(${callArguments .map((callArgNode) => sourceCode.getText(callArgNode)) - .join(', ')})`; + .join(', ')}${waitOptionsSourceCode})`; return fixer.replaceText(node, newCode); }, }); diff --git a/tests/lib/rules/prefer-find-by.test.ts b/tests/lib/rules/prefer-find-by.test.ts index f67d8ce7..97fec6d5 100644 --- a/tests/lib/rules/prefer-find-by.test.ts +++ b/tests/lib/rules/prefer-find-by.test.ts @@ -702,6 +702,29 @@ ruleTester.run(RULE_NAME, rule, { queryMethod )}('foo', { name: 'baz' }) }) + `, + })), + // Issue #579, https://github.com/testing-library/eslint-plugin-testing-library/issues/579 + // findBy can have two sets of options: await screen.findByText('text', queryOptions, waitForOptions) + ...createScenario((waitMethod: string, queryMethod: string) => ({ + code: `import {${waitMethod}} from '${testingFramework}'; + const button = await ${waitMethod}(() => screen.${queryMethod}('Count is: 0'), { timeout: 100, interval: 200 }) + `, + errors: [ + { + messageId: 'preferFindBy', + data: { + queryVariant: getFindByQueryVariant(queryMethod), + queryMethod: queryMethod.split('By')[1], + prevQuery: queryMethod, + waitForMethodName: waitMethod, + }, + }, + ], + output: `import {${waitMethod}} from '${testingFramework}'; + const button = await screen.${buildFindByMethod( + queryMethod + )}('Count is: 0', { timeout: 100, interval: 200 }) `, })), ]),