|
18 | 18 | import '@testing-library/jest-dom/vitest'; |
19 | 19 | import indexeddb from 'fake-indexeddb'; |
20 | 20 |
|
| 21 | +// nock v14 uses @mswjs/interceptors, which calls `new Request(url, init)` internally when |
| 22 | +// intercepting a fetch. In jsdom v24+, globalThis.Request wraps undici's native Request, |
| 23 | +// whose WebIDL validator requires init.signal to be an instance of undici's own AbortSignal. |
| 24 | +// jsdom installs its own AbortController (via vitest's populateGlobal), so signals created |
| 25 | +// with `new AbortController()` in test code are jsdom AbortSignals that fail that check. |
| 26 | +// This Proxy wraps Request construction: if the call fails with an AbortSignal type error, |
| 27 | +// it retries without the signal so nock can normalise the request. All other behaviour is |
| 28 | +// unchanged. setupFiles run before test-file imports, so this patch is in place before nock |
| 29 | +// patches globalThis.fetch. |
| 30 | +if (typeof Request !== 'undefined') { |
| 31 | + const OriginalRequest = globalThis.Request; |
| 32 | + globalThis.Request = new Proxy(OriginalRequest, { |
| 33 | + construct(target, args, newTarget) { |
| 34 | + const [input, init] = args as [RequestInfo | URL, RequestInit | undefined]; |
| 35 | + if (init?.signal) { |
| 36 | + try { |
| 37 | + return Reflect.construct(target, args, newTarget); |
| 38 | + } catch (e: unknown) { |
| 39 | + if (e instanceof TypeError && (e as TypeError).message.includes('AbortSignal')) { |
| 40 | + return Reflect.construct( |
| 41 | + target, |
| 42 | + [input, { ...init, signal: undefined }, ...args.slice(2)], |
| 43 | + newTarget |
| 44 | + ); |
| 45 | + } |
| 46 | + throw e; |
| 47 | + } |
| 48 | + } |
| 49 | + return Reflect.construct(target, args, newTarget); |
| 50 | + }, |
| 51 | + }); |
| 52 | +} |
| 53 | + |
21 | 54 | globalThis.indexedDB = indexeddb; |
22 | 55 |
|
23 | 56 | if (typeof TextDecoder === 'undefined' && typeof require !== 'undefined') { |
|
0 commit comments