Fix multi-webview browser capture prep

This commit is contained in:
Mohamed Boudra
2026-07-03 07:00:06 +02:00
parent 33ffeb4d42
commit f22865df62
7 changed files with 392 additions and 82 deletions
@@ -55,6 +55,7 @@ class FakeTab implements TabContents {
public captureThrows = false;
public deferCaptures = false;
public prepareNeverAcks = false;
public fullPageScreenshotThrows = false;
public layoutMetrics = {
cssLayoutViewport: { clientWidth: 390, clientHeight: 844 },
cssContentSize: { width: 390, height: 1200 },
@@ -184,6 +185,9 @@ class FakeTab implements TabContents {
return this.layoutMetrics;
}
if (command === "Page.captureScreenshot") {
if (this.fullPageScreenshotThrows) {
throw new Error("UnknownVizError");
}
return { data: this.fullPageScreenshotData };
}
if (command === "DOM.getDocument") {
@@ -959,7 +963,7 @@ describe("executeAutomationCommand", () => {
}
});
test("screenshot restores capture preparation when viewport capture fails", async () => {
test("screenshot returns no-frame and restores capture preparation when viewport capture throws", async () => {
const browser = new BrowserAutomationHarness();
browser.tab.captureThrows = true;
@@ -968,7 +972,15 @@ describe("executeAutomationCommand", () => {
command: "screenshot",
args: { browserId: BROWSER_A },
}),
).rejects.toThrow("capture failed");
).resolves.toEqual({
requestId: "req-screenshot",
ok: false,
error: {
code: "screenshot_no_frame",
message: "The browser tab has no painted frame. Focus the tab in the app, then try again.",
retryable: false,
},
});
expect(browser.tab.actions).toEqual([
"prepare",
@@ -1135,6 +1147,35 @@ describe("executeAutomationCommand", () => {
]);
});
test("screenshot with fullPage returns no-frame when CDP capture throws", async () => {
const browser = new BrowserAutomationHarness();
browser.tab.fullPageScreenshotThrows = true;
const result = await browser.execute({
command: "screenshot",
args: { browserId: BROWSER_A, fullPage: true },
});
expect(result).toEqual({
requestId: "req-screenshot",
ok: false,
error: {
code: "screenshot_no_frame",
message: "The browser tab has no painted frame. Focus the tab in the app, then try again.",
retryable: false,
},
});
expect(browser.tab.actions).toEqual([
"prepare",
"background:false",
"invalidate",
"debug:Page.getLayoutMetrics",
"debug:Page.captureScreenshot",
"restore:capture-1",
"background:true",
]);
});
test("upload resolves workspace files before setting them on the file input", async () => {
const browser = new BrowserAutomationHarness();
browser.tab.snapshotElements = [
@@ -149,6 +149,17 @@ async function restorePixelCapture(
}
}
async function capturePreparedPixelFrame<T>(capture: () => Promise<T>): Promise<T> {
try {
return await withPixelCaptureTimeout(capture());
} catch (error) {
if (isScreenshotNoFrameError(error)) {
throw error;
}
throw new ScreenshotNoFrameError();
}
}
async function runPreparedPixelCapture<T>(
contents: TabContents,
capture: () => Promise<T>,
@@ -163,7 +174,7 @@ async function runPreparedPixelCapture<T>(
preparation = await prepareForPixelCapture(contents);
contents.setBackgroundThrottling(false);
contents.invalidate();
return await withPixelCaptureTimeout(capture());
return await capturePreparedPixelFrame(capture);
} finally {
try {
if (preparation) {