From 9f1832fb046190a1746dd253264b29f549fe5daf Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 27 Sep 2025 15:04:11 +0900 Subject: [PATCH 1/4] feat: add auto-fix for no-wait-for-side-effects --- lib/rules/no-wait-for-side-effects.ts | 50 ++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/rules/no-wait-for-side-effects.ts b/lib/rules/no-wait-for-side-effects.ts index aeea5640..04e17b7f 100644 --- a/lib/rules/no-wait-for-side-effects.ts +++ b/lib/rules/no-wait-for-side-effects.ts @@ -42,6 +42,8 @@ export default createTestingLibraryRule({ }, defaultOptions: [], create(context, _, helpers) { + const sourceCode = getSourceCode(context); + function isCallerWaitFor( node: | TSESTree.AssignmentExpression @@ -155,8 +157,6 @@ export default createTestingLibraryRule({ } return false; }); - - return false; } function getSideEffectNodes( @@ -195,7 +195,17 @@ export default createTestingLibraryRule({ }) as TSESTree.ExpressionStatement[]; } - function reportSideEffects(node: TSESTree.BlockStatement) { + function reportSideEffects( + node: TSESTree.BlockStatement & { + parent: ( + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + ) & { + parent: TSESTree.CallExpression; + }; + } + ) { if (!isCallerWaitFor(node)) { return; } @@ -208,6 +218,38 @@ export default createTestingLibraryRule({ context.report({ node: sideEffectNode, messageId: 'noSideEffectsWaitFor', + fix(fixer) { + const { parent: callExpressionNode } = node.parent; + const targetNode = isAwaitExpression(callExpressionNode.parent) + ? callExpressionNode.parent + : callExpressionNode; + const lines = sourceCode.getText().split('\n'); + + const line = lines[targetNode.loc.start.line - 1]; + + const indent = line.match(/^\s*/)?.[0] ?? ''; + const lineStart = sourceCode.getIndexFromLoc({ + line: sideEffectNode.loc.start.line, + column: 0, + }); + const lineEnd = sourceCode.getIndexFromLoc({ + line: sideEffectNode.loc.end.line + 1, + column: 0, + }); + + const sideEffectLines = lines.slice( + sideEffectNode.loc.start.line - 1, + sideEffectNode.loc.end.line + ); + const sideEffectNodeText = sideEffectLines.join('\n'); + return [ + fixer.insertTextBefore( + targetNode, + sideEffectNodeText.trimStart() + '\n' + indent + ), + fixer.removeRange([lineStart, lineEnd]), + ]; + }, }) ); } @@ -260,7 +302,7 @@ export default createTestingLibraryRule({ const targetNode = isAwaitExpression(callExpressionNode.parent) ? callExpressionNode.parent : callExpressionNode; - const sourceCode = getSourceCode(context); + return fixer.replaceText(targetNode, sourceCode.getText(node)); }, }); From cd6b1b8cb2425288c08e1d647abbd6fe3d35e478 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 27 Sep 2025 15:05:46 +0900 Subject: [PATCH 2/4] test: add tests --- .../rules/no-wait-for-side-effects.test.ts | 337 +++++++++++++++++- 1 file changed, 336 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-wait-for-side-effects.test.ts b/tests/lib/rules/no-wait-for-side-effects.test.ts index eaf9af2c..8213e0fb 100644 --- a/tests/lib/rules/no-wait-for-side-effects.test.ts +++ b/tests/lib/rules/no-wait-for-side-effects.test.ts @@ -363,6 +363,17 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; render() + `, + }, + { + code: ` + import { waitFor } from '${testingFramework}'; + waitFor(() => render()) + `, + errors: [{ line: 3, column: 23, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + render() `, }, { @@ -373,6 +384,27 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + render() + await waitFor(function() { + }) + `, + }, + { + code: ` + import { waitFor } from '${testingFramework}'; + waitFor(function() { + render() + }) + `, + errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + render() + waitFor(function() { + }) + `, }, { code: ` @@ -382,6 +414,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + const { container } = renderHelper() + await waitFor(function() { + }) + `, }, { settings: { 'testing-library/custom-renders': ['renderHelper'] }, @@ -407,6 +445,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + import { renderHelper } from 'somewhere-else'; + renderHelper() + await waitFor(() => { + }) + `, }, { settings: { 'testing-library/custom-renders': ['renderHelper'] }, @@ -418,6 +463,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + import { renderHelper } from 'somewhere-else'; + const { container } = renderHelper() + await waitFor(() => { + }) + `, }, { settings: { 'testing-library/custom-renders': ['renderHelper'] }, @@ -430,6 +482,14 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 6, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + import { renderHelper } from 'somewhere-else'; + let container; + ({ container } = renderHelper()) + await waitFor(() => { + }) + `, }, { code: ` @@ -539,6 +599,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + render() + await waitFor(() => { + }) + `, }, { code: ` @@ -548,6 +614,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + const { container } = render() + await waitFor(() => { + }) + `, }, { code: ` @@ -557,6 +629,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + result = render() + await waitFor(() => { + }) + `, }, { code: ` @@ -566,7 +644,22 @@ ruleTester.run(RULE_NAME, rule, { { container } = render() }) `, - errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + errors: [ + { + line: 4, + column: 11, + messageId: 'noSideEffectsWaitFor', + endLine: 5, + endColumn: 42, + }, + ], + output: ` + import { waitFor } from '${testingFramework}'; + const a = 5, + { container } = render() + await waitFor(() => { + }) + `, }, { code: ` @@ -577,6 +670,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + const { rerender } = render() + rerender() + await waitFor(() => { + }) + `, }, { code: ` @@ -590,6 +690,22 @@ ruleTester.run(RULE_NAME, rule, { { line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }, { line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }, ], + output: [ + ` + import { waitFor } from '${testingFramework}'; + render() + await waitFor(() => { + fireEvent.keyDown(input, {key: 'ArrowDown'}) + }) + `, + ` + import { waitFor } from '${testingFramework}'; + render() + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + }) + `, + ], }, { code: ` @@ -603,6 +719,22 @@ ruleTester.run(RULE_NAME, rule, { { line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }, { line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }, ], + output: [ + ` + import { waitFor } from '${testingFramework}'; + render() + await waitFor(() => { + userEvent.click(button) + }) + `, + ` + import { waitFor } from '${testingFramework}'; + render() + userEvent.click(button) + await waitFor(() => { + }) + `, + ], }, ] ), @@ -642,6 +774,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + }) + `, }, { code: ` @@ -651,6 +789,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor, fireEvent as renamedFireEvent } from '${testingFramework}'; + renamedFireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + }) + `, }, ] ), @@ -663,6 +807,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor, fireEvent } from '~/test-utils'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + }) + `, }, ...SUPPORTED_TESTING_FRAMEWORKS.flatMap( (testingFramework) => [ @@ -675,6 +825,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -685,6 +842,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -694,6 +858,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(function() { + }) + `, }, { code: ` @@ -704,6 +874,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(function() { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -714,6 +891,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + fireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(function() { + expect(b).toEqual('b') + }) + `, }, ] ), @@ -739,6 +923,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(() => { + }) + `, }, { code: ` @@ -749,6 +939,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + import renamedUserEvent from '@testing-library/user-event' + renamedUserEvent.click(button) + await waitFor(() => { + }) + `, }, ] ), @@ -762,6 +959,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '~/test-utils'; + import userEvent from '@testing-library/user-event' + userEvent.click(); + await waitFor(() => { + }) + `, }, ...SUPPORTED_TESTING_FRAMEWORKS.flatMap( (testingFramework) => [ @@ -774,6 +978,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(() => { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -784,6 +995,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(() => { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -793,6 +1011,12 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(function() { + }) + `, }, { code: ` @@ -803,6 +1027,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(function() { + expect(b).toEqual('b') + }) + `, }, { code: ` @@ -813,6 +1044,13 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + await waitFor(function() { + expect(b).toEqual('b') + }) + `, }, { // Issue #500, https://github.com/testing-library/eslint-plugin-testing-library/issues/500 @@ -827,6 +1065,16 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + waitFor(function() { + expect(b).toEqual('b') + }).then(() => { + userEvent.click(button) // Side effects are allowed inside .then() + expect(b).toEqual('b') + }) + `, }, { // Issue #500, https://github.com/testing-library/eslint-plugin-testing-library/issues/500 @@ -848,6 +1096,20 @@ ruleTester.run(RULE_NAME, rule, { { line: 4, column: 11, messageId: 'noSideEffectsWaitFor' }, { line: 10, column: 13, messageId: 'noSideEffectsWaitFor' }, ], + output: ` + import { waitFor } from '${testingFramework}'; + userEvent.click(button) + waitFor(function() { + expect(b).toEqual('b') + }).then(() => { + userEvent.click(button) // Side effects are allowed inside .then() + expect(b).toEqual('b') + fireEvent.keyDown(input, {key: 'ArrowDown'}) // But not if there is a another waitFor with side effects inside the .then() + await waitFor(() => { + expect(b).toEqual('b') + }) + }) + `, }, ] ), @@ -874,6 +1136,40 @@ ruleTester.run(RULE_NAME, rule, { { line: 9, column: 13, messageId: 'noSideEffectsWaitFor' }, { line: 12, column: 13, messageId: 'noSideEffectsWaitFor' }, ], + output: [ + `// all mixed + import { waitFor, fireEvent as renamedFireEvent, screen } from '~/test-utils'; + import userEvent from '@testing-library/user-event' + import { fireEvent } from 'somewhere-else' + + test('check all mixed', async () => { + const button = await screen.findByRole('button') + renamedFireEvent.keyDown(input, {key: 'ArrowDown'}) + await waitFor(() => { + expect(b).toEqual('b') + fireEvent.keyDown(input, {key: 'ArrowDown'}) + userEvent.click(button) + someBool ? 'a' : 'b' // cover expression statement without identifier for 100% coverage + }) + }) + `, + `// all mixed + import { waitFor, fireEvent as renamedFireEvent, screen } from '~/test-utils'; + import userEvent from '@testing-library/user-event' + import { fireEvent } from 'somewhere-else' + + test('check all mixed', async () => { + const button = await screen.findByRole('button') + renamedFireEvent.keyDown(input, {key: 'ArrowDown'}) + userEvent.click(button) + await waitFor(() => { + expect(b).toEqual('b') + fireEvent.keyDown(input, {key: 'ArrowDown'}) + someBool ? 'a' : 'b' // cover expression statement without identifier for 100% coverage + }) + }) + `, + ], }, // side effects (userEvent, fireEvent or render) in variable declarations ...SUPPORTED_TESTING_FRAMEWORKS.flatMap( @@ -894,6 +1190,35 @@ ruleTester.run(RULE_NAME, rule, { { line: 6, column: 11, messageId: 'noSideEffectsWaitFor' }, { line: 7, column: 11, messageId: 'noSideEffectsWaitFor' }, ], + output: [ + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + await waitFor(() => { + const b = fireEvent.click(button); + const wrapper = render(); + }) + `, + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + const b = fireEvent.click(button); + await waitFor(() => { + const wrapper = render(); + }) + `, + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + const b = fireEvent.click(button); + const wrapper = render(); + await waitFor(() => { + }) + `, + ], }, ] ), @@ -912,6 +1237,16 @@ ruleTester.run(RULE_NAME, rule, { }); `, errors: [{ line: 7, column: 13, messageId: 'noSideEffectsWaitFor' }], + output: ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + + it("some test", async () => { + await fireEvent.click(screen.getByTestId("something")); + await waitFor(async () => { + }); + }); + `, }, ] ), From e27716545b89b27321b4bb7a14c3dfa54ee8f9ac Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 29 Sep 2025 23:41:43 +0900 Subject: [PATCH 3/4] fix: remove entire waitFor call when its body becomes empty after moving side effects --- lib/rules/no-wait-for-side-effects.ts | 34 ++++++++++++++++++++------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/rules/no-wait-for-side-effects.ts b/lib/rules/no-wait-for-side-effects.ts index 04e17b7f..3082d8b3 100644 --- a/lib/rules/no-wait-for-side-effects.ts +++ b/lib/rules/no-wait-for-side-effects.ts @@ -214,7 +214,8 @@ export default createTestingLibraryRule({ return; } - getSideEffectNodes(node.body).forEach((sideEffectNode) => + const sideEffects = getSideEffectNodes(node.body); + sideEffects.forEach((sideEffectNode) => context.report({ node: sideEffectNode, messageId: 'noSideEffectsWaitFor', @@ -223,11 +224,31 @@ export default createTestingLibraryRule({ const targetNode = isAwaitExpression(callExpressionNode.parent) ? callExpressionNode.parent : callExpressionNode; - const lines = sourceCode.getText().split('\n'); + const lines = sourceCode.getText().split('\n'); const line = lines[targetNode.loc.start.line - 1]; - const indent = line.match(/^\s*/)?.[0] ?? ''; + const sideEffectLines = lines.slice( + sideEffectNode.loc.start.line - 1, + sideEffectNode.loc.end.line + ); + const sideEffectNodeText = sideEffectLines.join('\n').trimStart(); + if ( + sideEffects.length === node.body.length && + sideEffects.length === 1 + ) { + const tokenAfter = sourceCode.getTokenAfter(targetNode); + return [ + fixer.insertTextBefore(targetNode, sideEffectNodeText), + tokenAfter?.value === ';' + ? fixer.removeRange([ + targetNode.range[0], + tokenAfter.range[1], + ]) + : fixer.remove(targetNode), + ]; + } + const lineStart = sourceCode.getIndexFromLoc({ line: sideEffectNode.loc.start.line, column: 0, @@ -237,15 +258,10 @@ export default createTestingLibraryRule({ column: 0, }); - const sideEffectLines = lines.slice( - sideEffectNode.loc.start.line - 1, - sideEffectNode.loc.end.line - ); - const sideEffectNodeText = sideEffectLines.join('\n'); return [ fixer.insertTextBefore( targetNode, - sideEffectNodeText.trimStart() + '\n' + indent + sideEffectNodeText + '\n' + indent ), fixer.removeRange([lineStart, lineEnd]), ]; From 9b90f0a2d2de5b351f44c1b437c78a27b0b97f51 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Mon, 29 Sep 2025 23:42:35 +0900 Subject: [PATCH 4/4] test: remove unnecessary waitFor calls --- .../rules/no-wait-for-side-effects.test.ts | 92 ++++++++++--------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/tests/lib/rules/no-wait-for-side-effects.test.ts b/tests/lib/rules/no-wait-for-side-effects.test.ts index 8213e0fb..9d302f98 100644 --- a/tests/lib/rules/no-wait-for-side-effects.test.ts +++ b/tests/lib/rules/no-wait-for-side-effects.test.ts @@ -387,8 +387,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; render() - await waitFor(function() { - }) `, }, { @@ -402,8 +400,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; render() - waitFor(function() { - }) `, }, { @@ -417,8 +413,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; const { container } = renderHelper() - await waitFor(function() { - }) `, }, { @@ -449,8 +443,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; import { renderHelper } from 'somewhere-else'; renderHelper() - await waitFor(() => { - }) `, }, { @@ -467,8 +459,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; import { renderHelper } from 'somewhere-else'; const { container } = renderHelper() - await waitFor(() => { - }) `, }, { @@ -487,8 +477,6 @@ ruleTester.run(RULE_NAME, rule, { import { renderHelper } from 'somewhere-else'; let container; ({ container } = renderHelper()) - await waitFor(() => { - }) `, }, { @@ -602,8 +590,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; render() - await waitFor(() => { - }) `, }, { @@ -617,8 +603,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; const { container } = render() - await waitFor(() => { - }) `, }, { @@ -632,8 +616,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; result = render() - await waitFor(() => { - }) `, }, { @@ -657,8 +639,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; const a = 5, { container } = render() - await waitFor(() => { - }) `, }, { @@ -674,8 +654,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; const { rerender } = render() rerender() - await waitFor(() => { - }) `, }, { @@ -702,8 +680,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; render() fireEvent.keyDown(input, {key: 'ArrowDown'}) - await waitFor(() => { - }) `, ], }, @@ -731,8 +707,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; render() userEvent.click(button) - await waitFor(() => { - }) `, ], }, @@ -777,8 +751,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; fireEvent.keyDown(input, {key: 'ArrowDown'}) - await waitFor(() => { - }) `, }, { @@ -792,8 +764,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor, fireEvent as renamedFireEvent } from '${testingFramework}'; renamedFireEvent.keyDown(input, {key: 'ArrowDown'}) - await waitFor(() => { - }) `, }, ] @@ -810,8 +780,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor, fireEvent } from '~/test-utils'; fireEvent.keyDown(input, {key: 'ArrowDown'}) - await waitFor(() => { - }) `, }, ...SUPPORTED_TESTING_FRAMEWORKS.flatMap( @@ -861,8 +829,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; fireEvent.keyDown(input, {key: 'ArrowDown'}) - await waitFor(function() { - }) `, }, { @@ -926,8 +892,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; userEvent.click(button) - await waitFor(() => { - }) `, }, { @@ -943,8 +907,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '${testingFramework}'; import renamedUserEvent from '@testing-library/user-event' renamedUserEvent.click(button) - await waitFor(() => { - }) `, }, ] @@ -963,8 +925,6 @@ ruleTester.run(RULE_NAME, rule, { import { waitFor } from '~/test-utils'; import userEvent from '@testing-library/user-event' userEvent.click(); - await waitFor(() => { - }) `, }, ...SUPPORTED_TESTING_FRAMEWORKS.flatMap( @@ -1014,8 +974,6 @@ ruleTester.run(RULE_NAME, rule, { output: ` import { waitFor } from '${testingFramework}'; userEvent.click(button) - await waitFor(function() { - }) `, }, { @@ -1215,7 +1173,55 @@ ruleTester.run(RULE_NAME, rule, { const a = userEvent.click(button); const b = fireEvent.click(button); const wrapper = render(); + `, + ], + }, + { + // Issue #368, https://github.com/testing-library/eslint-plugin-testing-library/issues/368 + code: ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' await waitFor(() => { + const a = userEvent.click(button); + const b = fireEvent.click(button); + const c = "hoge"; + const wrapper = render(); + }) + `, + errors: [ + { line: 5, column: 11, messageId: 'noSideEffectsWaitFor' }, + { line: 6, column: 11, messageId: 'noSideEffectsWaitFor' }, + { line: 8, column: 11, messageId: 'noSideEffectsWaitFor' }, + ], + output: [ + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + await waitFor(() => { + const b = fireEvent.click(button); + const c = "hoge"; + const wrapper = render(); + }) + `, + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + const b = fireEvent.click(button); + await waitFor(() => { + const c = "hoge"; + const wrapper = render(); + }) + `, + ` + import { waitFor } from '${testingFramework}'; + import userEvent from '@testing-library/user-event' + const a = userEvent.click(button); + const b = fireEvent.click(button); + const wrapper = render(); + await waitFor(() => { + const c = "hoge"; }) `, ], @@ -1243,8 +1249,6 @@ ruleTester.run(RULE_NAME, rule, { it("some test", async () => { await fireEvent.click(screen.getByTestId("something")); - await waitFor(async () => { - }); }); `, },