feat: allow custom runner configuration options (tuple format)#16141
Conversation
✅ Deploy Preview for jestjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
babel-jest
babel-plugin-jest-hoist
babel-preset-jest
create-jest
@jest/diff-sequences
expect
@jest/expect-utils
jest
jest-changed-files
jest-circus
jest-cli
jest-config
@jest/console
@jest/core
@jest/create-cache-key-function
jest-diff
jest-docblock
jest-each
@jest/environment
jest-environment-jsdom
@jest/environment-jsdom-abstract
jest-environment-node
@jest/expect
@jest/fake-timers
@jest/get-type
@jest/globals
jest-haste-map
jest-jasmine2
jest-leak-detector
jest-matcher-utils
jest-message-util
jest-mock
@jest/pattern
jest-phabricator
jest-regex-util
@jest/reporters
jest-resolve
jest-resolve-dependencies
jest-runner
jest-runtime
@jest/schemas
jest-snapshot
@jest/snapshot-utils
@jest/source-map
@jest/test-result
@jest/test-sequencer
@jest/transform
@jest/types
jest-util
jest-validate
jest-watcher
jest-worker
pretty-format
commit: |
11710cf to
d6e3d44
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds support for configuring custom test runners via a tuple config format (similar to reporters/watch plugins), normalizing the tuple into a resolved runner path plus a runnerOptions object, and then passing those options into the runner constructor.
Changes:
- Extend config schema/types to support
runner: string | [string, object]and introducerunnerOptionson normalizedProjectConfig. - Normalize tuple runner configs into
runner+runnerOptions, and pass options as an optional 3rd argument when instantiating runners. - Add unit/e2e coverage and documentation for the new tuple format.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/test-utils/src/config.ts | Adds runnerOptions to the default project config used by tests. |
| packages/jest-types/src/Config.ts | Adds runnerOptions to public normalized config types. |
| packages/jest-transform/src/tests/snapshots/ScriptTransformer.test.ts.snap | Updates snapshots to include runnerOptions in config serialization. |
| packages/jest-schemas/src/raw-types.ts | Updates schema for runner to allow tuple and adds runnerOptions. |
| packages/jest-runner/src/types.ts | Extends base runner constructor to accept optional options. |
| packages/jest-core/src/TestScheduler.ts | Passes runnerOptions to runner constructor and keys runner instances by runner+options. |
| packages/jest-core/src/lib/tests/snapshots/logDebugMessages.test.ts.snap | Snapshot update to include runnerOptions. |
| packages/jest-core/src/tests/TestScheduler.test.js | Adds unit tests for passing options and deduping runner instances. |
| packages/jest-config/src/ValidConfig.ts | Updates valid config examples to allow tuple runner and includes runnerOptions. |
| packages/jest-config/src/normalize.ts | Normalizes tuple runner config and sets runnerOptions. |
| packages/jest-config/src/index.ts | Ensures runnerOptions is included in grouped projectConfig. |
| packages/jest-config/src/Defaults.ts | Adds default runnerOptions: {}. |
| packages/jest-config/src/tests/normalize.test.ts | Adds normalization/validation tests for tuple runner config. |
| e2e/runner-options/runner.js | Adds a custom runner fixture that records received options. |
| e2e/runner-options/package.json | Adds an e2e fixture config using tuple runner options. |
| e2e/runner-options/tests/dummy.test.js | Adds a minimal test file for the e2e fixture. |
| e2e/tests/runnerOptions.test.ts | Adds an e2e test asserting options reach the runner. |
| e2e/tests/snapshots/showConfig.test.ts.snap | Snapshot update to include runnerOptions. |
| docs/Configuration.md | Documents tuple runner config and constructor options parameter. |
| CHANGELOG.md | Adds a feature entry describing tuple runner options support. |
18e13b2 to
0f188fb
Compare
SimenB
left a comment
There was a problem hiding this comment.
On fire knocking out these old issues! 😀 Thanks!
8c662a2 to
909a547
Compare
909a547 to
a0678b6
Compare
| datasource | package | from | to | | ---------- | ------- | ------ | ------ | | npm | jest | 30.3.0 | 30.4.2 | ## [v30.4.2](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3042) ##### Fixes - `[jest-runtime]` Fix named imports from CJS modules whose `module.exports` is a function with own-property exports ([#16150](jestjs/jest#16150)) ## [v30.4.1](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3041) ##### Features - `[jest-config, jest-core, jest-runner, jest-schemas, jest-types]` Allow custom runner configuration options via tuple format `['runner-path', {options}]` ([#16141](jestjs/jest#16141)) ##### Fixes - `[jest-runtime]` Align CJS-from-ESM default export with Node: `module.exports` is always the ESM default, `__esModule` unwrapping is no longer applied ([#16143](jestjs/jest#16143)) ## [v30.4.0](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3040) ##### Features - `[babel-jest]` Support collecting coverage from `.mts`, `.cts` (and other) files ([#15994](jestjs/jest#15994)) - `[jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types]` Add `--collect-tests` flag to discover and list tests without executing them ([#16006](jestjs/jest#16006)) - `[jest-config, jest-runner, jest-worker]` Add `workerGracefulExitTimeout` config option to control how long workers are given to exit before being force-killed ([#15984](jestjs/jest#15984)) - `[jest-config]` Add support for `jest.config.mts` as a valid configuration file ([#16005](jestjs/jest#16005)) - `[jest-config, jest-core, jest-reporters, jest-runner]` `verbose` and `silent` can now be set per-project; the project-level value overrides the global value for that project's tests ([#16133](jestjs/jest#16133)) - `[@jest/fake-timers]` Accept `Temporal.Duration` in `jest.advanceTimersByTime()` and `jest.advanceTimersByTimeAsync()` ([#16128](jestjs/jest#16128)) - `[@jest/fake-timers]` Accept `Temporal.Instant` and `Temporal.ZonedDateTime` in `jest.setSystemTime()` and `useFakeTimers({now})` ([#16128](jestjs/jest#16128)) - `[@jest/fake-timers]` Support faking `Temporal.Now.*` ([#16131](jestjs/jest#16131)) - `[jest-mock]` Add `clearMocksOnScope(scope)` on `ModuleMocker` for clearing every mock function exposed on a scope object ([#16088](jestjs/jest#16088)) - `[jest-resolve]` Add `canResolveSync()` on `Resolver` so callers can detect when a user-configured resolver only exports an `async` hook ([#16064](jestjs/jest#16064)) - `[jest-runtime]` Use synchronous `evaluate()` for ES modules without top-level `await` on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured ([#16062](jestjs/jest#16062)) - `[jest-runtime]` Support `require()` of ES modules on Node v24.9+ ([#16074](jestjs/jest#16074)) - `[jest-runtime]` Validate TC39 import attributes (`with { type: 'json' }`) on ESM imports ([#16127](jestjs/jest#16127)) - `[@jest/transform]` Add `canTransformSync(filename)` on `ScriptTransformer` so callers can pick the sync vs async transform path ([#16062](jestjs/jest#16062)) - `[jest-util]` Add `isError` helper ([#16076](jestjs/jest#16076)) - `[pretty-format]` Support React 19 ([#16123](jestjs/jest#16123)) ##### Fixes - `[expect-utils]` Fix `toStrictEqual` failing on `structuredClone` results due to cross-realm constructor mismatch ([#15959](jestjs/jest#15959)) - `[@jest/expect-utils]` Prevent `toMatchObject`/subset matching from throwing when encountering exotic iterables ([#15952](jestjs/jest#15952)) - `[fake-timers]` Convert `Date` to milliseconds before passing to `@sinonjs/fake-timers` ([#16029](jestjs/jest#16029)) - `[jest]` Export `GlobalConfig` and `ProjectConfig` TypeScript types ([#16132](jestjs/jest#16132)) - `[jest-circus]` Prevent crash when `asyncError` is undefined for non-Error throws ([#16003](jestjs/jest#16003)) - `[jest-circus, jest-jasmine2]` Include `Error.cause` in JSON `failureMessages` output ([#15967](jestjs/jest#15967)) - `[jest-config]` Fix preset path resolution on Windows when the preset uses subpath `exports` ([#15961](jestjs/jest#15961)) - `[jest-config]` Allow `collectCoverage` and `coverageProvider` in project config without a validation warning ([#16132](jestjs/jest#16132)) - `[jest-config]` Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options ([#16132](jestjs/jest#16132)) - `[jest-environment-node]` Fix `--localstorage-file` warning on Node 25+ ([#16086](jestjs/jest#16086)) - `[jest-reporters]` Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds ([#16137](jestjs/jest#16137)) - `[jest-reporters, jest-runner, jest-runtime, jest-transform]` Fix coverage report not showing correct code coverage when using `projects` config option ([#16140](jestjs/jest#16140)) - `[jest-runtime]` Resolve `expect` and `@jest/expect` from the internal module registry so test-file imports share the same `JestAssertionError` as the global `expect` ([#16130](jestjs/jest#16130)) - `[jest-runtime]` Improve CJS-from-ESM interop: `__esModule`/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Load `.js` files with ESM syntax but no `"type":"module"` marker as native ESM ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Extend the `.js`-with-ESM-syntax fallback to `require()` on Node v24.9+ - falls back to `require(esm)` when the CJS parser rejects ESM syntax ([#16078](jestjs/jest#16078)) - `[jest-runtime]` Fix deadlocks and double-evaluation in concurrent ESM and wasm imports ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Fix error when `require()` is called after the Jest environment has been torn down ([#15951](jestjs/jest#15951)) - `[jest-runtime]` Fix missing error when `import()` is called after the Jest environment has been torn down ([#16080](jestjs/jest#16080)) - `[jest-runtime]` Fix virtual `unstable_mockModule` registrations not respected in ESM ([#16081](jestjs/jest#16081)) - `[jest-runtime]` Apply `moduleNameMapper` when resolving modules with `require.resolve()` and the `paths` option ([#16135](jestjs/jest#16135)) ##### Chore & Maintenance - `[@jest/fake-timers]` Upgrade `@sinonjs/fake-timers` ([#16139](jestjs/jest#16139)) - `[jest-runtime]` Use synchronous `linkRequests` / `instantiate` for ESM linking on Node v24.9+ ([#16063](jestjs/jest#16063))
| datasource | package | from | to | | ---------- | ------- | ------ | ------ | | npm | jest | 30.3.0 | 30.4.2 | ## [v30.4.2](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3042) ##### Fixes - `[jest-runtime]` Fix named imports from CJS modules whose `module.exports` is a function with own-property exports ([#16150](jestjs/jest#16150)) ## [v30.4.1](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3041) ##### Features - `[jest-config, jest-core, jest-runner, jest-schemas, jest-types]` Allow custom runner configuration options via tuple format `['runner-path', {options}]` ([#16141](jestjs/jest#16141)) ##### Fixes - `[jest-runtime]` Align CJS-from-ESM default export with Node: `module.exports` is always the ESM default, `__esModule` unwrapping is no longer applied ([#16143](jestjs/jest#16143)) ## [v30.4.0](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3040) ##### Features - `[babel-jest]` Support collecting coverage from `.mts`, `.cts` (and other) files ([#15994](jestjs/jest#15994)) - `[jest-circus, jest-cli, jest-config, jest-core, jest-jasmine2, jest-types]` Add `--collect-tests` flag to discover and list tests without executing them ([#16006](jestjs/jest#16006)) - `[jest-config, jest-runner, jest-worker]` Add `workerGracefulExitTimeout` config option to control how long workers are given to exit before being force-killed ([#15984](jestjs/jest#15984)) - `[jest-config]` Add support for `jest.config.mts` as a valid configuration file ([#16005](jestjs/jest#16005)) - `[jest-config, jest-core, jest-reporters, jest-runner]` `verbose` and `silent` can now be set per-project; the project-level value overrides the global value for that project's tests ([#16133](jestjs/jest#16133)) - `[@jest/fake-timers]` Accept `Temporal.Duration` in `jest.advanceTimersByTime()` and `jest.advanceTimersByTimeAsync()` ([#16128](jestjs/jest#16128)) - `[@jest/fake-timers]` Accept `Temporal.Instant` and `Temporal.ZonedDateTime` in `jest.setSystemTime()` and `useFakeTimers({now})` ([#16128](jestjs/jest#16128)) - `[@jest/fake-timers]` Support faking `Temporal.Now.*` ([#16131](jestjs/jest#16131)) - `[jest-mock]` Add `clearMocksOnScope(scope)` on `ModuleMocker` for clearing every mock function exposed on a scope object ([#16088](jestjs/jest#16088)) - `[jest-resolve]` Add `canResolveSync()` on `Resolver` so callers can detect when a user-configured resolver only exports an `async` hook ([#16064](jestjs/jest#16064)) - `[jest-runtime]` Use synchronous `evaluate()` for ES modules without top-level `await` on Node versions that support it (v24.9+), and prefer the synchronous transform path when a sync transformer is configured ([#16062](jestjs/jest#16062)) - `[jest-runtime]` Support `require()` of ES modules on Node v24.9+ ([#16074](jestjs/jest#16074)) - `[jest-runtime]` Validate TC39 import attributes (`with { type: 'json' }`) on ESM imports ([#16127](jestjs/jest#16127)) - `[@jest/transform]` Add `canTransformSync(filename)` on `ScriptTransformer` so callers can pick the sync vs async transform path ([#16062](jestjs/jest#16062)) - `[jest-util]` Add `isError` helper ([#16076](jestjs/jest#16076)) - `[pretty-format]` Support React 19 ([#16123](jestjs/jest#16123)) ##### Fixes - `[expect-utils]` Fix `toStrictEqual` failing on `structuredClone` results due to cross-realm constructor mismatch ([#15959](jestjs/jest#15959)) - `[@jest/expect-utils]` Prevent `toMatchObject`/subset matching from throwing when encountering exotic iterables ([#15952](jestjs/jest#15952)) - `[fake-timers]` Convert `Date` to milliseconds before passing to `@sinonjs/fake-timers` ([#16029](jestjs/jest#16029)) - `[jest]` Export `GlobalConfig` and `ProjectConfig` TypeScript types ([#16132](jestjs/jest#16132)) - `[jest-circus]` Prevent crash when `asyncError` is undefined for non-Error throws ([#16003](jestjs/jest#16003)) - `[jest-circus, jest-jasmine2]` Include `Error.cause` in JSON `failureMessages` output ([#15967](jestjs/jest#15967)) - `[jest-config]` Fix preset path resolution on Windows when the preset uses subpath `exports` ([#15961](jestjs/jest#15961)) - `[jest-config]` Allow `collectCoverage` and `coverageProvider` in project config without a validation warning ([#16132](jestjs/jest#16132)) - `[jest-config]` Project config validator now emits "is not supported in an individual project configuration" instead of "probably a typing mistake" for known global-only options ([#16132](jestjs/jest#16132)) - `[jest-environment-node]` Fix `--localstorage-file` warning on Node 25+ ([#16086](jestjs/jest#16086)) - `[jest-reporters]` Apply global coverage threshold to unmatched pattern files in addition to glob/path thresholds ([#16137](jestjs/jest#16137)) - `[jest-reporters, jest-runner, jest-runtime, jest-transform]` Fix coverage report not showing correct code coverage when using `projects` config option ([#16140](jestjs/jest#16140)) - `[jest-runtime]` Resolve `expect` and `@jest/expect` from the internal module registry so test-file imports share the same `JestAssertionError` as the global `expect` ([#16130](jestjs/jest#16130)) - `[jest-runtime]` Improve CJS-from-ESM interop: `__esModule`/Babel default unwrap, broader named-export coverage, and shared CJS singleton across importers ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Load `.js` files with ESM syntax but no `"type":"module"` marker as native ESM ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Extend the `.js`-with-ESM-syntax fallback to `require()` on Node v24.9+ - falls back to `require(esm)` when the CJS parser rejects ESM syntax ([#16078](jestjs/jest#16078)) - `[jest-runtime]` Fix deadlocks and double-evaluation in concurrent ESM and wasm imports ([#16050](jestjs/jest#16050)) - `[jest-runtime]` Fix error when `require()` is called after the Jest environment has been torn down ([#15951](jestjs/jest#15951)) - `[jest-runtime]` Fix missing error when `import()` is called after the Jest environment has been torn down ([#16080](jestjs/jest#16080)) - `[jest-runtime]` Fix virtual `unstable_mockModule` registrations not respected in ESM ([#16081](jestjs/jest#16081)) - `[jest-runtime]` Apply `moduleNameMapper` when resolving modules with `require.resolve()` and the `paths` option ([#16135](jestjs/jest#16135)) ##### Chore & Maintenance - `[@jest/fake-timers]` Upgrade `@sinonjs/fake-timers` ([#16139](jestjs/jest#16139)) - `[jest-runtime]` Use synchronous `linkRequests` / `instantiate` for ESM linking on Node v24.9+ ([#16063](jestjs/jest#16063))
Summary
Resolves #4278
Adds support for passing configuration options to custom test runners using a tuple format, similar to how reporters and watch plugins are configured:
Changes
runnerconfig acceptsstring | [string, Record<string, unknown>]; newrunnerOptionsfield onProjectConfigrunner) + options (runnerOptions); plain string remains backward-compatiblemultipleValidOptionsallows both formats(globalConfig, context, options?)Breaking changes
None. Existing
runner: 'string'configs continue to work unchanged. The 3rd constructor parameter is optional.Test plan
yarn build:tspassestransform-runnere2e test passes (backward compat)runnerOptionse2e test passes (tuple config delivers options to runner)