diff --git a/packages/app/src/components/browser-webview-resident.browser.test.ts b/packages/app/src/components/browser-webview-resident.browser.test.ts index fc1510803..fa22d3f86 100644 --- a/packages/app/src/components/browser-webview-resident.browser.test.ts +++ b/packages/app/src/components/browser-webview-resident.browser.test.ts @@ -3,6 +3,7 @@ import { cancelResidentBrowserWebviewPixelCapture, clearResidentBrowserWebviewsForTests, ensureResidentBrowserWebview, + prepareBrowserWebview, prepareResidentBrowserWebviewForPixelCapture, releaseResidentBrowserWebview, removeResidentBrowserWebview, @@ -144,6 +145,62 @@ describe("resident browser webviews", () => { expect(secondWebview.style.zIndex).toBe("0"); }); + it("prepares the physically resident webview when a focused duplicate exists outside the resident host", async () => { + const residentWebview = ensureResidentBrowserWebview({ + browserId: "browser-focused-undisplayed", + url: "https://example.com/resident", + }); + if (!residentWebview) { + throw new Error("Expected resident browser webview"); + } + const visibleHost = document.createElement("div"); + const duplicateWebview = document.createElement("webview"); + prepareBrowserWebview(duplicateWebview, { + browserId: "browser-focused-undisplayed", + initialUrl: "https://example.com/duplicate", + }); + visibleHost.appendChild(duplicateWebview); + document.body.prepend(visibleHost); + + const preparation = await prepareResidentBrowserWebviewForPixelCapture({ + browserId: "browser-focused-undisplayed", + }); + const residentHost = document.getElementById("paseo-browser-resident-webviews"); + + expect(residentHost?.style.left).toBe("0px"); + expect(residentHost?.style.width).toBe("1px"); + expect(residentWebview.style.zIndex).toBe("2"); + expect(duplicateWebview.style.zIndex).toBe(""); + + await restoreResidentBrowserWebviewAfterPixelCapture(preparation); + }); + + it("does not apply resident prep styles for a genuinely visible pane webview", async () => { + const visibleHost = document.createElement("div"); + const visibleWebview = document.createElement("webview"); + prepareBrowserWebview(visibleWebview, { + browserId: "browser-visible-pane", + initialUrl: "https://example.com", + }); + visibleWebview.style.display = "flex"; + visibleWebview.style.width = "100%"; + visibleWebview.style.height = "100%"; + visibleHost.appendChild(visibleWebview); + document.body.appendChild(visibleHost); + + const preparation = await prepareResidentBrowserWebviewForPixelCapture({ + browserId: "browser-visible-pane", + }); + const residentHost = document.getElementById("paseo-browser-resident-webviews"); + + expect(residentHost?.style.left).toBe("-20000px"); + expect(residentHost?.style.width).toBe("1280px"); + expect(visibleWebview.style.position).toBe(""); + expect(visibleWebview.style.zIndex).toBe(""); + + await restoreResidentBrowserWebviewAfterPixelCapture(preparation); + }); + it("clears capture preparation when a resident webview is taken visible", async () => { const webview = ensureResidentBrowserWebview({ browserId: "browser-visible", diff --git a/packages/app/src/components/browser-webview-resident.ts b/packages/app/src/components/browser-webview-resident.ts index a6e37aed2..3a24abaca 100644 --- a/packages/app/src/components/browser-webview-resident.ts +++ b/packages/app/src/components/browser-webview-resident.ts @@ -92,6 +92,17 @@ function findBrowserWebview(browserId: string, ownerDocument: Document): HTMLEle return null; } +function findBrowserWebviewForPixelCapture( + browserId: string, + ownerDocument: Document, +): HTMLElement | null { + const resident = residentWebviewsByBrowserId.get(browserId) ?? null; + if (resident?.isConnected) { + return resident; + } + return findBrowserWebview(browserId, ownerDocument); +} + function applyResidentWebviewStyle(webview: HTMLElement): void { webview.style.display = "inline-flex"; webview.style.flex = "0 0 auto"; @@ -258,6 +269,9 @@ export function ensureResidentBrowserWebview(input: { const existing = findBrowserWebview(browserId, ownerDocument); if (existing) { + if (existing.parentElement?.id === RESIDENT_BROWSER_HOST_ID) { + residentWebviewsByBrowserId.set(browserId, existing); + } return existing; } @@ -314,7 +328,7 @@ export async function prepareResidentBrowserWebviewForPixelCapture(input: { } const host = getResidentBrowserHost(ownerDocument); - const webview = findBrowserWebview(browserId, ownerDocument); + const webview = findBrowserWebviewForPixelCapture(browserId, ownerDocument); if (!webview) { throw new Error(`Browser webview ${browserId} is not mounted.`); }