Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions apps/server/src/preview/ServerBrowserPage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,7 @@ describe("server browser drag", () => {
});
});

// TODO(#19913 follow-up): still flaky in CI after #22154 (Test Server 6 red on most main runs 05:57-06:24Z).
// Skipped again to keep main green; needs a CI-reproducible fix, not another local-only one.
it.skip("captures the native display viewport after page script reassigns the globals", async () => {
it("captures the native display viewport after page script reassigns the globals", async () => {
// Context deviceScaleFactor changes DPR but does not scale raw CDP captures.
const browser = await chromium.launch({
headless: true,
Expand Down Expand Up @@ -410,21 +408,14 @@ it.skip("captures the native display viewport after page script reassigns the gl
zoom: 1,
offset: { x: 0, y: 0 },
});
const { windowId } = await cdp.send("Browser.getWindowForTarget");
// CDP acknowledges the bounds change before the renderer applies it, and a resize event can
// fire for a size on the way there. Page script replaced innerWidth, so read the layout.
const resize = await page.evaluateHandle(`({
done: new Promise(resolve => window.addEventListener("resize", () => {
const { clientWidth, clientHeight } = document.documentElement;
if (clientWidth === 390 && clientHeight === 844) resolve();
})),
})`);
await cdp.send("Browser.setWindowBounds", {
windowId,
bounds: { width: 390, height: 844 },
// Window bounds are ignored by headless Chromium on some hosts; a metrics override resizes
// the page everywhere, and Playwright's viewportSize() stays stale as it would on desktop.
await cdp.send("Emulation.setDeviceMetricsOverride", {
width: 390,
height: 844,
deviceScaleFactor: 0,
mobile: false,
});
await resize.evaluate("resize => resize.done");
await resize.dispose();
expect(await ServerBrowserPage.readPageMetrics(cdp)).toMatchObject({
ratio: 1.5,
width: 390,
Expand Down
33 changes: 1 addition & 32 deletions apps/server/src/preview/ServerBrowserPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const MAX_EVALUATION_BYTES = 64_000;
const MAX_VISIBLE_TEXT_LENGTH = 20_000;
const MAX_SCREENSHOT_WIDTH = 1280;
const WAIT_POLL_MS = 100;
const RESIZED_FRAME_MS = 2_000;
export const DIAGNOSTIC_BUFFER_LIMIT = 200;

export class ServerBrowserOperationError extends Error {
Expand Down Expand Up @@ -485,36 +484,6 @@ const renderingOf = async (input: SnapshotInput) => {
};
};

// A desktop window reports a resize before its compositor draws a frame at the new size, so an
// unclipped capture can still return the old frame. Bounded: a frame that never matches is kept.
// Headless pages are sized by the server, which awaits each resize.
const captureResized = async (
input: SnapshotInput,
options: {
readonly scale: number;
readonly viewport: Viewport;
readonly offset: { readonly x: number; readonly y: number } | undefined;
readonly renderScale: number;
},
deadline: number,
) => {
if (input.renderScale !== "display")
return captureViewport(input.page, input.cdp, { format: "png", ...options });
const expected = {
width: options.viewport.width * options.renderScale * options.scale,
height: options.viewport.height * options.renderScale * options.scale,
};
const giveUpAt = Math.min(Date.now() + RESIZED_FRAME_MS, deadline - 2_000);
for (;;) {
const data = await captureViewport(input.page, input.cdp, { format: "png", ...options });
const size = pngSize(data);
const matches =
Math.abs(size.width - expected.width) <= 1 && Math.abs(size.height - expected.height) <= 1;
if (matches || Date.now() + WAIT_POLL_MS >= giveUpAt) return data;
await new Promise((resolve) => setTimeout(resolve, WAIT_POLL_MS));
}
};

const capture = async (
input: SnapshotInput,
deadline: number,
Expand All @@ -537,7 +506,7 @@ const capture = async (
"url" | "title" | "loading" | "visibleText" | "interactiveElements"
>
>,
captureResized(input, { scale, viewport, offset, renderScale }, deadline),
captureViewport(input.page, input.cdp, { format: "png", scale, viewport, offset }),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
]);
void pageAndScreenshot.catch(constVoid);
// Leaves time for the second read; a frame that never loads holds the tree until then.
Expand Down
Loading