Merge pull request #1575 from mauriceboe/chore/jsdom-node-webstorage

chore(test): make jsdom Storage work under Node's native Web Storage …
This commit is contained in:
Konstantinos Thermos
2026-07-16 13:53:33 +02:00
committed by GitHub
+13 -2
View File
@@ -2,15 +2,22 @@
* Custom Vitest environment that extends jsdom but preserves the native
* Node.js AbortController and AbortSignal.
*
* Problem: jsdom replaces globalThis.AbortController and AbortSignal with its
* Problem 1: jsdom replaces globalThis.AbortController and AbortSignal with its
* own implementations. Node.js's undici-based fetch validates signals via
* `signal instanceof AbortSignal` against its own native class reference.
* jsdom's AbortSignal instances fail this check, causing fetch to throw:
* TypeError: RequestInit: Expected signal ("AbortSignal {}") to be an
* instance of AbortSignal.
*
* Fix: after jsdom installs its globals, restore the native AbortController
* and AbortSignal so fetch works correctly in tests.
*
* Problem 2 (Node 22+ experimental Web Storage): Node now exposes its own
* `localStorage`/`sessionStorage` globals, inert unless `--localstorage-file`
* is passed. Vitest's global-populate skips any key already present on the
* global that isn't in its own allow-list, and Storage isn't in it — so
* jsdom's working Storage never overwrites Node's inert one and every test
* throws on `localStorage.clear()`. Fix: delete Node's shadow globals before
* jsdom setup runs, so vitest copies jsdom's Storage across.
*/
import { builtinEnvironments } from 'vitest/environments';
@@ -26,6 +33,10 @@ export default {
const NativeAbortController = global.AbortController;
const NativeAbortSignal = global.AbortSignal;
// Clear Node's inert Web Storage globals so jsdom's win, not this shadow.
delete (global as { localStorage?: unknown }).localStorage;
delete (global as { sessionStorage?: unknown }).sessionStorage;
// Run standard jsdom setup (installs jsdom globals, including its own AbortController)
const env = await jsdomEnv.setup(global, options as Parameters<typeof jsdomEnv.setup>[1]);