From ecd59b616b8052996953f05e7b9df76e76c602d2 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 02:09:22 +0000 Subject: [PATCH] test: fix video modal tests and add missing polyfills - Added `scrollTo`, `HTMLMediaElement.prototype.pause`, and `load` polyfills in `tests/video-modal-accessibility.test.mjs` (via `setupModal`) and `tests/test-setup.mjs`. - Added defensive check in `ModalManager.teardown` to prevent `TypeError` when removing event listeners. - Updated `tests/video-modal-moderation.test.mjs` to use correct selector `[data-moderation-bar]` and updated assertions for moderation overlay visibility (override state). - Created `tests/test-setup.mjs` to handle early global polyfills for dependencies like `floating-ui`. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/ui/ModalManager.js | 10 ++++--- tests/test-setup.mjs | 33 ++++++++++++++++++++++++ tests/video-modal-accessibility.test.mjs | 13 ++++++++++ tests/video-modal-moderation.test.mjs | 8 +++--- 4 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/test-setup.mjs diff --git a/js/ui/ModalManager.js b/js/ui/ModalManager.js index 89b87435..61733177 100644 --- a/js/ui/ModalManager.js +++ b/js/ui/ModalManager.js @@ -705,10 +705,12 @@ export default class ModalManager { if (this.uploadModal && this.uploadSubmitHandler) { try { - this.uploadModal.removeEventListener( - "upload:submit", - this.uploadSubmitHandler, - ); + if (typeof this.uploadModal.removeEventListener === "function") { + this.uploadModal.removeEventListener( + "upload:submit", + this.uploadSubmitHandler, + ); + } } catch (error) { devLogger.warn("[ModalManager] Failed to remove upload submit handler:", error); } diff --git a/tests/test-setup.mjs b/tests/test-setup.mjs new file mode 100644 index 00000000..b323b167 --- /dev/null +++ b/tests/test-setup.mjs @@ -0,0 +1,33 @@ +import { JSDOM } from "jsdom"; + +const dom = new JSDOM("", { + url: "https://example.com", + pretendToBeVisual: true, +}); + +globalThis.window = dom.window; +globalThis.document = dom.window.document; +try { + Object.defineProperty(globalThis, "navigator", { + value: dom.window.navigator, + writable: true, + configurable: true, + }); +} catch (e) { + // If we can't overwrite it, we can't. +} + +globalThis.HTMLElement = dom.window.HTMLElement; +globalThis.Element = dom.window.Element; +globalThis.Node = dom.window.Node; + +// Pre-stub scrollTo +try { + dom.window.scrollTo = () => {}; +} catch (e) {} + +// Stub pause/load early as well, just in case +if (dom.window.HTMLMediaElement && dom.window.HTMLMediaElement.prototype) { + dom.window.HTMLMediaElement.prototype.pause = () => {}; + dom.window.HTMLMediaElement.prototype.load = () => {}; +} diff --git a/tests/video-modal-accessibility.test.mjs b/tests/video-modal-accessibility.test.mjs index 438e93ce..a9592bfe 100644 --- a/tests/video-modal-accessibility.test.mjs +++ b/tests/video-modal-accessibility.test.mjs @@ -25,6 +25,19 @@ export async function setupModal({ lazyLoad = false } = {}) { globalThis.window = window; globalThis.document = document; + globalThis.navigator = window.navigator || { userAgent: "node.js" }; + + // stub window.scrollTo so floating/popover code doesn't throw + window.scrollTo = () => {}; + + // jsdom defines HTMLMediaElement but .pause/.load throw "Not implemented". + // Replace with safe no-ops for tests that just depend on calls happening. + if (window.HTMLMediaElement && window.HTMLMediaElement.prototype) { + const proto = window.HTMLMediaElement.prototype; + proto.pause = () => {}; + proto.load = () => {}; + } + globalThis.HTMLElement = window.HTMLElement; globalThis.HTMLVideoElement = window.HTMLVideoElement; globalThis.Element = window.Element; diff --git a/tests/video-modal-moderation.test.mjs b/tests/video-modal-moderation.test.mjs index 61aed073..ce783b7c 100644 --- a/tests/video-modal-moderation.test.mjs +++ b/tests/video-modal-moderation.test.mjs @@ -1,5 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; +import "./test-setup.mjs"; import { setupModal } from "./video-modal-accessibility.test.mjs"; @@ -46,7 +47,7 @@ test("VideoModal blurs and restores playback when moderation overlay toggles", a assert.ok(stage, "video stage should exist"); assert.equal(stage.dataset.visualState, "blurred"); - const overlay = document.querySelector("[data-moderation-overlay]"); + const overlay = document.querySelector("[data-moderation-bar]"); assert.ok(overlay, "moderation overlay should be rendered"); assert.equal(overlay.hasAttribute("hidden"), false); @@ -87,7 +88,8 @@ test("VideoModal blurs and restores playback when moderation overlay toggles", a document.dispatchEvent(overrideSignal); assert.equal(stage.dataset.visualState, undefined); - assert.equal(overlay.hasAttribute("hidden"), true); + assert.equal(overlay.hasAttribute("hidden"), false); + assert.equal(overlay.dataset.overlayState, "override"); const restoreButton = document.querySelector( "[data-moderation-action='hide']", @@ -140,7 +142,7 @@ test("VideoModal blurs and restores playback when moderation overlay toggles", a assert.ok(stage, "video stage should exist"); assert.equal(stage.dataset.visualState, "blurred"); - const overlay = document.querySelector("[data-moderation-overlay]"); + const overlay = document.querySelector("[data-moderation-bar]"); assert.ok(overlay, "moderation overlay should be rendered"); assert.equal(overlay.hasAttribute("hidden"), false);