Skip to content

feat(prefer-top-level-configure): add rule to disallow configure inside tests - #1371

Open
gaurav-init wants to merge 2 commits into
testing-library:mainfrom
gaurav-init:pr/prefer-top-level-configure
Open

feat(prefer-top-level-configure): add rule to disallow configure inside tests#1371
gaurav-init wants to merge 2 commits into
testing-library:mainfrom
gaurav-init:pr/prefer-top-level-configure

Conversation

@gaurav-init

Copy link
Copy Markdown

Summary

Closes #997.

Calling configure() inside a test body sets global Testing Library options that persist for the rest of the test run. Because there is no automatic reset between tests, this creates implicit ordering dependencies — test results start to depend on which tests ran before them, and each test becomes harder to reason about in isolation.

What the rule does

Warns when configure imported from a Testing Library package is called inside a test, it, xit, xtest, or any of their .each/.only/.skip variants. Top-level calls and beforeAll/beforeEach hooks are allowed.

Invalid:

import { configure } from '@testing-library/react';

test('some test', () => {
  configure({ asyncUtilTimeout: 5000 }); // ← warns
});

test.each([1, 2])('parameterized %i', () => {
  configure({ reactStrictMode: true }); // ← warns
});

Valid:

import { configure } from '@testing-library/react';

configure({ asyncUtilTimeout: 5000 }); // top-level — OK

beforeAll(() => {
  configure({ reactStrictMode: true }); // setup hook — OK
});

Details

  • Aliased imports (import { configure as tlConfigure }) are correctly handled via the imported specifier name.
  • The rule is enabled at warn severity in all framework configs (dom, angular, react, vue, svelte, marko) — matching the issue's "warns about a potential error" category.
  • Tests cover: all supported frameworks, beforeAll/beforeEach hooks, non-TL imports, aliased imports, test.each/it.each (curried form), test.only/it.skip, nested helper functions inside tests, xit/xtest.
  • generate:docs and generate:configs were run; README and all config files updated automatically.

…de tests

Calling configure() inside a test body sets global Testing Library options
that persist across tests, creating implicit ordering dependencies and making
individual tests harder to reason about. The rule warns when configure is
called inside test, it, xit, xtest, or their .each/.only/.skip variants,
and allows top-level calls and beforeAll/beforeEach hooks.

Aliased imports (configure as tlConfigure) are handled via the imported
specifier name. Closes testing-library#997.
Copilot AI lite review requested due to automatic review settings August 7, 2026 01:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new ESLint rule to prevent calling Testing Library’s global configure() from inside test bodies, avoiding cross-test side effects and order-dependent tests.

Changes:

  • Introduces testing-library/prefer-top-level-configure rule implementation and registers it in the plugin.
  • Adds rule tests and rule documentation.
  • Enables the rule at warn severity across all framework configs and updates the README rules table.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/rules/prefer-top-level-configure.test.ts Adds RuleTester coverage for valid/invalid configure() call locations.
src/rules/prefer-top-level-configure.ts Implements the new rule and reports configure() calls found inside test bodies.
src/rules/index.ts Registers the new rule in the exported rules map.
src/configs/angular.ts Enables the rule at warn in the Angular preset.
src/configs/dom.ts Enables the rule at warn in the DOM preset.
src/configs/react.ts Enables the rule at warn in the React preset.
src/configs/vue.ts Enables the rule at warn in the Vue preset.
src/configs/svelte.ts Enables the rule at warn in the Svelte preset.
src/configs/marko.ts Enables the rule at warn in the Marko preset.
README.md Adds the new rule to the rules documentation table.
docs/rules/prefer-top-level-configure.md Adds end-user documentation and examples for the new rule.

Comment thread src/rules/prefer-top-level-configure.ts Outdated
Comment on lines +48 to +58
// test.each([1, 2])('title', fn) — curried form
// callee is the result of test.each([...]), i.e. a CallExpression whose
// own callee is the MemberExpression test.each / it.each
if (
isCallExpression(callee) &&
isMemberExpression(callee.callee) &&
ASTUtils.isIdentifier(callee.callee.object) &&
TEST_FUNCTION_NAMES.has(callee.callee.object.name)
) {
return true;
}
Comment on lines +54 to +65
import { configure, cleanup } from '@testing-library/react';

let previousConfig;

beforeAll(() => {
// OK: inside a setup hook
previousConfig = configure({ asyncUtilTimeout: 5000 });
});

afterAll(() => {
configure(previousConfig);
});
Comment on lines +6 to +12
const SUPPORTED_TESTING_FRAMEWORKS = [
'@testing-library/dom',
'@testing-library/angular',
'@testing-library/react',
'@testing-library/vue',
'@marko/testing-library',
];
…d Svelte to test matrix

Extend isInsideTestBody to walk the full MemberExpression/CallExpression
chain leftward to the root identifier, so test.only.each([…])(…) and other
chained variants are correctly detected in addition to test.each and
test.only. Add @testing-library/svelte to the rule test matrix.
Copilot AI review requested due to automatic review settings August 7, 2026 02:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (5)

docs/rules/prefer-top-level-configure.md:58

  • The example implies configure() returns the previous config (previousConfig = configure(...)), but configure() returns void in Testing Library. The snippet should use getConfig() to capture the current config before overriding it (and the cleanup import is unused).
import { configure, cleanup } from '@testing-library/react';

let previousConfig;

beforeAll(() => {

src/rules/prefer-top-level-configure.ts:111

  • The rule currently only matches configure when it’s a named ES import (ImportSpecifier). If configure is called via a Testing Library namespace import (import * as rtl from ...; rtl.configure(...)) or CommonJS require default (const rtl = require(...); rtl.configure(...)), findImportedTestingLibraryUtilSpecifier('configure') returns a non-ImportSpecifier and the rule silently skips reporting.
				// Resolve the import specifier for this local identifier name and
				// verify the original exported name is 'configure'.
				// This handles both direct imports and aliased imports:
				//   import { configure } from '@testing-library/react'
				//   import { configure as tlConfigure } from '@testing-library/react'

tests/rules/prefer-top-level-configure.test.ts:94

  • Test coverage doesn’t currently include calling configure via a Testing Library namespace import (import * as rtl) or CommonJS require (const rtl = require(...)). Since the rule is intended to warn whenever configure comes from a TL package, add invalid test cases for these import styles (and optionally const { configure } = require(...)).
		// configure inside test.each
		{
			code: `
        import { configure } from '@testing-library/react';
        test.each([1, 2])('fails %i', () => {

docs/rules/prefer-top-level-configure.md:5

  • The auto-generated rule header is missing the line that indicates which configs enable this rule (e.g. “⚠️ This rule warns in the following configs …”), even though the file includes the <!-- end auto-generated rule header --> marker. This usually means pnpm run generate:docs wasn’t applied to this new rule doc output.

This issue also appears on line 54 of the same file.

# testing-library/prefer-top-level-configure

📝 Disallow calling `configure` inside test functions to avoid cross-test side effects.

<!-- end auto-generated rule header -->

README.md:359

  • In the rules table, prefer-top-level-configure is missing the config badges in the ⚠️ (warn) column even though the rule is configured as warn in all framework configs in this PR. This points to generated README output being out of sync.
| [prefer-top-level-configure](docs/rules/prefer-top-level-configure.md)           | Disallow calling `configure` inside test functions to avoid cross-test side effects          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |     |

@gaurav-init

Copy link
Copy Markdown
Author

Hey @Belco90 — would love your feedback when you get a chance! This implements the rule you confirmed in the issue. Happy to adjust anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disallow calling configure inside of a test

2 participants