Skip to content

Commit 19df262

Browse files
authored
[Reporting] set zoom to 1 for long reports (#248785)
resolves #138812 ## Summary Chrome has a hard limit of 16000 rows in a page screenshot. We currently set the zoom level to 2, which means any report > 8000 in height won't be rendered correctly. As a partial fix, we'll set zoom to 1 for any report that is > 8000 height. for more info: puppeteer/puppeteer#359
1 parent 1d9a659 commit 19df262

4 files changed

Lines changed: 30 additions & 7 deletions

File tree

x-pack/platform/plugins/private/reporting/server/routes/common/request_handler/validator.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ const timezoneSchema = z.string().refine((val) => validateTimezone(val) === unde
4141

4242
const dimensionsSchema = z
4343
.object({
44-
height: z.number().positive().max(14400),
44+
// 16000px height is the maximum screenshot Chrome can make
45+
height: z.number().positive().max(16000),
4546
width: z.number().positive().max(14400),
4647
})
4748
.strict();

x-pack/platform/plugins/shared/screenshotting/server/layouts/create_layout.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('Create Layout', () => {
3737
},
3838
"useReportingBranding": true,
3939
"width": 16,
40+
"zoom": 2,
4041
}
4142
`);
4243
});

x-pack/platform/plugins/shared/screenshotting/server/layouts/preserve_layout.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,18 @@ it('preserve layout allows customizable selectors', () => {
5858
}
5959
`);
6060
});
61+
62+
it('preserve layout use a default zoom of 2', () => {
63+
const testPreserveLayout = new PreserveLayout({ width: 1000, height: 2000 });
64+
expect(testPreserveLayout.getBrowserZoom()).toBe(2);
65+
expect(testPreserveLayout.getBrowserViewport().height).toBe(4000);
66+
});
67+
68+
it('preserve layout caps browser zoom for extremely large screenshots to avoid Chromium artifacts', () => {
69+
// A very tall layout would exceed Chrome limits at zoom=2.
70+
const testPreserveLayout = new PreserveLayout({ width: 1727, height: 15000 });
71+
72+
// The zoom should be reduced so that output height stays <= 16000 pixels.
73+
expect(testPreserveLayout.getBrowserZoom()).toBe(1);
74+
expect(testPreserveLayout.getBrowserViewport().height).toBeLessThanOrEqual(16000);
75+
});

x-pack/platform/plugins/shared/screenshotting/server/layouts/preserve_layout.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ import type { Layout } from '.';
1212
import { BaseLayout } from './base_layout';
1313
import type { PageSizeParams, PdfImageSize } from './base_layout';
1414

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

1822
export class PreserveLayout extends BaseLayout implements Layout {
1923
public readonly selectors: LayoutSelectorDictionary;
2024
public readonly height: number;
2125
public readonly width: number;
26+
private readonly zoom: number;
2227
private readonly scaledHeight: number;
2328
private readonly scaledWidth: number;
2429
private imageSize: PdfImageSize = { height: 0, width: 0 };
@@ -27,8 +32,9 @@ export class PreserveLayout extends BaseLayout implements Layout {
2732
super('preserve_layout');
2833
this.height = size.height;
2934
this.width = size.width;
30-
this.scaledHeight = size.height * ZOOM;
31-
this.scaledWidth = size.width * ZOOM;
35+
this.zoom = this.height <= MAX_HEIGHT_PX ? DEFAULT_ZOOM : 1;
36+
this.scaledHeight = size.height * this.zoom;
37+
this.scaledWidth = size.width * this.zoom;
3238

3339
this.selectors = { ...DEFAULT_SELECTORS, ...selectors };
3440
}
@@ -46,14 +52,14 @@ export class PreserveLayout extends BaseLayout implements Layout {
4652
}
4753

4854
public getBrowserZoom() {
49-
return ZOOM;
55+
return this.zoom;
5056
}
5157

5258
public getViewport() {
5359
return {
5460
height: this.height,
5561
width: this.width,
56-
zoom: ZOOM,
62+
zoom: this.zoom,
5763
};
5864
}
5965

0 commit comments

Comments
 (0)