fix(tests): stop hls_qa deep-probe suite hanging under jsdom (test-only) #3
@@ -679,8 +679,43 @@ if (!probeMatch) {
|
|||||||
}
|
}
|
||||||
const probeFnSource = probeMatch[0];
|
const probeFnSource = probeMatch[0];
|
||||||
|
|
||||||
|
// jsdom exposes a set of self-referential cyclic globals as *enumerable own-*
|
||||||
|
// properties on the window object. A real Chrome MAIN-world window does not:
|
||||||
|
// `window`, `self`, `top`, `parent`, `frames` are non-enumerable, and the
|
||||||
|
// jsdom-internal `_globalObject`/`_globalProxy`/`_top`/`_parent` keys don't
|
||||||
|
// exist at all. The deep-probe's Strategy H runs `Object.keys(window)` and a
|
||||||
|
// no-visited-set `walk()` over each player-like value, so these cyclic
|
||||||
|
// jsdom-only keys make the walk explode to O(keys^depth) (~3.5e11 ops) and the
|
||||||
|
// suite never terminates. We can't fix the probe (production src/ is off-limits
|
||||||
|
// for this test-only PR), so instead we make this jsdom window mirror a real
|
||||||
|
// page by marking the cyclic globals non-enumerable before the probe runs.
|
||||||
|
const JSDOM_CYCLIC_GLOBALS = [
|
||||||
|
'_globalObject', '_globalProxy', '_top', '_parent',
|
||||||
|
'window', 'self', 'top', 'parent', 'frames',
|
||||||
|
];
|
||||||
|
function sanitizeJsdomWinForProbe(win) {
|
||||||
|
for (const key of JSDOM_CYCLIC_GLOBALS) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(win, key)) continue;
|
||||||
|
let desc;
|
||||||
|
try { desc = Object.getOwnPropertyDescriptor(win, key); } catch { continue; }
|
||||||
|
if (!desc) continue;
|
||||||
|
try {
|
||||||
|
// Re-assert the same descriptor but with enumerable:false so the probe's
|
||||||
|
// `Object.keys(window)` no longer sees jsdom's cyclic self-references.
|
||||||
|
Object.defineProperty(win, key, { ...desc, enumerable: false });
|
||||||
|
} catch {
|
||||||
|
// Non-configurable descriptors (e.g. the `window`/`top` getters) can't be
|
||||||
|
// redefined; skip them. The remaining cyclic keys are already suppressed,
|
||||||
|
// leaving only a shallow 2-branch recursion that terminates in ms.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper: eval the probe function inside a JSDOM window, then return results
|
// Helper: eval the probe function inside a JSDOM window, then return results
|
||||||
function runProbeInWin(win) {
|
function runProbeInWin(win) {
|
||||||
|
// Mirror a real page environment (see JSDOM_CYCLIC_GLOBALS note above):
|
||||||
|
// non-enumerable cyclic globals prevent Strategy H's window scan from looping.
|
||||||
|
sanitizeJsdomWinForProbe(win);
|
||||||
// Define the function in the JSDOM context and call it
|
// Define the function in the JSDOM context and call it
|
||||||
const result = win.eval(`
|
const result = win.eval(`
|
||||||
(${probeFnSource})();
|
(${probeFnSource})();
|
||||||
|
|||||||
Reference in new issue
Block a user