Skip to content

Commit a783036

Browse files
lourencigndelia
andauthored
fix(prefer-screen-queries): take container into account (testing-library#150)
Co-authored-by: Gonzalo D'Elia <[email protected]>
1 parent 7a9af37 commit a783036

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

docs/rules/prefer-screen-queries.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,30 @@
22

33
## Rule Details
44

5-
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.
5+
DOM Testing Library (and other Testing Library frameworks built on top of it) exports a `screen` object which has every query (plus the `container` and a `debug` method). This works better with autocomplete and makes each test a little simpler to write and maintain.
66
This rule aims to force writing tests using queries directly from `screen` object rather than destructuring them from `render` result.
77

88
Examples of **incorrect** code for this rule:
99

1010
```js
1111
// calling a query from the `render` method
12-
const { getByText } = render(<Component />);
12+
const { getByText, container } = render(<Component />);
1313
getByText('foo');
14+
container.querySelector('foo');
1415

1516
// calling a query from a variable returned from a `render` method
1617
const utils = render(<Component />);
1718
utils.getByText('foo');
19+
utils.container.querySelector('foo');
1820

1921
// using after render
2022
render(<Component />).getByText('foo');
23+
render(<Component />).container.querySelector('foo');
2124

2225
// calling a query from a custom `render` method that returns an array
23-
const [getByText] = myCustomRender(<Component />);
26+
const [getByText, container] = myCustomRender(<Component />);
2427
getByText('foo');
28+
container.querySelector('foo');
2529
```
2630

2731
Examples of **correct** code for this rule:
@@ -32,17 +36,21 @@ import { screen } from '@testing-library/any-framework';
3236
// calling a query from the `screen` object
3337
render(<Component />);
3438
screen.getByText('foo');
39+
screen.container.querySelector('foo');
3540

3641
// using after within clause
3742
within(screen.getByTestId('section')).getByText('foo');
43+
within(screen.getByTestId('section')).container.querySelector('foo');
3844

3945
// calling a query method returned from a within call
40-
const { getByText } = within(screen.getByText('foo'));
46+
const { getByText, container } = within(screen.getByText('foo'));
4147
getByText('foo');
48+
container.querySelector('foo');
4249

4350
// calling a method directly from a variable created by within
4451
const myWithinVariable = within(screen.getByText('foo'));
4552
myWithinVariable.getByText('foo');
53+
myWithinVariable.container.querySelector('foo');
4654
```
4755

4856
## Further Reading

lib/rules/prefer-screen-queries.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const RULE_NAME = 'prefer-screen-queries';
1212
export type MessageIds = 'preferScreenQueries';
1313
type Options = [];
1414

15-
const ALL_QUERIES_COMBINATIONS_REGEXP = ALL_QUERIES_COMBINATIONS.join('|');
15+
const ALL_QUERIES_COMBINATIONS_REGEXP = [...ALL_QUERIES_COMBINATIONS, 'container'].join('|');
1616

1717
export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
1818
name: RULE_NAME,
@@ -93,7 +93,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
9393
isIdentifier(node) &&
9494
isMemberExpression(node.parent) &&
9595
isCallExpression(node.parent.object) &&
96-
isIdentifier(node.parent.object.callee) &&
96+
isIdentifier(node.parent.object.callee) &&
9797
node.parent.object.callee.name !== 'within'
9898
) {
9999
reportInvalidUsage(node);

tests/lib/rules/prefer-screen-queries.test.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { ALL_QUERIES_COMBINATIONS } from '../../../lib/utils';
44

55
const ruleTester = createRuleTester();
66

7+
const ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER = [...ALL_QUERIES_COMBINATIONS, 'container']
8+
79
ruleTester.run(RULE_NAME, rule, {
810
valid: [
9-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
11+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
1012
code: `screen.${queryMethod}()`,
1113
})),
1214
{
@@ -15,19 +17,19 @@ ruleTester.run(RULE_NAME, rule, {
1517
{
1618
code: `component.otherFunctionShouldNotThrow()`,
1719
},
18-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
20+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
1921
code: `within(component).${queryMethod}()`,
2022
})),
21-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
23+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
2224
code: `within(screen.${queryMethod}()).${queryMethod}()`,
2325
})),
24-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
26+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
2527
code: `
2628
const { ${queryMethod} } = within(screen.getByText('foo'))
2729
${queryMethod}(baz)
2830
`,
2931
})),
30-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
32+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
3133
code: `
3234
const myWithinVariable = within(foo)
3335
myWithinVariable.${queryMethod}('baz')
@@ -36,7 +38,7 @@ ruleTester.run(RULE_NAME, rule, {
3638
],
3739

3840
invalid: [
39-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
41+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
4042
code: `${queryMethod}()`,
4143
errors: [
4244
{
@@ -48,7 +50,7 @@ ruleTester.run(RULE_NAME, rule, {
4850
],
4951
})),
5052

51-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
53+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
5254
code: `render().${queryMethod}()`,
5355
errors: [
5456
{
@@ -60,7 +62,7 @@ ruleTester.run(RULE_NAME, rule, {
6062
],
6163
})),
6264

63-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
65+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
6466
code: `component.${queryMethod}()`,
6567
errors: [
6668
{
@@ -71,7 +73,7 @@ ruleTester.run(RULE_NAME, rule, {
7173
},
7274
],
7375
})),
74-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
76+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
7577
code: `
7678
const { ${queryMethod} } = render()
7779
${queryMethod}(baz)
@@ -85,7 +87,7 @@ ruleTester.run(RULE_NAME, rule, {
8587
},
8688
],
8789
})),
88-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
90+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
8991
code: `
9092
const myRenderVariable = render()
9193
myRenderVariable.${queryMethod}(baz)
@@ -99,7 +101,7 @@ ruleTester.run(RULE_NAME, rule, {
99101
},
100102
],
101103
})),
102-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
104+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
103105
code: `
104106
const [myVariable] = render()
105107
myVariable.${queryMethod}(baz)
@@ -113,7 +115,7 @@ ruleTester.run(RULE_NAME, rule, {
113115
},
114116
],
115117
})),
116-
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
118+
...ALL_QUERIES_COMBINATIONS_PLUS_CONTAINER.map(queryMethod => ({
117119
code: `
118120
const [myVariable] = within()
119121
myVariable.${queryMethod}(baz)

0 commit comments

Comments
 (0)