Why does JSDOM's `runScripts: 'dangerously'` change the output of `Object.getOwnPropertyNames(jsdom.window)`?

103 Views Asked by At

Update

I've yet to understand why, but the runScripts: 'dangerously', is causing this problem. When I comment that out, the first console.log prints 1, just like a browser.


I created a repository for the node.js side of this question. Here's the entire index.js file:

import { JSDOM } from 'jsdom';

JSDOM.fromFile('template.html', {
    url: 'http://localhost',
    runScripts: 'dangerously',
    resources: 'usable',
    pretendToBeVisual: true,
}).then(({ window }) => {
    console.log(`Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length`, Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length);
    
    console.log(`window.HTMLElement`, window.HTMLElement);
    console.log(`Object.getOwnPropertyDescriptor(window, 'HTMLElement')`, Object.getOwnPropertyDescriptor(window, 'HTMLElement'));
    console.log(`Object.getPrototypeOf(window.constructor).name`, Object.getPrototypeOf(window.constructor).name);
});

Note the 0 in this code's output:

Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length 0
window.HTMLElement [class HTMLElement extends Element]
Object.getOwnPropertyDescriptor(window, 'HTMLElement') {
  value: [class HTMLElement extends Element],
  writable: true,
  enumerable: false,
  configurable: true
}
Object.getPrototypeOf(window.constructor).name EventTarget

If I run those same console.logs in the browser, it prints 1:

console.log(`Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length`, Object.getOwnPropertyNames(window).filter((k) => k === "HTMLElement").length);

console.log(`window.HTMLElement`, window.HTMLElement);
console.log(`Object.getOwnPropertyDescriptor(window, 'HTMLElement')`, Object.getOwnPropertyDescriptor(window, 'HTMLElement'));
console.log(`Object.getPrototypeOf(window.constructor).name`, Object.getPrototypeOf(window.constructor).name);

As far as I can tell, these properties have the same descriptors and both windows have the same prototype (name). I'm not aware of anything else that could because this difference in behavior.

Why does this code work differently in JSDOM?


Miscellaneous information

I have created this GitHub issue in the JSDOM repository because it might be a bug of some sort: https://github.com/jsdom/jsdom/issues/3688

As far as I know, the template.html file is irrelevant to my question, but here's how it looks:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>title</title>
  </head>
  <body>
    <p>Hello world</p>
  </body>
</html>

I am using jsdom 24.0.0 and node v20.10.0.

0

There are 0 best solutions below