From 0cd4f12cfb695a450665d968fea81f3079d92f8e Mon Sep 17 00:00:00 2001 From: Satoshi Qazi Muhammed Date: Sat, 10 Oct 2026 08:52:46 +0400 Subject: [PATCH] dev-test: JSDOM's Event and CustomEvent win over Node's in the browser env Globals were only set where Node had none, and Node defines Event and CustomEvent itself. Code running in the browser env therefore built Node events, which a JSDOM node refuses: react-tooltip's window.dispatchEvent(new CustomEvent(...)) threw "parameter 1 is not of type 'Event'". In the browser env these two now come from JSDOM, as they do under jest-environment-jsdom. --- packages/dev-test/src/env/browser.spec.ts | 5 +++++ packages/dev-test/src/env/browser.ts | 10 ++++++++++ packages/dev-test/src/env/index.ts | 8 ++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/dev-test/src/env/browser.spec.ts b/packages/dev-test/src/env/browser.spec.ts index e38c910..30fa22b 100644 --- a/packages/dev-test/src/env/browser.spec.ts +++ b/packages/dev-test/src/env/browser.spec.ts @@ -23,4 +23,9 @@ describe('browser', () => { it('contains HTML*Element', () => { expect(typeof all.HTMLElement).toBe('function'); }); + + it('dispatches the global CustomEvent and Event on window', () => { + expect(() => window.dispatchEvent(new CustomEvent('custom', { detail: 1 }))).not.toThrow(); + expect(() => window.dispatchEvent(new Event('plain'))).not.toThrow(); + }); }); diff --git a/packages/dev-test/src/env/browser.ts b/packages/dev-test/src/env/browser.ts index 39377a1..0a702a0 100644 --- a/packages/dev-test/src/env/browser.ts +++ b/packages/dev-test/src/env/browser.ts @@ -3,6 +3,13 @@ import { JSDOM } from 'jsdom'; +/** + * Constructors that Node defines as well. A DOM node only accepts an event + * created in its own realm, so in the browser environment the JSDOM ones + * replace Node's, as they do under jest-environment-jsdom. + */ +export const BROWSER_OVERRIDES: readonly string[] = ['CustomEvent', 'Event']; + /** * Export a very basic JSDom environment - this is just enough so we have * @testing-environment/react tests passing in this repo @@ -15,6 +22,9 @@ export function browser () { const { window } = new JSDOM('', { url: 'http://localhost' }); return { + // Event constructors, see BROWSER_OVERRIDES + CustomEvent: window.CustomEvent, + Event: window.Event, // All HTML Elements that are defined on the JSDOM window object. // (we copied as-is from the types definition). We cannot get this // via Object.keys(window).filter(...) so we have to specify explicitly diff --git a/packages/dev-test/src/env/index.ts b/packages/dev-test/src/env/index.ts index 37ce94e..8ec9132 100644 --- a/packages/dev-test/src/env/index.ts +++ b/packages/dev-test/src/env/index.ts @@ -1,7 +1,7 @@ // Copyright 2017-2026 @pezkuwi/dev-test authors & contributors // SPDX-License-Identifier: Apache-2.0 -import { browser } from './browser.js'; +import { browser, BROWSER_OVERRIDES } from './browser.js'; import { expect } from './expect.js'; import { jest } from './jest.js'; import { lifecycle } from './lifecycle.js'; @@ -15,7 +15,11 @@ export function exposeEnv (isBrowser: boolean): void { env && Object .entries(env()) .forEach(([key, fn]) => { - globalThis[key as 'undefined'] ??= fn; + if (isBrowser && BROWSER_OVERRIDES.includes(key)) { + (globalThis as Record)[key] = fn; + } else { + globalThis[key as 'undefined'] ??= fn; + } }); }); }