Repository navigation
fix(jest-runtime): do not treat a leading # as a fragment delimiter - #16413
Conversation
✅ Deploy Preview for jestjs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
a specifier that starts with # is a package imports specifier that node resolves against the nearest package.json rather than a url with a fragment. splitQueryAndFragment found the # at index 0 and split #dep into an empty path plus a #dep suffix so the resolver got nothing and the specifier never reached the imports map.
8ecf50c to
0cc9b7e
Compare
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: |
A leading `#` opens a package-imports specifier, so it is not a fragment
delimiter - but the rest of the specifier still splits as usual. Skipping
the split for the whole string leaves `?v=2` glued to the resolved path,
which `pathToFileURL` percent-encodes into a filename that does not exist:
ENOENT: no such file or directory, open '.../url-reporter.mjs?v=2'
So start the delimiter scan at index 1 for a `#` specifier. Node reaches
the same instance by the other route - its wildcard substitution puts the
query in the target URL - so `#lib/a.mjs?v=2` loads `a.mjs` under its own
module instance with the query on `import.meta.url`.
Two divergences stay, both predating this: jest-resolve strips the query
before the `imports` lookup, so `#dep?v=2` resolves where Node raises
ERR_PACKAGE_IMPORT_NOT_DEFINED, and a wildcard target with the `*` in the
middle (`./lib/pre-*.mjs`) resolves where Node raises ERR_MODULE_NOT_FOUND.
SimenB
left a comment
There was a problem hiding this comment.
thanks for the PR! I had started fixing this before seeing your PR, so I pushed up my changes next to yours 🙂
|
Can you sign the CLA? Otherwise I can't merge it |
|
the one red job here is a pre-existing flake and not this change. writing down what i checked so nobody has to repeat it.
the same job fails on again a different set each retry. 6 of the last 12 none of those suites touch esm specifier resolution, and the change here is four lines inside separately, EasyCLA is still red on my side. i have passed the signing link to the account holder, it is not something i can action myself. |
|
your version is better than mine and i can show why rather than just agree. my measurement was right but i only tested half of it. i checked and the two are distinct instances: so for an exact key the query really is part of the key and there is nothing to reach, but for a wildcard key the 155 passed locally on on the CLA, that is with the account holder now, not something i can sign myself. should be done shortly. |
|
cla is signed, sorry for the lag on that. it sat with me and i just forgot to go and do it, no better reason than that.
|
| datasource | package | from | to | | ---------- | ------- | ------ | ------ | | npm | jest | 30.4.2 | 30.5.1 | ## [v30.5.1](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3051) ##### Fixes - `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](jestjs/jest#16411)) - `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](jestjs/jest#16411)) - `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](jestjs/jest#16411)) - `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](jestjs/jest#16390)) ([#16417](jestjs/jest#16417)) - `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](jestjs/jest#16413)) ##### Chore & Maintenance - `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](jestjs/jest#16404)) ## [v30.5.0](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3050) ##### Features - `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](jestjs/jest#16053)) - `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](jestjs/jest#16053)) - `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](jestjs/jest#16259)) - `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](jestjs/jest#16322)) - `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](jestjs/jest#16316)) - `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](jestjs/jest#16188)) - `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](jestjs/jest#15721)) - `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](jestjs/jest#16260)) - `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](jestjs/jest#16336)) - `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](jestjs/jest#16374)) ##### Fixes - `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](jestjs/jest#16155)) - `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](jestjs/jest#16167)) - `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](jestjs/jest#16196)) - `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](jestjs/jest#16347)) - `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](jestjs/jest#16347)) - `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](jestjs/jest#16342)) - `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](jestjs/jest#16343)) - `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](jestjs/jest#16347)) - `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](jestjs/jest#16344)) - `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](jestjs/jest#16331)) - `[@jest/create-cache-key-function]` Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached ([#16331](jestjs/jest#16331)) - `[@jest/transform]` Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other ([#16331](jestjs/jest#16331)) - `[jest-config]` Add missing `findRelatedTests`, `outputFile`, and `replname` entries to `ValidConfig` so they no longer trigger spurious "Unknown option" warnings ([#16224](jestjs/jest#16224)) - `[jest-config]` Use `--config` for the global config when multiple `--projects` are specified ([#16273](jestjs/jest#16273)) - `[jest-core]` Serialize `bigint` values in `--json` and `--outputFile` output as their literal form (`4n`), instead of failing the run with `TypeError: Do not know how to serialize a BigInt` ([#16338](jestjs/jest#16338)) - `[jest-core]` Do not report a `CustomGC` async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is `napi_unref`'d by the addon and can never keep the event loop alive ([#16379](jestjs/jest#16379)) - `[jest-each]` Keep a `$&`, `` $` ``, `$'` or `$$` inside a `%p` param value out of the replacement, so the title shows the value instead of the text around it ([#16338](jestjs/jest#16338)) - `[jest-each]` Interpolate a `bigint` into a `%j` title as its literal form (`"4n"`) at any depth, instead of throwing `TypeError: Do not know how to serialize a BigInt` while collecting the tests ([#16338](jestjs/jest#16338)) - `[jest-environment, jest-runtime]` Bind `sandboxInjectedGlobals` to the right values when `injectGlobals` is `false`, instead of shifting every one of them by a position ([#16377](jestjs/jest#16377)) - `[jest-environment-node, jest-util]` Only warn about a conflicting `globalsCleanup` mode when one was explicitly configured, and follow the mode that is actually in effect ([#16323](jestjs/jest#16323)) - `[jest-environment-node, jest-util]` Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file ([#16324](jestjs/jest#16324)) - `[jest-haste-map]` Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on `EPERM` ([#16295](jestjs/jest#16295)) - `[jest-haste-map]` Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on `EPERM` ([#16358](jestjs/jest#16358)) - `[jest-haste-map]` Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode ([#16360](jestjs/jest#16360)) - `[jest-haste-map]` Shut the worker farm down when a duplicate manual mock aborts the build under `throwOnModuleCollision` ([#16354](jestjs/jest#16354)) - `[jest-haste-map]` Attach the watchman client's `error` listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled `error` event, and always end the client ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Stop delivering watch events after `WatchmanWatcher` is closed, and route its warnings through the configured console ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Restore the nested `duplicates` index correctly in `ModuleMap.fromJSON`, so a haste collision reported inside a test worker raises `DuplicateHasteCandidatesError` instead of a `TypeError` ([#16353](jestjs/jest#16353)) - `[jest-haste-map]` Match watched files on a full extension, so `moduleFileExtensions: ['js']` no longer accepts `foo.mjs` ([#16352](jestjs/jest#16352)) - `[jest-haste-map]` Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file ([#16352](jestjs/jest#16352)) - `[jest-message-util]` Print the inner errors of an `AggregateError` thrown inside a test ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Indent nested `cause` and `AggregateError` sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Color stack traces line by line so blank lines stay blank ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Detect Jest's own frames without assuming the checkout directory's name, and cover `@jest/*` packages, so stack traces and code frames point at user code ([#16326](jestjs/jest#16326)) - `[jest-mock]` `mockResolvedValue` / `mockRejectedValue` now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. `pg.Client['end']`) ([#16237](jestjs/jest#16237)) - `[@jest-environment/jsdom-abstract]` Make `@types/jsdom` a peer dependency ([#16166](jestjs/jest#16166)) - `[jest-mock]` Remove the leftover own accessor descriptor when restoring a `spyOn` of an inherited getter or setter, so the instance keeps reflecting the prototype ([#16226](jestjs/jest#16226)) - `[jest-resolve]` Include `extensionsToTreatAsEsm` in the `shouldLoadAsEsm` cache key, so projects with different extension lists don't read each other's answers ([#16369](jestjs/jest#16369)) - `[jest-resolve]` Make `getModuleIDAsync` build and cache `data:` URI module IDs the same way as `getModuleID` ([#16370](jestjs/jest#16370)) - `[jest-resolve]` Keep the `node:` prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (`node:sea`, `node:sqlite`, `node:test`, `node:test/reporters`) resolves instead of failing as a missing bare package ([#16388](jestjs/jest#16388)) - `[jest-resolve]` Look up manual mocks for `node:` protocol specifiers under the unprefixed name they are stored as ([#16388](jestjs/jest#16388)) - `[jest-resolve]` Apply `moduleNameMapper` consistently to both spellings of core module specifiers (`fs` vs `node:fs`) ([#16390](jestjs/jest#16390)) - `[jest-resolve]` Keep virtual and ordinary mock module IDs isolated across test files ([#16296](jestjs/jest#16296)) - `[jest-resolve]` Guard missing `require.resolve.paths` ([#16052](jestjs/jest#16052)) - `[jest-resolve, jest-config, jest-runner]` Support a user resolver written as an ES module ([#16332](jestjs/jest#16332)) - `[jest-resolve, jest-runtime]` Throw the CJS parse error for ESM syntax in a `"type": "commonjs"` package or a `.cjs` file instead of loading it as ESM, matching Node ([#16368](jestjs/jest#16368)) - `[@jest/source-map]` Keep source map sources that name a scheme, such as `webpack:///`, instead of resolving them into a path that does not exist ([#16327](jestjs/jest#16327)) - `[@jest/source-map]` Look up `--testLocationInResults` positions at the right column, and keep a mapping to the first column instead of discarding it ([#16327](jestjs/jest#16327)) - `[@jest/source-map]` Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated ([#16327](jestjs/jest#16327)) - `[jest-runner, @jest/source-map]` Keep a source-mapped stack for an error thrown after the test environment was torn down ([#16327](jestjs/jest#16327)) - `[jest-runtime, @jest/source-map]` Keep source maps past teardown and past the next test file's `install`, so a stack from a file no earlier stack mentioned still points at the original source ([#16330](jestjs/jest#16330)) - `[jest-runtime]` Report that no coverage was collected when `getAllV8CoverageInfoCopy` is called after `teardown`, instead of returning an empty result ([#16385](jestjs/jest#16385)) - `[jest-runtime]` Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM ([#16363](jestjs/jest#16363)) - `[jest-runtime]` Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so `module.exports = require('./dep.mjs')` loads instead of failing with `module is not defined` ([#16363](jestjs/jest#16363)) - `[jest-runtime]` Scope module mocks instantiated inside `jest.isolateModules`/`isolateModulesAsync` to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave ([#16365](jestjs/jest#16365)) - `[jest-runtime]` Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry ([#16365](jestjs/jest#16365)) - `[jest-runtime]` Check a cached ES module's status before `require()` returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Report the original `ERR_REQUIRE_ASYNC_MODULE` when a `require()` of a top-level-await graph is retried, instead of a spurious "concurrent `import()`" error ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Throw the evaluation error when another caller's `import()` of the same module failed while we awaited it, instead of resolving with the errored module ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Mark the result of `require()`ing an ES module that has a default export with `__esModule: true` through a live-binding facade, and serve the same object from `require.cache`, matching Node ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Provide a CommonJS module's exports under the `'module.exports'` named export when imported from ESM, matching Node 23+ ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Give the test file itself a non-null `require.main` ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Populate `module.children` with the modules a file loads, matching Node ([#16368](jestjs/jest#16368)) - `[jest-runtime]` Provide `import.meta.resolve` and `import.meta.jest` in `data:` URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid `data:` URIs ([#16368](jestjs/jest#16368)) - `[jest-runtime]` Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in `import.meta.url` ([#16375](jestjs/jest#16375)) - `[jest-runtime]` Share modules between overlapping graphs when a CommonJS module `require()`s an ES module mid-load, instead of evaluating shared dependencies twice ([#16375](jestjs/jest#16375)) - `[jest-runtime]` Throw `ERR_REQUIRE_CYCLE_MODULE` like Node when a CommonJS module `require()`s an ES module that is still being loaded, instead of evaluating the module a second time ([#16366](jestjs/jest#16366)) - `[jest-runtime]` Key builtin modules in the ESM registry by one canonical specifier ([#16341](jestjs/jest#16341)) - `[jest-runtime]` `import.meta.resolve()` for a builtin uses its `node:` specifier ([#16341](jestjs/jest#16341)) - `[jest-runtime]` Fall back to native ESM when a `.js` file contains ESM syntax but has no `"type":"module"` marker ([#16152](jestjs/jest#16152)) - `[jest-runtime]` Allow `require()` of ESM-marked files on Node < 24.9 via transform fallback ([#16244](jestjs/jest#16244)) - `[jest-runtime, @jest/transform]` Surface actionable `ERR_REQUIRE_ESM` error for files with untransformed ESM syntax instead of the generic "unexpected token" message ([#16244](jestjs/jest#16244)) - `[jest-runtime]` Support older test environments whose `moduleMocker` does not implement `clearMocksOnScope` ([#16169](jestjs/jest#16169)) - `[jest-runtime]` Apply `jest.unstable_mockModule` when the mocked file itself is `require()`d, not only when it is imported as a dependency ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Apply `jest.unstable_mockModule` to statically imported `data:` URIs on Node 24.9+, matching dynamic `import()` ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Run an async `jest.unstable_mockModule` factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Hide a `require(esm)` module that failed to evaluate from `require.cache`, as Node does, instead of exposing a namespace with uninitialized bindings ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Strip the byte-order mark when importing a JSON module, matching `require()` and Node ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Throw `ERR_REQUIRE_ASYNC_MODULE` when `require(esm)` runs under an async-only custom resolver, instead of silently resolving with the default resolver ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Parse imported JSON modules with the test realm's `JSON`, so their objects pass `instanceof Object` inside the test like `require()`d JSON does ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Accept every `file:` URL string in the sandboxed `module.createRequire`, including one with a `localhost` authority, as Node does ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Point at `{virtual: true}` when `jest.mock` or `jest.unstable_mockModule` is given a module that cannot be resolved ([#16389](jestjs/jest#16389)) - `[jest-reporters]` Fix coverage report table formatting in CI/GitHub Actions environments where `process.stdout.columns` is undefined by falling back to the `COLUMNS` env var or `80` columns in CI, preserving existing behaviour in other non-TTY environments ([#16227](jestjs/jest#16227)) - `[jest-runtime]` Support CJS-in-ESM exports via `"module.exports"` named exports ([#16277](jestjs/jest#16277)) - `[jest-snapshot]` Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete ([#16348](jestjs/jest#16348)) - `[jest-util]` Stop `globsToMatcher` reusing a cached matcher compiled with different picomatch options, and keep its `dot: true` default when `dot` is passed as `undefined` ([#16381](jestjs/jest#16381)) - `[pretty-format]` Move the `react-is` aliases into the `@jest` scope, so they cannot be shadowed by unrelated packages published under the alias names ([#16333](jestjs/jest#16333)) ##### Chore & Maintenance - `[docs]` Document the intentional divergences from Node's module system in the ECMAScript Modules page ([#16368](jestjs/jest#16368)) - `[docs]` Note deprecation of `react-test-renderer` in React Native tutorial and `pretty-format` README ([#16294](jestjs/jest#16294)) - `[docs]` Use `@testing-library/react-native` in the React Native tutorial instead of the deprecated `react-test-renderer` ([#16318](jestjs/jest#16318)) - `[babel-jest, @jest/transform]` Update `babel-plugin-istanbul` to v8 ([#16049](jestjs/jest#16049)) - `[jest-config, @jest/reporters, jest-runtime]` Update `glob` to v13 ([#16397](jestjs/jest#16397)) - `[jest-haste-map]` Refactor massive class into multiple files ([#16180](jestjs/jest#16180)) - `[jest-haste-map]` Drop `walker` dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with `fdir` ([#16187](jestjs/jest#16187)) - `[jest-haste-map]` Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup ([#16351](jestjs/jest#16351)) - `[jest-haste-map]` Cache the watchman socket path and replace the `watchman --version` probe with `get-sockname`, so warm runs spawn no watchman processes ([#16386](jestjs/jest#16386)) - `[jest-resolve]` Store the per-directory package-type lookup in the cache it reads, so it actually memoizes ([#16369](jestjs/jest#16369)) - `[jest-resolve, jest-runtime]` Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize `isCoreModule` and the options cache-key serialization, skip mapper preparation when no `moduleNameMapper` is configured, run each mapper regex once, and stop re-parsing `NODE_OPTIONS` on every default-resolver call ([#16371](jestjs/jest#16371)) - `[jest-resolve]` Cut warm resolution cost to about a third: reuse one `unrs-resolver` factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an `Error` for misses that `findNodeModule` swallows; add a `__benchmarks__` suite for the default resolver ([#16373](jestjs/jest#16373)) - `[jest-runner, @jest/source-map]` Replace `source-map-support` with an implementation in `@jest/source-map` ([#16327](jestjs/jest#16327)) - `[jest-snapshot]` Load babel, semver and synckit lazily, so requiring the package (which every test process does through `@jest/expect`) no longer loads \~200 modules that only writing inline snapshots needs ([#16387](jestjs/jest#16387)) - `[jest-runtime]` Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one `require.cache` proxy across modules, and cache empty files ([#16376](jestjs/jest#16376)) - `[@jest/source-map]` Deprecate `getCallsite` in favour of `SourceMapSupport#getCallsite` ([#16327](jestjs/jest#16327)) - `[jest-runtime]` Avoid magical `null` value in ESM loader ([#16160](jestjs/jest#16160))
| datasource | package | from | to | | ---------- | ------- | ------ | ------ | | npm | jest | 30.4.2 | 30.5.1 | ## [v30.5.1](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3051) ##### Fixes - `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](jestjs/jest#16411)) - `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](jestjs/jest#16411)) - `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](jestjs/jest#16411)) - `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](jestjs/jest#16390)) ([#16417](jestjs/jest#16417)) - `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](jestjs/jest#16413)) ##### Chore & Maintenance - `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](jestjs/jest#16404)) ## [v30.5.0](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3050) ##### Features - `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](jestjs/jest#16053)) - `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](jestjs/jest#16053)) - `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](jestjs/jest#16259)) - `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](jestjs/jest#16322)) - `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](jestjs/jest#16316)) - `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](jestjs/jest#16188)) - `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](jestjs/jest#15721)) - `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](jestjs/jest#16260)) - `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](jestjs/jest#16336)) - `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](jestjs/jest#16374)) ##### Fixes - `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](jestjs/jest#16155)) - `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](jestjs/jest#16167)) - `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](jestjs/jest#16196)) - `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](jestjs/jest#16347)) - `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](jestjs/jest#16347)) - `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](jestjs/jest#16342)) - `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](jestjs/jest#16343)) - `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](jestjs/jest#16347)) - `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](jestjs/jest#16344)) - `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](jestjs/jest#16331)) - `[@jest/create-cache-key-function]` Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached ([#16331](jestjs/jest#16331)) - `[@jest/transform]` Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other ([#16331](jestjs/jest#16331)) - `[jest-config]` Add missing `findRelatedTests`, `outputFile`, and `replname` entries to `ValidConfig` so they no longer trigger spurious "Unknown option" warnings ([#16224](jestjs/jest#16224)) - `[jest-config]` Use `--config` for the global config when multiple `--projects` are specified ([#16273](jestjs/jest#16273)) - `[jest-core]` Serialize `bigint` values in `--json` and `--outputFile` output as their literal form (`4n`), instead of failing the run with `TypeError: Do not know how to serialize a BigInt` ([#16338](jestjs/jest#16338)) - `[jest-core]` Do not report a `CustomGC` async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is `napi_unref`'d by the addon and can never keep the event loop alive ([#16379](jestjs/jest#16379)) - `[jest-each]` Keep a `$&`, `` $` ``, `$'` or `$$` inside a `%p` param value out of the replacement, so the title shows the value instead of the text around it ([#16338](jestjs/jest#16338)) - `[jest-each]` Interpolate a `bigint` into a `%j` title as its literal form (`"4n"`) at any depth, instead of throwing `TypeError: Do not know how to serialize a BigInt` while collecting the tests ([#16338](jestjs/jest#16338)) - `[jest-environment, jest-runtime]` Bind `sandboxInjectedGlobals` to the right values when `injectGlobals` is `false`, instead of shifting every one of them by a position ([#16377](jestjs/jest#16377)) - `[jest-environment-node, jest-util]` Only warn about a conflicting `globalsCleanup` mode when one was explicitly configured, and follow the mode that is actually in effect ([#16323](jestjs/jest#16323)) - `[jest-environment-node, jest-util]` Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file ([#16324](jestjs/jest#16324)) - `[jest-haste-map]` Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on `EPERM` ([#16295](jestjs/jest#16295)) - `[jest-haste-map]` Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on `EPERM` ([#16358](jestjs/jest#16358)) - `[jest-haste-map]` Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode ([#16360](jestjs/jest#16360)) - `[jest-haste-map]` Shut the worker farm down when a duplicate manual mock aborts the build under `throwOnModuleCollision` ([#16354](jestjs/jest#16354)) - `[jest-haste-map]` Attach the watchman client's `error` listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled `error` event, and always end the client ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Stop delivering watch events after `WatchmanWatcher` is closed, and route its warnings through the configured console ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Restore the nested `duplicates` index correctly in `ModuleMap.fromJSON`, so a haste collision reported inside a test worker raises `DuplicateHasteCandidatesError` instead of a `TypeError` ([#16353](jestjs/jest#16353)) - `[jest-haste-map]` Match watched files on a full extension, so `moduleFileExtensions: ['js']` no longer accepts `foo.mjs` ([#16352](jestjs/jest#16352)) - `[jest-haste-map]` Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file ([#16352](jestjs/jest#16352)) - `[jest-message-util]` Print the inner errors of an `AggregateError` thrown inside a test ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Indent nested `cause` and `AggregateError` sections of a test failure by one level per depth, so the nesting is legible instead of rendering flat ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Color stack traces line by line so blank lines stay blank ([#16316](jestjs/jest#16316)) - `[jest-message-util]` Detect Jest's own frames without assuming the checkout directory's name, and cover `@jest/*` packages, so stack traces and code frames point at user code ([#16326](jestjs/jest#16326)) - `[jest-mock]` `mockResolvedValue` / `mockRejectedValue` now see all overload return types, so a Promise-returning overload survives even when a later overload returns a non-Promise (e.g. `pg.Client['end']`) ([#16237](jestjs/jest#16237)) - `[@jest-environment/jsdom-abstract]` Make `@types/jsdom` a peer dependency ([#16166](jestjs/jest#16166)) - `[jest-mock]` Remove the leftover own accessor descriptor when restoring a `spyOn` of an inherited getter or setter, so the instance keeps reflecting the prototype ([#16226](jestjs/jest#16226)) - `[jest-resolve]` Include `extensionsToTreatAsEsm` in the `shouldLoadAsEsm` cache key, so projects with different extension lists don't read each other's answers ([#16369](jestjs/jest#16369)) - `[jest-resolve]` Make `getModuleIDAsync` build and cache `data:` URI module IDs the same way as `getModuleID` ([#16370](jestjs/jest#16370)) - `[jest-resolve]` Keep the `node:` prefix when resolving a core module asynchronously, so a builtin that only exists prefixed (`node:sea`, `node:sqlite`, `node:test`, `node:test/reporters`) resolves instead of failing as a missing bare package ([#16388](jestjs/jest#16388)) - `[jest-resolve]` Look up manual mocks for `node:` protocol specifiers under the unprefixed name they are stored as ([#16388](jestjs/jest#16388)) - `[jest-resolve]` Apply `moduleNameMapper` consistently to both spellings of core module specifiers (`fs` vs `node:fs`) ([#16390](jestjs/jest#16390)) - `[jest-resolve]` Keep virtual and ordinary mock module IDs isolated across test files ([#16296](jestjs/jest#16296)) - `[jest-resolve]` Guard missing `require.resolve.paths` ([#16052](jestjs/jest#16052)) - `[jest-resolve, jest-config, jest-runner]` Support a user resolver written as an ES module ([#16332](jestjs/jest#16332)) - `[jest-resolve, jest-runtime]` Throw the CJS parse error for ESM syntax in a `"type": "commonjs"` package or a `.cjs` file instead of loading it as ESM, matching Node ([#16368](jestjs/jest#16368)) - `[@jest/source-map]` Keep source map sources that name a scheme, such as `webpack:///`, instead of resolving them into a path that does not exist ([#16327](jestjs/jest#16327)) - `[@jest/source-map]` Look up `--testLocationInResults` positions at the right column, and keep a mapping to the first column instead of discarding it ([#16327](jestjs/jest#16327)) - `[@jest/source-map]` Warn when a source map cannot be parsed, instead of silently leaving its frames untranslated ([#16327](jestjs/jest#16327)) - `[jest-runner, @jest/source-map]` Keep a source-mapped stack for an error thrown after the test environment was torn down ([#16327](jestjs/jest#16327)) - `[jest-runtime, @jest/source-map]` Keep source maps past teardown and past the next test file's `install`, so a stack from a file no earlier stack mentioned still points at the original source ([#16330](jestjs/jest#16330)) - `[jest-runtime]` Report that no coverage was collected when `getAllV8CoverageInfoCopy` is called after `teardown`, instead of returning an empty result ([#16385](jestjs/jest#16385)) - `[jest-runtime]` Cache a CJS module's parsed exports before walking its re-exports, so two modules that re-export each other no longer overflow the stack when imported from ESM ([#16363](jestjs/jest#16363)) - `[jest-runtime]` Keep a re-exported ES module's parse failure from marking the re-exporting CommonJS file as ESM, so `module.exports = require('./dep.mjs')` loads instead of failing with `module is not defined` ([#16363](jestjs/jest#16363)) - `[jest-runtime]` Scope module mocks instantiated inside `jest.isolateModules`/`isolateModulesAsync` to that block, so a mock first imported there no longer outlives it - matching how CommonJS mocks already behave ([#16365](jestjs/jest#16365)) - `[jest-runtime]` Suspend module isolation while generating an automock, so loading the real module to read its shape no longer populates the isolated registry ([#16365](jestjs/jest#16365)) - `[jest-runtime]` Check a cached ES module's status before `require()` returns it, so a module whose evaluation threw rethrows that error and one left linked by a failed sibling is evaluated instead of returning uninitialized bindings ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Report the original `ERR_REQUIRE_ASYNC_MODULE` when a `require()` of a top-level-await graph is retried, instead of a spurious "concurrent `import()`" error ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Throw the evaluation error when another caller's `import()` of the same module failed while we awaited it, instead of resolving with the errored module ([#16364](jestjs/jest#16364)) - `[jest-runtime]` Mark the result of `require()`ing an ES module that has a default export with `__esModule: true` through a live-binding facade, and serve the same object from `require.cache`, matching Node ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Provide a CommonJS module's exports under the `'module.exports'` named export when imported from ESM, matching Node 23+ ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Give the test file itself a non-null `require.main` ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Populate `module.children` with the modules a file loads, matching Node ([#16368](jestjs/jest#16368)) - `[jest-runtime]` Provide `import.meta.resolve` and `import.meta.jest` in `data:` URI modules, accept any-case mediatype parameters, and use Node's error codes for invalid `data:` URIs ([#16368](jestjs/jest#16368)) - `[jest-runtime]` Key ES modules by full URL, so query and fragment suffixes create the same module instances as Node and show up in `import.meta.url` ([#16375](jestjs/jest#16375)) - `[jest-runtime]` Share modules between overlapping graphs when a CommonJS module `require()`s an ES module mid-load, instead of evaluating shared dependencies twice ([#16375](jestjs/jest#16375)) - `[jest-runtime]` Throw `ERR_REQUIRE_CYCLE_MODULE` like Node when a CommonJS module `require()`s an ES module that is still being loaded, instead of evaluating the module a second time ([#16366](jestjs/jest#16366)) - `[jest-runtime]` Key builtin modules in the ESM registry by one canonical specifier ([#16341](jestjs/jest#16341)) - `[jest-runtime]` `import.meta.resolve()` for a builtin uses its `node:` specifier ([#16341](jestjs/jest#16341)) - `[jest-runtime]` Fall back to native ESM when a `.js` file contains ESM syntax but has no `"type":"module"` marker ([#16152](jestjs/jest#16152)) - `[jest-runtime]` Allow `require()` of ESM-marked files on Node < 24.9 via transform fallback ([#16244](jestjs/jest#16244)) - `[jest-runtime, @jest/transform]` Surface actionable `ERR_REQUIRE_ESM` error for files with untransformed ESM syntax instead of the generic "unexpected token" message ([#16244](jestjs/jest#16244)) - `[jest-runtime]` Support older test environments whose `moduleMocker` does not implement `clearMocksOnScope` ([#16169](jestjs/jest#16169)) - `[jest-runtime]` Apply `jest.unstable_mockModule` when the mocked file itself is `require()`d, not only when it is imported as a dependency ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Apply `jest.unstable_mockModule` to statically imported `data:` URIs on Node 24.9+, matching dynamic `import()` ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Run an async `jest.unstable_mockModule` factory once per module instead of twice, and fail the import instead of crashing the worker when the factory rejects ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Hide a `require(esm)` module that failed to evaluate from `require.cache`, as Node does, instead of exposing a namespace with uninitialized bindings ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Strip the byte-order mark when importing a JSON module, matching `require()` and Node ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Throw `ERR_REQUIRE_ASYNC_MODULE` when `require(esm)` runs under an async-only custom resolver, instead of silently resolving with the default resolver ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Parse imported JSON modules with the test realm's `JSON`, so their objects pass `instanceof Object` inside the test like `require()`d JSON does ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Accept every `file:` URL string in the sandboxed `module.createRequire`, including one with a `localhost` authority, as Node does ([#16389](jestjs/jest#16389)) - `[jest-runtime]` Point at `{virtual: true}` when `jest.mock` or `jest.unstable_mockModule` is given a module that cannot be resolved ([#16389](jestjs/jest#16389)) - `[jest-reporters]` Fix coverage report table formatting in CI/GitHub Actions environments where `process.stdout.columns` is undefined by falling back to the `COLUMNS` env var or `80` columns in CI, preserving existing behaviour in other non-TTY environments ([#16227](jestjs/jest#16227)) - `[jest-runtime]` Support CJS-in-ESM exports via `"module.exports"` named exports ([#16277](jestjs/jest#16277)) - `[jest-snapshot]` Keep a skipped or failed test's hinted snapshots, instead of reporting them obsolete ([#16348](jestjs/jest#16348)) - `[jest-util]` Stop `globsToMatcher` reusing a cached matcher compiled with different picomatch options, and keep its `dot: true` default when `dot` is passed as `undefined` ([#16381](jestjs/jest#16381)) - `[pretty-format]` Move the `react-is` aliases into the `@jest` scope, so they cannot be shadowed by unrelated packages published under the alias names ([#16333](jestjs/jest#16333)) ##### Chore & Maintenance - `[docs]` Document the intentional divergences from Node's module system in the ECMAScript Modules page ([#16368](jestjs/jest#16368)) - `[docs]` Note deprecation of `react-test-renderer` in React Native tutorial and `pretty-format` README ([#16294](jestjs/jest#16294)) - `[docs]` Use `@testing-library/react-native` in the React Native tutorial instead of the deprecated `react-test-renderer` ([#16318](jestjs/jest#16318)) - `[babel-jest, @jest/transform]` Update `babel-plugin-istanbul` to v8 ([#16049](jestjs/jest#16049)) - `[jest-config, @jest/reporters, jest-runtime]` Update `glob` to v13 ([#16397](jestjs/jest#16397)) - `[jest-haste-map]` Refactor massive class into multiple files ([#16180](jestjs/jest#16180)) - `[jest-haste-map]` Drop `walker` dependency; replace hand-rolled directory recursion in the JS crawler and watcher startup with `fdir` ([#16187](jestjs/jest#16187)) - `[jest-haste-map]` Reuse cached metadata for files whose haste name is a known duplicate, instead of re-reading and re-parsing them on every startup ([#16351](jestjs/jest#16351)) - `[jest-haste-map]` Cache the watchman socket path and replace the `watchman --version` probe with `get-sockname`, so warm runs spawn no watchman processes ([#16386](jestjs/jest#16386)) - `[jest-resolve]` Store the per-directory package-type lookup in the cache it reads, so it actually memoizes ([#16369](jestjs/jest#16369)) - `[jest-resolve, jest-runtime]` Cut repeated work on the resolution hot path: hoist the platform-extension list to construction, memoize `isCoreModule` and the options cache-key serialization, skip mapper preparation when no `moduleNameMapper` is configured, run each mapper regex once, and stop re-parsing `NODE_OPTIONS` on every default-resolver call ([#16371](jestjs/jest#16371)) - `[jest-resolve]` Cut warm resolution cost to about a third: reuse one `unrs-resolver` factory per options shape instead of cloning per resolution, compose the factory cache key from per-array cached strings instead of serializing options, and stop constructing an `Error` for misses that `findNodeModule` swallows; add a `__benchmarks__` suite for the default resolver ([#16373](jestjs/jest#16373)) - `[jest-runner, @jest/source-map]` Replace `source-map-support` with an implementation in `@jest/source-map` ([#16327](jestjs/jest#16327)) - `[jest-snapshot]` Load babel, semver and synckit lazily, so requiring the package (which every test process does through `@jest/expect`) no longer loads \~200 modules that only writing inline snapshots needs ([#16387](jestjs/jest#16387)) - `[jest-runtime]` Reduce per-require overhead: skip module ID resolution when no mock can apply, answer core modules before probing for a manual mock, share one `require.cache` proxy across modules, and cache empty files ([#16376](jestjs/jest#16376)) - `[@jest/source-map]` Deprecate `getCallsite` in favour of `SourceMapSupport#getCallsite` ([#16327](jestjs/jest#16327)) - `[jest-runtime]` Avoid magical `null` value in ESM loader ([#16160](jestjs/jest#16160))
…ip ci] Bumps [babel-jest](https://github.com/jestjs/jest/tree/HEAD/packages/babel-jest) from 30.4.1 to 30.5.1. Release notes *Sourced from [babel-jest's releases](https://github.com/jestjs/jest/releases).* > v30.5.1 > ------- > > Fixes > ----- > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > Chore & Maintenance > ------------------- > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > New Contributors > ---------------- > > * [`@HuzaifaChaudary`](https://github.com/HuzaifaChaudary) made their first contribution in [jestjs/jest#16413](https://redirect.github.com/jestjs/jest/pull/16413) > > **Full Changelog**: <jestjs/jest@v30.5.0...v30.5.1> > > v30.5.0 > ------- > > On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴 > > --- > > This is a big release. It touches `jest-runtime`, `jest-resolve` and `jest-haste-map` in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please [open an issue](https://github.com/jestjs/jest/issues). > > Highlights > ========== > > `whenCalledWith` > ---------------- > > Mock functions can now configure return values per argument list, contributed by [`@timkindberg`](https://github.com/timkindberg) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)): > > ``` > const fn = jest.fn(); > fn.whenCalledWith('apple').mockReturnValue('red'); > fn.whenCalledWith('banana').mockReturnValue('yellow'); > fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric'); > > fn('apple'); // 'red' > fn('banana'); // 'yellow' > fn(42); // 'numeric' > fn('grape'); // undefined > ``` > > The returned object is a real `Mock`, so `mockReturnValueOnce`, `mockResolvedValue`, `mockImplementation` etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as `toHaveBeenCalledWith()`. Calls that match nothing fall through to the base mock. See the [Mock Functions docs](https://jestjs.io/docs/mock-function-api#mockfnwhencalledwithargs) for matching and precedence details. > > Describe-level retries > ---------------------- > > `jest.retryTimes()` can now retry a whole `describe` block instead of a single test, contributed by [`@soltonigiri`](https://github.com/soltonigiri) ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)). Each attempt reruns the block's `beforeAll`/`afterAll` hooks, child tests and nested describes, which helps when tests in a block depend on shared state: > > ``` > </tr></table> > ``` ... (truncated) Changelog *Sourced from [babel-jest's changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md).* > 30.5.1 > ------ > > ### Fixes > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > ### Chore & Maintenance > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > 30.5.0 > ------ > > ### Features > > * `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](https://redirect.github.com/jestjs/jest/pull/16259)) > * `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)) > * `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](https://redirect.github.com/jestjs/jest/pull/16188)) > * `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](https://redirect.github.com/jestjs/jest/pull/15721)) > * `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](https://redirect.github.com/jestjs/jest/pull/16260)) > * `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](https://redirect.github.com/jestjs/jest/pull/16367)) > * `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](https://redirect.github.com/jestjs/jest/pull/16336)) > * `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](https://redirect.github.com/jestjs/jest/pull/16374)) > > ### Fixes > > * `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](https://redirect.github.com/jestjs/jest/pull/16155)) > * `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](https://redirect.github.com/jestjs/jest/pull/16167)) > * `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](https://redirect.github.com/jestjs/jest/pull/16196)) > * `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](https://redirect.github.com/jestjs/jest/pull/16342)) > * `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](https://redirect.github.com/jestjs/jest/pull/16343)) > * `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](https://redirect.github.com/jestjs/jest/pull/16344)) > * `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](https://redirect.github.com/jestjs/jest/pull/16331)) ... (truncated) Commits * [`9ab14fe`](jestjs/jest@9ab14fe) v30.5.1 * [`912baa3`](jestjs/jest@912baa3) v30.5.0 * [`8e6d128`](jestjs/jest@8e6d128) Update istanbul dependencies ([#16049](https://github.com/jestjs/jest/tree/HEAD/packages/babel-jest/issues/16049)) * [`1865dd8`](jestjs/jest@1865dd8) chore: update yarn & refresh lockfiles ([#16251](https://github.com/jestjs/jest/tree/HEAD/packages/babel-jest/issues/16251)) * [`ff542da`](jestjs/jest@ff542da) chore(deps): update babel monorepo to v8.0.0-rc.5 ([#16172](https://github.com/jestjs/jest/tree/HEAD/packages/babel-jest/issues/16172)) * [`b91717a`](jestjs/jest@b91717a) chore: refresh coding agent instructions ([#16182](https://github.com/jestjs/jest/tree/HEAD/packages/babel-jest/issues/16182)) * See full diff in [compare view](https://github.com/jestjs/jest/commits/v30.5.1/packages/babel-jest) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
… /webapp [skip ci] Bumps [jest-environment-jsdom](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom) from 30.4.1 to 30.5.1. Release notes *Sourced from [jest-environment-jsdom's releases](https://github.com/jestjs/jest/releases).* > v30.5.1 > ------- > > Fixes > ----- > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > Chore & Maintenance > ------------------- > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > New Contributors > ---------------- > > * [`@HuzaifaChaudary`](https://github.com/HuzaifaChaudary) made their first contribution in [jestjs/jest#16413](https://redirect.github.com/jestjs/jest/pull/16413) > > **Full Changelog**: <jestjs/jest@v30.5.0...v30.5.1> > > v30.5.0 > ------- > > On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴 > > --- > > This is a big release. It touches `jest-runtime`, `jest-resolve` and `jest-haste-map` in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please [open an issue](https://github.com/jestjs/jest/issues). > > Highlights > ========== > > `whenCalledWith` > ---------------- > > Mock functions can now configure return values per argument list, contributed by [`@timkindberg`](https://github.com/timkindberg) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)): > > ``` > const fn = jest.fn(); > fn.whenCalledWith('apple').mockReturnValue('red'); > fn.whenCalledWith('banana').mockReturnValue('yellow'); > fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric'); > > fn('apple'); // 'red' > fn('banana'); // 'yellow' > fn(42); // 'numeric' > fn('grape'); // undefined > ``` > > The returned object is a real `Mock`, so `mockReturnValueOnce`, `mockResolvedValue`, `mockImplementation` etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as `toHaveBeenCalledWith()`. Calls that match nothing fall through to the base mock. See the [Mock Functions docs](https://jestjs.io/docs/mock-function-api#mockfnwhencalledwithargs) for matching and precedence details. > > Describe-level retries > ---------------------- > > `jest.retryTimes()` can now retry a whole `describe` block instead of a single test, contributed by [`@soltonigiri`](https://github.com/soltonigiri) ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)). Each attempt reruns the block's `beforeAll`/`afterAll` hooks, child tests and nested describes, which helps when tests in a block depend on shared state: > > ``` > </tr></table> > ``` ... (truncated) Changelog *Sourced from [jest-environment-jsdom's changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md).* > 30.5.1 > ------ > > ### Fixes > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > ### Chore & Maintenance > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > 30.5.0 > ------ > > ### Features > > * `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](https://redirect.github.com/jestjs/jest/pull/16259)) > * `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)) > * `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](https://redirect.github.com/jestjs/jest/pull/16188)) > * `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](https://redirect.github.com/jestjs/jest/pull/15721)) > * `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](https://redirect.github.com/jestjs/jest/pull/16260)) > * `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](https://redirect.github.com/jestjs/jest/pull/16367)) > * `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](https://redirect.github.com/jestjs/jest/pull/16336)) > * `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](https://redirect.github.com/jestjs/jest/pull/16374)) > > ### Fixes > > * `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](https://redirect.github.com/jestjs/jest/pull/16155)) > * `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](https://redirect.github.com/jestjs/jest/pull/16167)) > * `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](https://redirect.github.com/jestjs/jest/pull/16196)) > * `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](https://redirect.github.com/jestjs/jest/pull/16342)) > * `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](https://redirect.github.com/jestjs/jest/pull/16343)) > * `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](https://redirect.github.com/jestjs/jest/pull/16344)) > * `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](https://redirect.github.com/jestjs/jest/pull/16331)) ... (truncated) Commits * [`9ab14fe`](jestjs/jest@9ab14fe) v30.5.1 * [`912baa3`](jestjs/jest@912baa3) v30.5.0 * [`b91717a`](jestjs/jest@b91717a) chore: refresh coding agent instructions ([#16182](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom/issues/16182)) * [`3955d24`](jestjs/jest@3955d24) Make `@types/jsdom` a peer dependency of jest-environment-jsdom-abstract ([#16166](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom/issues/16166)) * See full diff in [compare view](https://github.com/jestjs/jest/commits/v30.5.1/packages/jest-environment-jsdom)
Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 30.4.2 to 30.5.1. Release notes *Sourced from [jest's releases](https://github.com/jestjs/jest/releases).* > v30.5.1 > ------- > > Fixes > ----- > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > Chore & Maintenance > ------------------- > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > New Contributors > ---------------- > > * [`@HuzaifaChaudary`](https://github.com/HuzaifaChaudary) made their first contribution in [jestjs/jest#16413](https://redirect.github.com/jestjs/jest/pull/16413) > > **Full Changelog**: <jestjs/jest@v30.5.0...v30.5.1> > > v30.5.0 > ------- > > On a personal note: King Harald V of Norway passed away this morning. He ascended the throne 35 years ago, two months before I was born. This release is dedicated to his memory. Hvil i fred 🇳🇴 > > --- > > This is a big release. It touches `jest-runtime`, `jest-resolve` and `jest-haste-map` in many places, and with this many changes there might be regressions 😬. If your suite behaves differently after upgrading, please [open an issue](https://github.com/jestjs/jest/issues). > > Highlights > ========== > > `whenCalledWith` > ---------------- > > Mock functions can now configure return values per argument list, contributed by [`@timkindberg`](https://github.com/timkindberg) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)): > > ``` > const fn = jest.fn(); > fn.whenCalledWith('apple').mockReturnValue('red'); > fn.whenCalledWith('banana').mockReturnValue('yellow'); > fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric'); > > fn('apple'); // 'red' > fn('banana'); // 'yellow' > fn(42); // 'numeric' > fn('grape'); // undefined > ``` > > The returned object is a real `Mock`, so `mockReturnValueOnce`, `mockResolvedValue`, `mockImplementation` etc. all chain here too. Argument slots accept literals or any asymmetric matcher, with the same equality semantics as `toHaveBeenCalledWith()`. Calls that match nothing fall through to the base mock. See the [Mock Functions docs](https://jestjs.io/docs/mock-function-api#mockfnwhencalledwithargs) for matching and precedence details. > > Describe-level retries > ---------------------- > > `jest.retryTimes()` can now retry a whole `describe` block instead of a single test, contributed by [`@soltonigiri`](https://github.com/soltonigiri) ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)). Each attempt reruns the block's `beforeAll`/`afterAll` hooks, child tests and nested describes, which helps when tests in a block depend on shared state: > > ``` > </tr></table> > ``` ... (truncated) Changelog *Sourced from [jest's changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md).* > 30.5.1 > ------ > > ### Fixes > > * `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](https://redirect.github.com/jestjs/jest/pull/16411)) > * `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](https://redirect.github.com/jestjs/jest/pull/16390)) ([#16417](https://redirect.github.com/jestjs/jest/pull/16417)) > * `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](https://redirect.github.com/jestjs/jest/pull/16413)) > > ### Chore & Maintenance > > * `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](https://redirect.github.com/jestjs/jest/pull/16404)) > > 30.5.0 > ------ > > ### Features > > * `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](https://redirect.github.com/jestjs/jest/pull/16053)) > * `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](https://redirect.github.com/jestjs/jest/pull/16259)) > * `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](https://redirect.github.com/jestjs/jest/pull/16322)) > * `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](https://redirect.github.com/jestjs/jest/pull/16188)) > * `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](https://redirect.github.com/jestjs/jest/pull/15721)) > * `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](https://redirect.github.com/jestjs/jest/pull/16260)) > * `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](https://redirect.github.com/jestjs/jest/pull/16391)) > * `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](https://redirect.github.com/jestjs/jest/pull/16367)) > * `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](https://redirect.github.com/jestjs/jest/pull/16336)) > * `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](https://redirect.github.com/jestjs/jest/pull/16374)) > > ### Fixes > > * `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](https://redirect.github.com/jestjs/jest/pull/16155)) > * `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](https://redirect.github.com/jestjs/jest/pull/16167)) > * `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](https://redirect.github.com/jestjs/jest/pull/16196)) > * `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](https://redirect.github.com/jestjs/jest/pull/16342)) > * `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](https://redirect.github.com/jestjs/jest/pull/16343)) > * `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](https://redirect.github.com/jestjs/jest/pull/16347)) > * `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](https://redirect.github.com/jestjs/jest/pull/16316)) > * `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](https://redirect.github.com/jestjs/jest/pull/16344)) > * `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](https://redirect.github.com/jestjs/jest/pull/16331)) ... (truncated) Commits * [`9ab14fe`](jestjs/jest@9ab14fe) v30.5.1 * [`912baa3`](jestjs/jest@912baa3) v30.5.0 * [`b91717a`](jestjs/jest@b91717a) chore: refresh coding agent instructions ([#16182](https://github.com/jestjs/jest/tree/HEAD/packages/jest/issues/16182)) * See full diff in [compare view](https://github.com/jestjs/jest/commits/v30.5.1/packages/jest)
| datasource | package | from | to | | ---------- | ---------------------- | ------ | ------ | | npm | jest | 30.4.2 | 30.5.1 | | npm | jest-environment-jsdom | 30.4.1 | 30.5.1 | ## [v30.5.1](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3051) ##### Fixes - `[jest-config]` Don't warn about global-only options in the config that supplies the global config - the root config a project resolves to, or the first entry of `--projects` when no root config is passed ([#16411](jestjs/jest#16411)) - `[jest-config, jest-types]` Stop accepting `reporters`, `coverageReporters`, `workerIdleMemoryLimit`, `cwd` and `runnerOptions` in a project config - they were silently ignored, and now warn like the other global-only options ([#16411](jestjs/jest#16411)) - `[jest-config, jest-validate]` Warn about `maxWorkers` and `coverageThreshold` in a project config instead of dropping them without a word ([#16411](jestjs/jest#16411)) - `[jest-resolve]` Match `moduleNameMapper` patterns against the specifier as written again (reverting [#16390](jestjs/jest#16390)) ([#16417](jestjs/jest#16417)) - `[jest-runtime]` Resolve package `imports` specifiers like `#dep` under ESM again ([#16413](jestjs/jest#16413)) ##### Chore & Maintenance - `[jest-util]` Name the `testEnvironmentOptions.globalsCleanup` option and link the docs from the `JEST-01` deprecation warning, and document the option's modes ([#16404](jestjs/jest#16404)) ## [v30.5.0](https://github.com/jestjs/jest/blob/HEAD/CHANGELOG.md#3050) ##### Features - `[@jest/expect-utils, jest-mock]` Add `mockFn.whenCalledWith(...args)` for configuring return values per argument list, with first-class asymmetric-matcher support ([#16053](jestjs/jest#16053)) - `[@jest/expect-utils]` Export `AsymmetricMatcher` and `FunctionParameters` types (previously private to `expect`) ([#16053](jestjs/jest#16053)) - `[jest-circus, jest-core, jest-jasmine2, jest-test-result, jest-types]` `--collectTests` now expands `test.each`/`describe.each` cases and reports per-status counts (skipped/todo via the new `wouldRun` flag for selected tests) plus a summary line that match a real run, including under `--testNamePattern` and `.only`/`fdescribe` focus on both the circus and jasmine2 runners ([#16259](jestjs/jest#16259)) - `[jest-circus, jest-environment, jest-runtime, jest-types]` Add describe-level retries via `jest.retryTimes(..., {entireDescribe: true})` ([#16322](jestjs/jest#16322)) - `[jest-circus, jest-message-util, jest-reporters, jest-types]` Add `retryMessages` to `AssertionResult` and export `formatErrorStack`, so the retry log renders nested `cause` and `AggregateError` sections with code frames instead of serialized `[cause]:`/`[errors]:` markers ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-types]` Add `unhandledErrorsDetailed` to `Circus.RunResult`, so an unhandled rejection reports its `cause` chain and `AggregateError` entries with code frames instead of a pre-serialized stack ([#16316](jestjs/jest#16316)) - `[jest-haste-map]` Replace `NodeWatcher` and `FSEventsWatcher` with `@parcel/watcher` for the non-watchman watch path ([#16188](jestjs/jest#16188)) - `[jest-resolve]` Bump `unrs-resolver` to 1.12.1, remove `jest-pnp-resolver` and unnecessary checks ([#15721](jestjs/jest#15721)) - `[jest-resolve]` Honor Node's `--preserve-symlinks` / `NODE_PRESERVE_SYMLINKS` in the default resolver by passing `symlinks: false` to `unrs-resolver` ([#16260](jestjs/jest#16260)) - `[jest-runtime]` Apply automocking and manual `__mocks__` files to synchronously evaluable ESM graphs on Node 24.9+ - static imports, dynamic `import()` and `require()` of an ESM file now generate an automock from the real module's namespace instead of failing with "Attempting to import a mock without a factory". Graphs that need async evaluation (top-level await) or an async-only resolver or transformer still throw ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Route `process.getBuiltinModule` through the sandbox, so it returns the sandbox `process` and the hooked `node:module` instead of the host's ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw an actionable error from `module.register()` and `module.registerHooks()` inside a test - the hooks attached to the loader running Jest itself, never saw the sandboxed requires they were meant for, and stayed registered for every later test file in the worker ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Surface resolution and import-attribute errors in an ESM graph before executing any of its CJS dependencies on Node 24.9+, matching Node's run-nothing-on-a-broken-graph behavior; the legacy loader on older versions keeps its linking-time execution order ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Throw `ERR_SOURCE_PHASE_NOT_DEFINED` with an actionable message for `import source` and `import.source()`, instead of failing at instantiation with V8's bare "Source phase import object is not defined" ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Emit the JSON-without-import-attribute deprecation warning once per test file instead of once per worker, so it is no longer silently swallowed for every file after the first ([#16391](jestjs/jest#16391)) - `[jest-runtime]` Set `import.meta.main` to `true` in the test file and `false` in every module it loads, matching Node 24+ ([#16367](jestjs/jest#16367)) - `[jest-runtime]` Resolve the `module-sync` export condition, so a package that exposes its ESM entry point for `require()` loads the same file Node would ([#16336](jestjs/jest#16336)) - `[jest-snapshot]` Add external snapshot paths to custom reporter failure details ([#16374](jestjs/jest#16374)) ##### Fixes - `[jest-console, jest-reporters]` `CustomConsole` now buffers console output so `TestResult.console` is populated for reporters when `verbose` is enabled, while `GitHubActionsReporter` avoids replaying buffered output in verbose mode ([#16155](jestjs/jest#16155)) - `[expect, jest-message-util, jest-pattern, jest-regex-util, jest-util]` Revert `node:` protocol imports to restore webpack/browser-bundle compatibility ([#16167](jestjs/jest#16167)) - `[expect]` Widen `toMatchObject` and `objectContaining` parameter type from `Record<string, unknown>` to `object` so class instances are accepted ([#16196](jestjs/jest#16196)) - `[jest-circus]` Call a generator test body with the shared test context, so `this` matches what a regular test function receives ([#16347](jestjs/jest#16347)) - `[jest-circus]` Capture the error listeners of the parent process instead of the in-sandbox `process`, so listeners registered before the test file survive teardown and sandbox listeners no longer leak onto the parent ([#16347](jestjs/jest#16347)) - `[jest-circus]` Clear `currentlyRunningTest` after skipped and todo tests ([#16342](jestjs/jest#16342)) - `[jest-circus]` Prevent late `done()` callbacks from affecting later test or hook invocations ([#16343](jestjs/jest#16343)) - `[jest-circus, jest-jasmine2]` Honor `--expand` when formatting `node:assert` failures, instead of always collapsing the diff ([#16347](jestjs/jest#16347)) - `[jest-circus, jest-jasmine2, jest-message-util]` Serialize the inner errors of an `AggregateError` into `failureMessages`, `retryReasons` and `unhandledErrors`, so `--json` output and reporter annotations include them ([#16316](jestjs/jest#16316)) - `[jest-circus, jest-snapshot]` Keep snapshot state and counts correct when a test retries ([#16344](jestjs/jest#16344)) - `[@jest/create-cache-key-function]` Include the caller support flags in the generated key, so a transformer that emits ESM or CJS based on them no longer shares one cache entry between the two ([#16331](jestjs/jest#16331)) - `[@jest/create-cache-key-function]` Include the stringified project config in the generated key, so editing a transformer's own settings invalidates what it cached ([#16331](jestjs/jest#16331)) - `[@jest/transform]` Include the caller support flags in a transform's cache key, so a file transformed both as ESM and as CJS no longer serves one shape's output for the other ([#16331](jestjs/jest#16331)) - `[jest-config]` Add missing `findRelatedTests`, `outputFile`, and `replname` entries to `ValidConfig` so they no longer trigger spurious "Unknown option" warnings ([#16224](jestjs/jest#16224)) - `[jest-config]` Use `--config` for the global config when multiple `--projects` are specified ([#16273](jestjs/jest#16273)) - `[jest-core]` Serialize `bigint` values in `--json` and `--outputFile` output as their literal form (`4n`), instead of failing the run with `TypeError: Do not know how to serialize a BigInt` ([#16338](jestjs/jest#16338)) - `[jest-core]` Do not report a `CustomGC` async resource (used by N-API addons such as napi-rs for per-isolate GC bookkeeping) as an open handle, since it is `napi_unref`'d by the addon and can never keep the event loop alive ([#16379](jestjs/jest#16379)) - `[jest-each]` Keep a `$&`, `` $` ``, `$'` or `$$` inside a `%p` param value out of the replacement, so the title shows the value instead of the text around it ([#16338](jestjs/jest#16338)) - `[jest-each]` Interpolate a `bigint` into a `%j` title as its literal form (`"4n"`) at any depth, instead of throwing `TypeError: Do not know how to serialize a BigInt` while collecting the tests ([#16338](jestjs/jest#16338)) - `[jest-environment, jest-runtime]` Bind `sandboxInjectedGlobals` to the right values when `injectGlobals` is `false`, instead of shifting every one of them by a position ([#16377](jestjs/jest#16377)) - `[jest-environment-node, jest-util]` Only warn about a conflicting `globalsCleanup` mode when one was explicitly configured, and follow the mode that is actually in effect ([#16323](jestjs/jest#16323)) - `[jest-environment-node, jest-util]` Stop resolving lazy globals when setting up an environment, so Node 26's builtin module globals are no longer loaded (and no longer emit their deprecation warnings) for every test file ([#16324](jestjs/jest#16324)) - `[jest-haste-map]` Keep watch mode alive when an outside process briefly makes a file unreadable on Windows, instead of tearing the watcher down on `EPERM` ([#16295](jestjs/jest#16295)) - `[jest-haste-map]` Keep indexing when an outside process holds a file open on Windows, instead of failing the whole crawl on `EPERM` ([#16358](jestjs/jest#16358)) - `[jest-haste-map]` Keep a duplicated manual mock resolving when the file it pointed at is deleted in watch mode ([#16360](jestjs/jest#16360)) - `[jest-haste-map]` Shut the worker farm down when a duplicate manual mock aborts the build under `throwOnModuleCollision` ([#16354](jestjs/jest#16354)) - `[jest-haste-map]` Attach the watchman client's `error` listener before the first command, so a watchman failure falls back to the node crawler instead of crashing on an unhandled `error` event, and always end the client ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Stop delivering watch events after `WatchmanWatcher` is closed, and route its warnings through the configured console ([#16355](jestjs/jest#16355)) - `[jest-haste-map]` Restore the nested `duplicates` index correctly in `ModuleMap.fromJSON`, so a haste collision reported inside a test worker raises `DuplicateHasteCandidatesError` instead of a `TypeError` ([#16353](jestjs/jest#16353)) - `[jest-haste-map]` Match watched files on a full extension, so `moduleFileExtensions: ['js']` no longer accepts `foo.mjs` ([#16352](jestjs/jest#16352)) - `[jest-haste-map]` Delimit the fields that make up the haste map cache key, so two different option sets cannot hash to the same cache file ([#16352](
Summary
Fixes #16412.
Every subpath in a package's
importsfield starts with#, and on 30.5.0 none of them resolve under ESM.import { value } from '#dep'fails withThe requested module '#dep' does not provide an export named 'value'.splitQueryAndFragmentinpackages/jest-runtime/src/internals/EsmLoader.tslooks for the first#and treats it as a fragment delimiter:For
#depthat index is 0, so the specifier splits intopathOrSpecifier: ''andsuffix: '#dep'. The resolver is then handed an empty string and the specifier never reaches theimportsmap at all, which is also why a customresolverin the jest config does not see it.A leading
#is not a fragment delimiter. In Node's resolution algorithm a specifier starting with#is a package-imports specifier and goes to PACKAGE_IMPORTS_RESOLVE against the nearestpackage.json. So it passes through whole, next to the existingdata:carve-out:git log -S splitQueryAndFragmentgives one commit,30ce9da(#16375), first released in 30.5.0, so this is a regression from 30.4.2 and the change restores the earlier behaviour rather than adding anything.The reporter found the cause and the one line guard. I checked it against Node, wrote the tests, and checked the other direction.
checked against node 24 first
I wanted to know whether the whole specifier is the key or only the part before a
?, because that decides whether the suffix has to stay attached:#dep#lib/wild.mjsthrough"#lib/*"#dep?v=2ERR_PACKAGE_IMPORT_NOT_DEFINEDNode looks up the whole thing, so returning an empty suffix is right and the query must not be split off either. The wildcard form starts with
#too, so it was broken the same way and is covered.one thing I deliberately did not change
#dep?v=2is not a package-imports key in Node, but jest reaches a different error for it.unstable_importModuleends at:so the resolver matches the key and carries the query into the resolved path, and
FileCachethen tries to open a file with?v=2in its name. That is not new, it is what 30.4.2 does as well since the specifier reached the resolver whole there too, and it is unrelated to this bug. I found it while writing a test for the boundary and then dropped the test rather than pin a behaviour that is arguably its own small bug. Happy to open a separate issue if it is worth one.Test plan
Two tests in
runtime_esm_sync_graph.test.ts, one going through a module that imports both the plain and the wildcard form, one importing#imports-depdirectly as the entry specifier. Fixtures add animportsmap totest_esm_sync_graph_root/package.json.yarn jest packages/jest-runtime/src/__tests__/runtime_esm_sync_graph.test.ts:with the guard taken back out and nothing else changed:
which is the error from the issue.
The opposite direction, a
#that is a real fragment, is already covered in the same file by./stateful.mjs#frag,./url-reporter.mjs?#frag,./url-reporter.mjs?tag=1#fragand theimport.meta.resolvecase, and all of them still pass, so the guard is not swallowing fragments that should split.Also run:
yarn build:tsclean,yarn typecheck:testsexit 0, eslint clean on the changed files.yarn jest packages/jest-runtimereports 6 pre-existing failures in this environment, allENAMETOOLONGfromjest-haste-mapwriting a cache filename built out of my checkout path. Same 6 on a clean checkout with no changes, 578 tests there against 581 here, so the only difference is the 2 added tests plus the fixture module.