diff --git a/__tests__/hls_qa.test.mjs b/__tests__/hls_qa.test.mjs index a5114c7..ff98290 100644 --- a/__tests__/hls_qa.test.mjs +++ b/__tests__/hls_qa.test.mjs @@ -679,8 +679,43 @@ if (!probeMatch) { } 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 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 const result = win.eval(` (${probeFnSource})();