From fc947ce611b22230191800a329a0e80e4aaa5d4f Mon Sep 17 00:00:00 2001 From: Nicolas Stepien <567105+nstepien@users.noreply.github.com> Date: Sun, 1 Oct 2023 10:37:59 +0100 Subject: [PATCH] fix: add multiple globals in VM+JSDOM (fix #4199) (#4202) --- packages/vitest/src/integrations/env/jsdom.ts | 22 ++++++++++++++++--- test/core/test/environments/jsdom.spec.ts | 21 ++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 test/core/test/environments/jsdom.spec.ts diff --git a/packages/vitest/src/integrations/env/jsdom.ts b/packages/vitest/src/integrations/env/jsdom.ts index f6cc4dd14ef8..9d590301fadf 100644 --- a/packages/vitest/src/integrations/env/jsdom.ts +++ b/packages/vitest/src/integrations/env/jsdom.ts @@ -69,9 +69,25 @@ export default ({ // TODO: browser doesn't expose Buffer, but a lot of dependencies use it dom.window.Buffer = Buffer - // inject structuredClone if it exists - if (typeof structuredClone !== 'undefined' && !dom.window.structuredClone) - dom.window.structuredClone = structuredClone + // inject web globals if they missing in JSDOM but otherwise available in Nodejs + // https://nodejs.org/dist/latest/docs/api/globals.html + const globalNames = [ + 'structuredClone', + 'fetch', + 'Request', + 'Response', + 'BroadcastChannel', + 'MessageChannel', + 'MessagePort', + ] as const + for (const name of globalNames) { + const value = globalThis[name] + if ( + typeof value !== 'undefined' + && typeof dom.window[name] === 'undefined' + ) + dom.window[name] = value + } return { getVmContext() { diff --git a/test/core/test/environments/jsdom.spec.ts b/test/core/test/environments/jsdom.spec.ts new file mode 100644 index 000000000000..d9f97fb88492 --- /dev/null +++ b/test/core/test/environments/jsdom.spec.ts @@ -0,0 +1,21 @@ +// @vitest-environment jsdom + +import { expect, test } from 'vitest' + +const nodeMajor = Number(process.version.slice(1).split('.')[0]) + +test.runIf(nodeMajor >= 15)('MessageChannel and MessagePort are available', () => { + expect(MessageChannel).toBeDefined() + expect(MessagePort).toBeDefined() +}) + +test.runIf(nodeMajor >= 17)('structuredClone is available', () => { + expect(structuredClone).toBeDefined() +}) + +test.runIf(nodeMajor >= 18)('fetch, Request, Response, and BroadcastChannel are available', () => { + expect(fetch).toBeDefined() + expect(Request).toBeDefined() + expect(Response).toBeDefined() + expect(BroadcastChannel).toBeDefined() +})