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 c99974c1..98d809cc 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);