Skip to content

Commit

Permalink
fix(prefer-find-by): Respect waitFor options when autofixing (#679)
Browse files Browse the repository at this point in the history
Relates to #579 

* fix(docs): mark code keywords with `` and add a period to end of sentence

* fix(prefer-find-by): autofixer now transfers waitFor options to autofixed
  • Loading branch information
sjarva committed Oct 21, 2022
1 parent 2e1e9d5 commit e31fe03
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
6 changes: 3 additions & 3 deletions 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

Expand Down Expand Up @@ -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

Expand Down
10 changes: 9 additions & 1 deletion lib/rules/prefer-find-by.ts
Expand Up @@ -5,6 +5,7 @@ import {
isArrowFunctionExpression,
isCallExpression,
isMemberExpression,
isObjectExpression,
isObjectPattern,
isProperty,
} from '../node-utils';
Expand Down Expand Up @@ -366,6 +367,13 @@ export default createTestingLibraryRule<Options, MessageIds>({
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];
Expand All @@ -389,7 +397,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
}
const newCode = `${caller}.${queryVariant}${queryMethod}(${callArguments
.map((callArgNode) => sourceCode.getText(callArgNode))
.join(', ')})`;
.join(', ')}${waitOptionsSourceCode})`;
return fixer.replaceText(node, newCode);
},
});
Expand Down
23 changes: 23 additions & 0 deletions tests/lib/rules/prefer-find-by.test.ts
Expand Up @@ -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 })
`,
})),
]),
Expand Down

0 comments on commit e31fe03

Please sign in to comment.