From afa231da3e4cb86cfb35de36be5b73816f97e5e5 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:51:14 +0000 Subject: [PATCH] Fix: Enable video modal share button when source is available The share button in the video modal was not being enabled correctly because `updateSourceAvailability` returned early if `sourceToggleContainer` was missing, skipping the `setShareEnabled` call. This change ensures `setShareEnabled` is called based on `hasUrl` or `hasMagnet` before checking for `sourceToggleContainer`. Added a regression test `tests/e2e/video-modal-share-bug.spec.ts`. --- js/ui/components/VideoModal.js | 10 ++-- tests/e2e/video-modal-share-bug.spec.ts | 67 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 tests/e2e/video-modal-share-bug.spec.ts diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js index d4cf8b27..0188f1e7 100644 --- a/js/ui/components/VideoModal.js +++ b/js/ui/components/VideoModal.js @@ -2797,10 +2797,6 @@ export class VideoModal { } updateSourceAvailability(video) { - if (!this.sourceToggleContainer) { - return; - } - const hasUrl = Boolean( typeof video?.url === "string" && video.url.trim() ); @@ -2809,6 +2805,12 @@ export class VideoModal { video?.torrentSupported ); + this.setShareEnabled(hasUrl || hasMagnet); + + if (!this.sourceToggleContainer) { + return; + } + if (hasUrl || hasMagnet) { this.sourceToggleContainer.removeAttribute("hidden"); this.sourceToggleContainer.classList.remove("hidden"); diff --git a/tests/e2e/video-modal-share-bug.spec.ts b/tests/e2e/video-modal-share-bug.spec.ts new file mode 100644 index 00000000..47446903 --- /dev/null +++ b/tests/e2e/video-modal-share-bug.spec.ts @@ -0,0 +1,67 @@ +import { expect, test } from "@playwright/test"; +import { applyReducedMotion, failOnConsoleErrors } from "./helpers/uiTestUtils"; + +test.describe("video modal share button", () => { + test("opens the share menu when clicked", async ({ page }) => { + await applyReducedMotion(page); + await page.goto("/components/video-modal.html", { waitUntil: "networkidle" }); + + await page.addScriptTag({ + type: "module", + content: ` + import { VideoModal } from "/js/ui/components/VideoModal.js"; + + // Mock dependencies + const mockSetGlobalModalState = (name, isOpen) => { + console.log(\`setGlobalModalState: \${name} = \${isOpen}\`); + }; + + const mockMediaLoader = { + observe: () => {}, + unobserve: () => {}, + }; + + const videoModal = new VideoModal({ + document: document, + setGlobalModalState: mockSetGlobalModalState, + mediaLoader: mockMediaLoader, + }); + + // Force loaded state and hydrate + const playerModal = document.getElementById("playerModal"); + if (playerModal) { + videoModal.loaded = true; + videoModal.hydrate(playerModal); + + // Mock an active video so the share menu has data + videoModal.activeVideo = { + id: "test-video-id", + title: "Test Video", + url: "https://example.com/video.mp4", + magnet: "magnet:?xt=urn:btih:test", + }; + + // Open the modal + videoModal.open(videoModal.activeVideo); + } + + window.__videoModal = videoModal; + `, + }); + + // Ensure modal is visible + const modal = page.locator("#playerModal"); + await expect(modal).not.toHaveClass(/hidden/); + + // Click share button + const shareBtn = page.locator("#shareBtn"); + await expect(shareBtn).toBeVisible(); + await shareBtn.click(); + + // Expect popover to be open + // The popover engine adds data-popover-state="open" to the panel + const popoverPanel = page.locator('[data-menu="video-share"]'); + await expect(popoverPanel).toBeVisible(); + await expect(popoverPanel).toHaveAttribute("data-popover-state", "open"); + }); +});