mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: emulate if captureBeyondViewport is false (#11525)
This commit is contained in:
parent
026172761b
commit
b6d1163f7f
@ -16,7 +16,7 @@ export interface Viewport
|
||||
| ----------------- | --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| deviceScaleFactor | <code>optional</code> | number | Specify device scale factor. See [devicePixelRatio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) for more info. | <code>1</code> |
|
||||
| hasTouch | <code>optional</code> | boolean | Specify if the viewport supports touch events. | <code>false</code> |
|
||||
| height | | number | The page height in pixels. | |
|
||||
| height | | number | The page height in CSS pixels. | |
|
||||
| isLandscape | <code>optional</code> | boolean | Specifies if the viewport is in landscape mode. | <code>false</code> |
|
||||
| isMobile | <code>optional</code> | boolean | Whether the <code>meta viewport</code> tag is taken into account. | <code>false</code> |
|
||||
| width | | number | The page width in pixels. | |
|
||||
| width | | number | The page width in CSS pixels. | |
|
||||
|
@ -85,6 +85,7 @@ import type {ScreenRecorder} from '../node/ScreenRecorder.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {guarded} from '../util/decorators.js';
|
||||
import {
|
||||
AsyncDisposableStack,
|
||||
asyncDisposeSymbol,
|
||||
DisposableStack,
|
||||
disposeSymbol,
|
||||
@ -2450,18 +2451,47 @@ export abstract class Page extends EventEmitter<PageEvents> {
|
||||
|
||||
setDefaultScreenshotOptions(options);
|
||||
|
||||
options.clip =
|
||||
options.clip && roundRectangle(normalizeRectangle(options.clip));
|
||||
|
||||
if (options.fullPage) {
|
||||
if (options.clip) {
|
||||
throw new Error("'clip' and 'fullPage' are exclusive");
|
||||
await using stack = new AsyncDisposableStack();
|
||||
if (options.clip) {
|
||||
if (options.fullPage) {
|
||||
throw new Error("'clip' and 'fullPage' are mutually exclusive");
|
||||
}
|
||||
|
||||
options.clip = roundRectangle(normalizeRectangle(options.clip));
|
||||
} else {
|
||||
if (options.fullPage) {
|
||||
// If `captureBeyondViewport` is `false`, then we set the viewport to
|
||||
// capture the full page. Note this may be affected by on-page CSS and
|
||||
// JavaScript.
|
||||
if (!options.captureBeyondViewport) {
|
||||
const scrollDimensions = await this.mainFrame()
|
||||
.isolatedRealm()
|
||||
.evaluate(() => {
|
||||
const element = document.documentElement;
|
||||
return {
|
||||
width: element.scrollWidth,
|
||||
height: element.scrollHeight,
|
||||
};
|
||||
});
|
||||
const viewport = this.viewport();
|
||||
await this.setViewport({
|
||||
...viewport,
|
||||
...scrollDimensions,
|
||||
});
|
||||
stack.defer(async () => {
|
||||
if (viewport) {
|
||||
await this.setViewport(viewport).catch(debugError);
|
||||
} else {
|
||||
await this.setViewport({
|
||||
width: 0,
|
||||
height: 0,
|
||||
}).catch(debugError);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
options.captureBeyondViewport = false;
|
||||
}
|
||||
} else if (
|
||||
!options.clip &&
|
||||
userOptions.captureBeyondViewport === undefined
|
||||
) {
|
||||
options.captureBeyondViewport = false;
|
||||
}
|
||||
|
||||
const data = await this._screenshot(options);
|
||||
|
@ -666,12 +666,20 @@ export class BidiPage extends Page {
|
||||
if (options.fromSurface !== undefined && !options.fromSurface) {
|
||||
throw new UnsupportedOperation(`BiDi does not support 'fromSurface'.`);
|
||||
}
|
||||
if (clip !== undefined && clip.scale !== undefined && clip.scale !== 1) {
|
||||
throw new UnsupportedOperation(
|
||||
`BiDi does not support 'scale' in 'clip'.`
|
||||
);
|
||||
}
|
||||
|
||||
let box: BoundingBox | undefined;
|
||||
if (clip) {
|
||||
if (captureBeyondViewport) {
|
||||
box = clip;
|
||||
} else {
|
||||
// The clip is always with respect to the document coordinates, so we
|
||||
// need to convert this to viewport coordinates when we aren't capturing
|
||||
// beyond the viewport.
|
||||
const [pageLeft, pageTop] = await this.evaluate(() => {
|
||||
if (!window.visualViewport) {
|
||||
throw new Error('window.visualViewport is not supported.');
|
||||
@ -689,12 +697,6 @@ export class BidiPage extends Page {
|
||||
}
|
||||
}
|
||||
|
||||
if (clip !== undefined && clip.scale !== undefined && clip.scale !== 1) {
|
||||
throw new UnsupportedOperation(
|
||||
`BiDi does not support 'scale' in 'clip'.`
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
result: {data},
|
||||
} = await this.#connection.send('browsingContext.captureScreenshot', {
|
||||
|
@ -1122,10 +1122,7 @@ export class CdpPage extends Page {
|
||||
format: type,
|
||||
...(optimizeForSpeed ? {optimizeForSpeed} : {}),
|
||||
...(quality !== undefined ? {quality: Math.round(quality)} : {}),
|
||||
clip: clip && {
|
||||
...clip,
|
||||
scale: clip.scale ?? 1,
|
||||
},
|
||||
...(clip ? {clip: {...clip, scale: clip.scale ?? 1}} : {}),
|
||||
...(!fromSurface ? {fromSurface} : {}),
|
||||
captureBeyondViewport,
|
||||
}
|
||||
|
@ -19,11 +19,17 @@
|
||||
*/
|
||||
export interface Viewport {
|
||||
/**
|
||||
* The page width in pixels.
|
||||
* The page width in CSS pixels.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*/
|
||||
width: number;
|
||||
/**
|
||||
* The page height in pixels.
|
||||
* The page height in CSS pixels.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*/
|
||||
height: number;
|
||||
/**
|
||||
@ -31,7 +37,7 @@ export interface Viewport {
|
||||
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio | devicePixelRatio} for more info.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will set the deviceScaleFactor to the system default.
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*
|
||||
* @defaultValue `1`
|
||||
*/
|
||||
|
@ -1157,24 +1157,12 @@
|
||||
"parameters": ["firefox"],
|
||||
"expectations": ["PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should clip clip bigger than the viewport without \"captureBeyondViewport\"",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["firefox"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should get screenshot bigger than the viewport",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should use scale for clip",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[stacktrace.spec] Stack trace *",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
@ -3371,24 +3359,12 @@
|
||||
"parameters": ["cdp", "chrome"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["firefox", "webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
@ -3409,6 +3385,7 @@
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should return base64",
|
||||
"comment": "Bisected to https://chromium.googlesource.com/chromium/src/+log/b8b95f5715b4bd2348e537b740048e4b6aa281b1..8026f46b0e73174f33834a26748107d1089a83bf",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "chrome"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
@ -3421,12 +3398,20 @@
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots",
|
||||
"comment": "Bisected to https://chromium.googlesource.com/chromium/src/+log/b8b95f5715b4bd2348e537b740048e4b6aa281b1..8026f46b0e73174f33834a26748107d1089a83bf",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox"],
|
||||
"parameters": ["cdp", "chrome"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots without captureBeyondViewport",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["firefox", "webDriverBiDi"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots",
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots without captureBeyondViewport",
|
||||
"comment": "Bisected to https://chromium.googlesource.com/chromium/src/+log/b8b95f5715b4bd2348e537b740048e4b6aa281b1..8026f46b0e73174f33834a26748107d1089a83bf",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "chrome"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
@ -3439,6 +3424,7 @@
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should work",
|
||||
"comment": "Bisected to https://chromium.googlesource.com/chromium/src/+log/b8b95f5715b4bd2348e537b740048e4b6aa281b1..8026f46b0e73174f33834a26748107d1089a83bf",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "chrome"],
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
@ -3762,15 +3748,39 @@
|
||||
"expectations": ["FAIL", "PASS"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Cdp should work in \"fromSurface: false\" mode",
|
||||
"platforms": ["darwin", "win32"],
|
||||
"parameters": ["cdp", "chrome", "headless"],
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Cdp should use scale for clip",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Cdp should work in \"fromSurface: false\" mode",
|
||||
"platforms": ["darwin"],
|
||||
"parameters": ["cdp", "chrome", "new-headless"],
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headful"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headful"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should clip clip bigger than the viewport without \"captureBeyondViewport\"",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
@ -3786,7 +3796,19 @@
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should use scale for clip",
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headful"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
},
|
||||
{
|
||||
"testIdPattern": "[screenshot.spec] Screenshots Page.screenshot should take fullPage screenshots without captureBeyondViewport",
|
||||
"platforms": ["darwin", "linux", "win32"],
|
||||
"parameters": ["cdp", "firefox", "headless"],
|
||||
"expectations": ["FAIL"]
|
||||
|
BIN
test/golden-chrome/screenshot-grid-fullpage-2.png
Normal file
BIN
test/golden-chrome/screenshot-grid-fullpage-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 KiB |
BIN
test/golden-firefox/screenshot-grid-fullpage-2.png
Normal file
BIN
test/golden-firefox/screenshot-grid-fullpage-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -18,7 +18,12 @@ import assert from 'assert';
|
||||
|
||||
import expect from 'expect';
|
||||
|
||||
import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
|
||||
import {
|
||||
getTestState,
|
||||
isHeadless,
|
||||
launch,
|
||||
setupTestBrowserHooks,
|
||||
} from './mocha-utils.js';
|
||||
|
||||
describe('Screenshots', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -47,22 +52,6 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-rect.png');
|
||||
});
|
||||
it('should use scale for clip', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
clip: {
|
||||
x: 50,
|
||||
y: 100,
|
||||
width: 150,
|
||||
height: 100,
|
||||
scale: 2,
|
||||
},
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-rect-scale2.png');
|
||||
});
|
||||
it('should get screenshot bigger than the viewport', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
await page.setViewport({width: 50, height: 50});
|
||||
@ -123,6 +112,18 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-grid-fullpage.png');
|
||||
});
|
||||
it('should take fullPage screenshots without captureBeyondViewport', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
fullPage: true,
|
||||
captureBeyondViewport: false,
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-grid-fullpage-2.png');
|
||||
expect(page.viewport()).toMatchObject({width: 500, height: 500});
|
||||
});
|
||||
it('should run in parallel in multiple pages', async () => {
|
||||
const {server, context} = await getTestState();
|
||||
|
||||
@ -371,6 +372,22 @@ describe('Screenshots', function () {
|
||||
});
|
||||
|
||||
describe('Cdp', () => {
|
||||
it('should use scale for clip', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
clip: {
|
||||
x: 50,
|
||||
y: 100,
|
||||
width: 150,
|
||||
height: 100,
|
||||
scale: 2,
|
||||
},
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-rect-scale2.png');
|
||||
});
|
||||
it('should allow transparency', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
@ -390,15 +407,18 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('white.jpg');
|
||||
});
|
||||
it('should work in "fromSurface: false" mode', async () => {
|
||||
const {page, server} = await getTestState();
|
||||
(!isHeadless ? it : it.skip)(
|
||||
'should work in "fromSurface: false" mode',
|
||||
async () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
fromSurface: false,
|
||||
});
|
||||
expect(screenshot).toBeDefined(); // toBeGolden('screenshot-fromsurface-false.png');
|
||||
});
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
fromSurface: false,
|
||||
});
|
||||
expect(screenshot).toBeDefined(); // toBeGolden('screenshot-fromsurface-false.png');
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user