Use Electron capturePage for browser screenshots
This commit is contained in:
@@ -25,7 +25,10 @@ export interface TabContents {
|
||||
goBack(): void;
|
||||
goForward(): void;
|
||||
reload(): void;
|
||||
capturePage(): Promise<TabImage>;
|
||||
capturePage(options?: TabCapturePageOptions): Promise<TabImage>;
|
||||
invalidate(): void;
|
||||
isBackgroundThrottlingAllowed(): boolean;
|
||||
setBackgroundThrottling(allowed: boolean): void;
|
||||
getConsoleMessages?(): BrowserAutomationConsoleLogEntry[];
|
||||
getCookies?(url: string): Promise<BrowserAutomationCookieEntry[]>;
|
||||
sendDebugCommand?(command: string, params?: Record<string, unknown>): Promise<unknown>;
|
||||
@@ -42,6 +45,10 @@ export interface TabImage {
|
||||
getSize(): { width: number; height: number };
|
||||
}
|
||||
|
||||
export interface TabCapturePageOptions {
|
||||
stayHidden?: boolean;
|
||||
}
|
||||
|
||||
export interface BrowserRegistry {
|
||||
listRegisteredBrowserIds(): string[];
|
||||
listRegisteredBrowserIdsForWorkspace(workspaceId: string): string[];
|
||||
@@ -104,6 +111,17 @@ async function withPixelCaptureTimeout<T>(capture: Promise<T>): Promise<T> {
|
||||
}
|
||||
}
|
||||
|
||||
async function capturePaintedViewport(contents: TabContents): Promise<TabImage> {
|
||||
const previousBackgroundThrottling = contents.isBackgroundThrottlingAllowed();
|
||||
contents.setBackgroundThrottling(false);
|
||||
try {
|
||||
contents.invalidate();
|
||||
return await withPixelCaptureTimeout(contents.capturePage({ stayHidden: false }));
|
||||
} finally {
|
||||
contents.setBackgroundThrottling(previousBackgroundThrottling);
|
||||
}
|
||||
}
|
||||
|
||||
function tabInfoFromContents(
|
||||
browserId: string,
|
||||
contents: TabContents,
|
||||
@@ -1104,41 +1122,9 @@ async function executeScreenshot(
|
||||
if ("ok" in target) {
|
||||
return target;
|
||||
}
|
||||
if (target.contents.sendDebugCommand) {
|
||||
let screenshot: CdpCaptureScreenshotResult;
|
||||
try {
|
||||
screenshot = (await withPixelCaptureTimeout(
|
||||
target.contents.sendDebugCommand("Page.captureScreenshot", {
|
||||
format: "png",
|
||||
fromSurface: false,
|
||||
}),
|
||||
)) as CdpCaptureScreenshotResult;
|
||||
} catch (error) {
|
||||
if (isScreenshotNoFrameError(error)) {
|
||||
return screenshotNoFrameFailure(requestId);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!screenshot.data) {
|
||||
return fail(requestId, "browser_unsupported", "browser_screenshot returned no data");
|
||||
}
|
||||
const viewport = await getViewportSize(target.contents);
|
||||
return {
|
||||
requestId,
|
||||
ok: true,
|
||||
result: {
|
||||
command: "screenshot",
|
||||
browserId: target.browserId,
|
||||
mimeType: "image/png",
|
||||
dataBase64: screenshot.data,
|
||||
width: viewport.width,
|
||||
height: viewport.height,
|
||||
},
|
||||
};
|
||||
}
|
||||
let image: TabImage;
|
||||
try {
|
||||
image = await withPixelCaptureTimeout(target.contents.capturePage());
|
||||
image = await capturePaintedViewport(target.contents);
|
||||
} catch (error) {
|
||||
if (isScreenshotNoFrameError(error)) {
|
||||
return screenshotNoFrameFailure(requestId);
|
||||
@@ -1183,20 +1169,6 @@ interface CdpCaptureScreenshotResult {
|
||||
data?: string;
|
||||
}
|
||||
|
||||
async function getViewportSize(contents: TabContents): Promise<{ width: number; height: number }> {
|
||||
const result = await contents.executeJavaScript(
|
||||
"({ width: Math.round(window.innerWidth), height: Math.round(window.innerHeight) })",
|
||||
);
|
||||
if (!result || typeof result !== "object") {
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
const record = result as { width?: unknown; height?: unknown };
|
||||
return {
|
||||
width: typeof record.width === "number" && Number.isFinite(record.width) ? record.width : 0,
|
||||
height: typeof record.height === "number" && Number.isFinite(record.height) ? record.height : 0,
|
||||
};
|
||||
}
|
||||
|
||||
async function getCdpLayoutMetrics(contents: TabContents): Promise<{
|
||||
viewportWidth: number;
|
||||
viewportHeight: number;
|
||||
|
||||
Reference in New Issue
Block a user