-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Basic info:
- Node.js version: v18+
- jsdom version: any JSDOM version
Issue
JSDOM is polyfilling a bunch of already existing global APIs, which leads to all sorts of issues when the underlying code expects those APIs to be actual.
All the issues I'm describing are transient. They are likely not reproducible in an isolated JSDOM environment since JSDOM creates an illusion of "globals" working instead of actually relying on the environment's globals that already exist.
While JSDOM aims to emulate the browser, most of my (and others') pain of working with JSDOM rises from it ignoring that it's still being run in Node.js. It must respect Node.js globals to create a functional, complete environment.
Example 1: AbortSignal doesn't extend EventTarget
import { implementation as AbortSignal } from 'jsdom/lib/jsdom/living/aborting/AbortSignal-impl'
it('AbortSignal extends EventTarget', () => {
expect(AbortSignal instanceof EventTarget).toBe(true)
})Root cause: JSDOM extends its own EventTarget implementation. This is incorrect and harmful. No child classes of the custom EventTargetImpl in JSDOM will be treated as valid events in Node.js. It will throw right here, among other places:
Example 2: Custom Event
JSDOM implements a custom EventImpl instead of relying on the global Event class. No derives events will be considered valid events by Node.js.
Example: try dispatching an Event on an EventTarget instance.
import { implementation as Event } from 'jsdom/lib/jsdom/living/events/Event-impl'
// Valid global EventTarget in Node.js
const target = new EventTarget()
target.dispatchEvent(new Event('hello'))This will throw right over here in Node.js:
Because custom Event implementation from JSDOM is not a valid Event in Node.js.
Minimal reproduction case
I've provided two reproduction cases above. Please see those. I can submit a test suite that fails with JSDOM due to it not respecting Node.js globals.
How does similar code behave in browsers?
Both browsers and Node.js correctly rely on and execute global functions. I expect JSDOM not to rob me of those either.