diff --git a/js/components/src/components/chat/chat-box.tsx b/js/components/src/components/chat/chat-box.tsx index de3a27440..71ff8cfd4 100644 --- a/js/components/src/components/chat/chat-box.tsx +++ b/js/components/src/components/chat/chat-box.tsx @@ -694,14 +694,20 @@ export function ChatBox({ }} onPress={() => { const did = linfo?.author?.did ?? profile?.did; - if (did) { - const u = new URL(window.location.href); - u.pathname = `/chat-popout/${did}`; - window.open( - u.toString(), - "_blank", - "popup=true,width=480,height=600", - ); + if (!did) return; + const u = new URL(window.location.href); + u.pathname = `/chat-popout/${did}`; + const popup = window.open( + u.toString(), + "_blank", + "popup=true,width=480,height=600", + ); + if (!popup) { + // A blocked popup returns null. Don't hide the panel and + // leave the viewer with no chat at all — send this tab to + // the popout instead. + window.location.assign(u.toString()); + return; } setIsChatVisible?.(false); }} diff --git a/js/e2e-web/flows/07-chat-popout.spec.ts b/js/e2e-web/flows/07-chat-popout.spec.ts index 42822cd90..704b1a780 100644 --- a/js/e2e-web/flows/07-chat-popout.spec.ts +++ b/js/e2e-web/flows/07-chat-popout.spec.ts @@ -47,3 +47,29 @@ test("07-chat-popout: opens one window, leaves the stream page alone", async ({ await popup.close(); expect(page.context().pages()).toHaveLength(1); }); + +test("07-chat-popout: blocked popup falls back to this tab", async ({ + page, +}) => { + await loginThroughPds(page); + + await page.goto(`${HTTPS_URL}/`); + await page.getByTestId("home-stream-card").first().click(); + await expect( + page.getByText("Now streaming - e2e test stream").first(), + ).toBeVisible({ timeout: 30_000 }); + const popoutButton = page.getByTestId("chat-popout-button"); + await expect(popoutButton).toBeVisible({ timeout: 30_000 }); + + let popups = 0; + page.on("popup", () => popups++); + // A popup blocker makes window.open return null with no window; the button + // must not just hide the chat panel and leave the viewer with nothing. + await page.evaluate(() => { + window.open = () => null; + }); + + await popoutButton.click(); + await page.waitForURL(/\/chat-popout\/did:plc:/, { timeout: 10_000 }); + expect(popups).toBe(0); +});