diff --git a/js/app/uiCoordinator.js b/js/app/uiCoordinator.js index 7a0aee58..a124a2c2 100644 --- a/js/app/uiCoordinator.js +++ b/js/app/uiCoordinator.js @@ -95,6 +95,7 @@ export function createUiCoordinator(deps) { const logoutButton = this.logoutButton || document.getElementById("logoutButton"); if (logoutButton) { logoutButton.classList.remove("hidden"); + logoutButton.style.display = ""; } const userStatus = this.userStatus || document.getElementById("userStatus"); @@ -106,12 +107,14 @@ export function createUiCoordinator(deps) { if (uploadButton) { uploadButton.classList.remove("hidden"); uploadButton.removeAttribute("hidden"); + uploadButton.style.display = ""; } const profileButton = this.profileButton || document.getElementById("profileButton"); if (profileButton) { profileButton.classList.remove("hidden"); profileButton.removeAttribute("hidden"); + profileButton.style.display = ""; } const subscriptionsLink = this.resolveSubscriptionsLink(); diff --git a/js/testHarness.js b/js/testHarness.js index 6ad41ffb..51aed925 100644 --- a/js/testHarness.js +++ b/js/testHarness.js @@ -284,11 +284,9 @@ export function isTestMode() { export function getTestRelayOverrides() { if (typeof window === "undefined") return null; - console.error(`[testHarness] getTestRelayOverrides called. URL: ${window.location.href}`); const params = new URLSearchParams(window.location.search); const paramRelays = params.get("__testRelays__"); if (paramRelays) { - console.error(`[testHarness] Found URL override: ${paramRelays}`); return paramRelays .split(",") .map((r) => r.trim()) @@ -298,15 +296,13 @@ export function getTestRelayOverrides() { try { const stored = localStorage.getItem("__bitvidTestRelays__"); if (stored) { - console.error(`[testHarness] Found localStorage override: ${stored}`); const parsed = JSON.parse(stored); if (Array.isArray(parsed)) return parsed; } - } catch (err) { - console.error("[testHarness] localStorage read failed:", err); + } catch { + // Ignore } - console.error("[testHarness] No overrides found."); return null; } @@ -588,7 +584,8 @@ export function installTestHarness() { const defaultEntries = JSON.stringify(this.defaultEntries.map(e => ({ url: e.url, mode: e.mode }))); if (isTest && currentEntries !== defaultEntries) { - console.error("[testHarness] Preserving non-default relays in loadRelayList (test mode active)"); + // We pretend we loaded successfully but found no new events to apply, + // so the existing (test) relays remain active. return { ok: true, source: "test-override-preserved", events: [] }; } @@ -603,7 +600,6 @@ export function installTestHarness() { if (isTestMode()) { const overrides = getTestRelayOverrides(); if (overrides && overrides.length > 0) { - console.error("[testHarness] Patching reset to restore test relays:", overrides); this.lastEvent = null; this.loadedPubkey = null; this.lastLoadSource = "test-override"; diff --git a/tests/e2e/feed-pagination-stress.spec.ts b/tests/e2e/feed-pagination-stress.spec.ts index e40eb867..3147017f 100644 --- a/tests/e2e/feed-pagination-stress.spec.ts +++ b/tests/e2e/feed-pagination-stress.spec.ts @@ -297,13 +297,14 @@ test.describe("Feed pagination and stress scenarios", () => { const attrs = await page.evaluate(() => { const el = document.querySelector("[data-video-card]"); if (!el) return null; + const titleEl = el.querySelector("[data-video-title]"); return { - hasTitle: el.hasAttribute("data-video-title"), + hasTitle: !!titleEl, hasPubkey: el.hasAttribute("data-video-pubkey"), hasDtag: el.hasAttribute("data-video-dtag"), hasPlayUrl: el.hasAttribute("data-play-url"), hasPlayMagnet: el.hasAttribute("data-play-magnet"), - title: el.getAttribute("data-video-title"), + title: titleEl ? titleEl.getAttribute("data-video-title") : null, pubkey: el.getAttribute("data-video-pubkey"), dtag: el.getAttribute("data-video-dtag"), }; diff --git a/tests/e2e/helpers/bitvidTestFixture.ts b/tests/e2e/helpers/bitvidTestFixture.ts index 6057c936..83a99d9e 100644 --- a/tests/e2e/helpers/bitvidTestFixture.ts +++ b/tests/e2e/helpers/bitvidTestFixture.ts @@ -115,10 +115,14 @@ async function gotoWithTestMode(page: Page, relayUrl: string, path = "/") { const testUrl = `${path}${separator}__test__=1&__testRelays__=${encodeURIComponent(relayUrl)}`; // Set up localStorage before navigation - await page.addInitScript(() => { + await page.addInitScript((url) => { localStorage.setItem("hasSeenDisclaimer", "true"); localStorage.setItem("__bitvidTestMode__", "1"); - }); + // Inject test relays to ensure robust fallback if URL parsing fails + localStorage.setItem("__bitvidTestRelays__", JSON.stringify([url])); + // Disable whitelist mode to ensure seeded test events are accessible + localStorage.setItem("bitvid_admin_whitelist_mode", "false"); + }, relayUrl); await page.goto(testUrl); diff --git a/tests/e2e/video-playback-scenarios.spec.ts b/tests/e2e/video-playback-scenarios.spec.ts index 800c3e81..a846d5b7 100644 --- a/tests/e2e/video-playback-scenarios.spec.ts +++ b/tests/e2e/video-playback-scenarios.spec.ts @@ -35,6 +35,11 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + // Wait for the modal element to be present in DOM before clicking + // This ensures event listeners (like VideoModalController's body click delegate) + // have likely been initialized by the app boot sequence. + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + // When: user clicks the video card const card = page.locator("[data-video-card]").first(); await expect(card).toBeVisible(); @@ -65,6 +70,9 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + // Wait for modal presence to ensure app is fully initialized + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + await page.locator("[data-video-card]").first().click(); const playerModal = page.locator("#playerModal"); @@ -101,6 +109,8 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + // When: user opens the video await page.locator("[data-video-card]").first().click(); @@ -147,6 +157,8 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + // When: user opens the video await page.locator("[data-video-card]").first().click(); @@ -195,32 +207,31 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + await page.locator("[data-video-card]").first().click(); const playerModal = page.locator("#playerModal"); await expect(playerModal).not.toHaveClass(/hidden/, { timeout: 10000 }); // When: user closes the modal - // Try various close mechanisms - const closeBtn = page.locator( - "#playerModal .modal-close, #playerModal [data-close], #playerModal [data-dismiss], #closePlayerModal", - ); - if ((await closeBtn.count()) > 0) { - await closeBtn.first().click({ force: true }); + // Use the standard close button ID which is bound in VideoModal.js + const closeBtn = page.locator("#closeModal"); + await closeBtn.waitFor({ state: "visible", timeout: 5000 }); + await closeBtn.click(); - // Then: modal is hidden again - await page.waitForFunction( - () => { - const modal = document.querySelector("#playerModal"); - if (!modal) return true; - return ( - modal.classList.contains("hidden") || - modal.getAttribute("data-open") === "false" - ); - }, - { timeout: 10000 }, - ); - } + // Then: modal is hidden again + await page.waitForFunction( + () => { + const modal = document.querySelector("#playerModal"); + if (!modal) return true; + return ( + modal.classList.contains("hidden") || + modal.getAttribute("data-open") === "false" + ); + }, + { timeout: 10000 }, + ); // App state should still be valid const state = await page.evaluate(() => { @@ -249,6 +260,8 @@ test.describe("Video playback scenarios", () => { return (window as any).__bitvidTest__.waitForFeedItems(1, 15000); }); + await page.locator("#playerModal").waitFor({ state: "attached", timeout: 15000 }); + // When: user opens the video await page.locator("[data-video-card]").first().click();