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
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const timezoneSchema = z.string().refine((val) => validateTimezone(val) === unde

const dimensionsSchema = z
.object({
height: z.number().positive().max(14400),
// 16000px height is the maximum screenshot Chrome can make
height: z.number().positive().max(16000),
width: z.number().positive().max(14400),
})
.strict();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('Create Layout', () => {
},
"useReportingBranding": true,
"width": 16,
"zoom": 2,
}
`);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,18 @@ it('preserve layout allows customizable selectors', () => {
}
`);
});

it('preserve layout use a default zoom of 2', () => {
const testPreserveLayout = new PreserveLayout({ width: 1000, height: 2000 });
expect(testPreserveLayout.getBrowserZoom()).toBe(2);
expect(testPreserveLayout.getBrowserViewport().height).toBe(4000);
});

it('preserve layout caps browser zoom for extremely large screenshots to avoid Chromium artifacts', () => {
// A very tall layout would exceed Chrome limits at zoom=2.
const testPreserveLayout = new PreserveLayout({ width: 1727, height: 15000 });

// The zoom should be reduced so that output height stays <= 16000 pixels.
expect(testPreserveLayout.getBrowserZoom()).toBe(1);
expect(testPreserveLayout.getBrowserViewport().height).toBeLessThanOrEqual(16000);
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ import type { Layout } from '.';
import { BaseLayout } from './base_layout';
import type { PageSizeParams, PdfImageSize } from './base_layout';

// We use a zoom of two to bump up the resolution of the screenshot a bit.
const ZOOM: number = 2;
// We default to a zoom of two to bump up the resolution of the screenshot a bit.
// However, Chromium/Skia has a height limit of 16384px, so for anything larger
// than 8000, we should use a zoom of one.
// https://github.com/puppeteer/puppeteer/issues/359
const DEFAULT_ZOOM = 2;
const MAX_HEIGHT_PX = 8000;

export class PreserveLayout extends BaseLayout implements Layout {
public readonly selectors: LayoutSelectorDictionary;
public readonly height: number;
public readonly width: number;
private readonly zoom: number;
private readonly scaledHeight: number;
private readonly scaledWidth: number;
private imageSize: PdfImageSize = { height: 0, width: 0 };
Expand All @@ -27,8 +32,9 @@ export class PreserveLayout extends BaseLayout implements Layout {
super('preserve_layout');
this.height = size.height;
this.width = size.width;
this.scaledHeight = size.height * ZOOM;
this.scaledWidth = size.width * ZOOM;
this.zoom = this.height <= MAX_HEIGHT_PX ? DEFAULT_ZOOM : 1;
this.scaledHeight = size.height * this.zoom;
this.scaledWidth = size.width * this.zoom;

this.selectors = { ...DEFAULT_SELECTORS, ...selectors };
}
Expand All @@ -46,14 +52,14 @@ export class PreserveLayout extends BaseLayout implements Layout {
}

public getBrowserZoom() {
return ZOOM;
return this.zoom;
}

public getViewport() {
return {
height: this.height,
width: this.width,
zoom: ZOOM,
zoom: this.zoom,
};
}

Expand Down