From 79e11985ba44b72b1ad6b8cd861fe316f1945e64 Mon Sep 17 00:00:00 2001 From: Levi Pesin <35454228+LeviPesin@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:37:37 +1000 Subject: [PATCH] feat: add fromSurface option to page.screenshot (#8496) --- docs/api.md | 1 + src/common/Page.ts | 33 +++++++++++++++++++++++++++------ test/src/mocha-utils.ts | 11 +++++++++++ test/src/screenshot.spec.ts | 11 +++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/docs/api.md b/docs/api.md index 258896103ae67..b01304ff8a900 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2211,6 +2211,7 @@ Shortcut for [page.mainFrame().executionContext().queryObjects(prototypeHandle)] - `omitBackground` <[boolean]> Hides default white background and allows capturing screenshots with transparency. Defaults to `false`. - `encoding` <[string]> The encoding of the image, can be either `base64` or `binary`. Defaults to `binary`. - `captureBeyondViewport` <[boolean]> When true, captures screenshot [beyond the viewport](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot). When false, falls back to old behaviour, and cuts the screenshot by the viewport size. Defaults to `true`. + - `fromSurface` <[boolean]> When true, captures screenshot [from the surface rather than the view](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot). When false, works only in headful mode and ignores page viewport (but not browser window's bounds). Defaults to `true`. - returns: <[Promise]<[string]|[Buffer]>> Promise which resolves to buffer or a base64 string (depending on the value of `encoding`) with captured screenshot. > **NOTE** Screenshots take at least 1/6 second on OS X. See https://crbug.com/741689 for discussion. diff --git a/src/common/Page.ts b/src/common/Page.ts index 2e5754e534387..e783e1063516f 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -197,10 +197,15 @@ export interface ScreenshotOptions { */ encoding?: 'base64' | 'binary'; /** - * If you need a screenshot bigger than the Viewport + * Capture the screenshot beyond the viewport. * @defaultValue true */ captureBeyondViewport?: boolean; + /** + * Capture the screenshot from the surface, rather than the view. + * @defaultValue true + */ + fromSurface?: boolean; } /** @@ -2759,7 +2764,7 @@ export class Page extends EventEmitter { * applicable to `png` images. * * - `fullPage` : When true, takes a screenshot of the full - * scrollable page. Defaults to `false` + * scrollable page. Defaults to `false`. * * - `clip` : An object which specifies clipping region of the page. * Should have the following fields:
@@ -2769,11 +2774,21 @@ export class Page extends EventEmitter { * - `height` : height of clipping area. * * - `omitBackground` : Hides default white background and allows - * capturing screenshots with transparency. Defaults to `false` + * capturing screenshots with transparency. Defaults to `false`. * * - `encoding` : The encoding of the image, can be either base64 or * binary. Defaults to `binary`. * + * - `captureBeyondViewport` : When true, captures screenshot + * {@link https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot + * | beyond the viewport}. When false, falls back to old behaviour, + * and cuts the screenshot by the viewport size. Defaults to `true`. + * + * - `fromSurface` : When true, captures screenshot + * {@link https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot + * | from the surface rather than the view}. When false, works only in + * headful mode and ignores page viewport (but not browser window's + * bounds). Defaults to `true`. * * NOTE: Screenshots take at least 1/6 second on OS X. See * {@link https://crbug.com/741689} for discussion. @@ -2881,9 +2896,14 @@ export class Page extends EventEmitter { targetId: this.#target._targetId, }); let clip = options.clip ? processClip(options.clip) : undefined; - let {captureBeyondViewport = true} = options; - captureBeyondViewport = - typeof captureBeyondViewport === 'boolean' ? captureBeyondViewport : true; + const captureBeyondViewport = + typeof options.captureBeyondViewport === 'boolean' + ? options.captureBeyondViewport + : true; + const fromSurface = + typeof options.fromSurface === 'boolean' + ? options.fromSurface + : undefined; if (options.fullPage) { const metrics = await this.#client.send('Page.getLayoutMetrics'); @@ -2923,6 +2943,7 @@ export class Page extends EventEmitter { quality: options.quality, clip, captureBeyondViewport, + fromSurface, }); if (shouldSetDefaultBackground) { await this.#resetDefaultBackgroundColor(); diff --git a/test/src/mocha-utils.ts b/test/src/mocha-utils.ts index b69e1178af8eb..ef915199e86ab 100644 --- a/test/src/mocha-utils.ts +++ b/test/src/mocha-utils.ts @@ -185,6 +185,17 @@ export const itHeadlessOnly = ( } }; +export const itHeadfulOnly = ( + description: string, + body: Mocha.Func +): Mocha.Test => { + if (isChrome && isHeadless === false) { + return it(description, body); + } else { + return xit(description, body); + } +}; + export const itFirefoxOnly = ( description: string, body: Mocha.Func diff --git a/test/src/screenshot.spec.ts b/test/src/screenshot.spec.ts index 51324765202a0..39c5c9a6b670c 100644 --- a/test/src/screenshot.spec.ts +++ b/test/src/screenshot.spec.ts @@ -20,6 +20,7 @@ import { setupTestBrowserHooks, setupTestPageAndContextHooks, itFailsFirefox, + itHeadfulOnly, } from './mocha-utils.js'; describe('Screenshots', function () { @@ -188,6 +189,16 @@ describe('Screenshots', function () { 'screenshot-sanity.png' ); }); + itHeadfulOnly('should work in "fromSurface: false" mode', async () => { + const {page, server} = 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'); + }); }); describe('ElementHandle.screenshot', function () {