diff --git a/docs/api.md b/docs/api.md index 4fd5f5b2673de..53eca17b1694a 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2177,7 +2177,7 @@ Shortcut for [page.mainFrame().executionContext().queryObjects(prototypeHandle)] - `options` <[Object]> Options object which might have the following properties: - `path` <[string]> The file path to save the image to. The screenshot type will be inferred from file extension. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). If no path is provided, the image won't be saved to the disk. - - `type` <[string]> Specify screenshot type, can be either `jpeg` or `png`. Defaults to 'png'. + - `type` <[string]> Specify screenshot type, can be either `jpeg`, `png` or `webp`. Defaults to 'png'. - `quality` <[number]> The quality of the image, between 0-100. Not applicable to `png` images. - `fullPage` <[boolean]> When true, takes a screenshot of the full scrollable page. Defaults to `false`. - `clip` <[Object]> An object which specifies clipping region of the page. Should have the following fields: diff --git a/src/common/Page.ts b/src/common/Page.ts index c7e7bcb8df095..9ebf8a3376e58 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -31,7 +31,7 @@ import { } from './FrameManager.js'; import { Keyboard, Mouse, Touchscreen, MouseButton } from './Input.js'; import { Tracing } from './Tracing.js'; -import { assert } from './assert.js'; +import { assert, assertNever } from './assert.js'; import { helper, debugError } from './helper.js'; import { Coverage } from './Coverage.js'; import { WebWorker } from './WebWorker.js'; @@ -157,7 +157,7 @@ export interface ScreenshotOptions { /** * @defaultValue 'png' */ - type?: 'png' | 'jpeg'; + type?: 'png' | 'jpeg' | 'webp'; /** * The file path to save the image to. The screenshot type will be inferred * from file extension. If path is a relative path, then it is resolved @@ -2560,10 +2560,10 @@ export class Page extends EventEmitter { // because it may be a 0-length file with no extension created beforehand // (i.e. as a temp file). if (options.type) { - assert( - options.type === 'png' || options.type === 'jpeg', - 'Unknown options.type value: ' + options.type - ); + const type = options.type; + if (type !== 'png' && type !== 'jpeg' && type !== 'webp') { + assertNever(type, 'Unknown options.type value: ' + type); + } screenshotType = options.type; } else if (options.path) { const filePath = options.path; @@ -2573,6 +2573,7 @@ export class Page extends EventEmitter { if (extension === 'png') screenshotType = 'png'; else if (extension === 'jpg' || extension === 'jpeg') screenshotType = 'jpeg'; + else if (extension === 'webp') screenshotType = 'webp'; assert( screenshotType, `Unsupported screenshot type for extension \`.${extension}\`` @@ -2643,7 +2644,7 @@ export class Page extends EventEmitter { } private async _screenshotTask( - format: 'png' | 'jpeg', + format: Protocol.Page.CaptureScreenshotRequestFormat, options?: ScreenshotOptions ): Promise { await this._client.send('Target.activateTarget', { @@ -2682,7 +2683,7 @@ export class Page extends EventEmitter { } } const shouldSetDefaultBackground = - options.omitBackground && format === 'png'; + options.omitBackground && (format === 'png' || format === 'webp'); if (shouldSetDefaultBackground) { await this._setTransparentBackgroundColor(); } diff --git a/src/common/assert.ts b/src/common/assert.ts index 6ba090ce26e85..97dcc4278316b 100644 --- a/src/common/assert.ts +++ b/src/common/assert.ts @@ -22,3 +22,7 @@ export const assert = (value: unknown, message?: string): void => { if (!value) throw new Error(message); }; + +export const assertNever = (value: never, message?: string): void => { + if (value) throw new Error(message); +}; diff --git a/test/screenshot.spec.ts b/test/screenshot.spec.ts index 223d6c4a5687e..f2a6adc6d5fe1 100644 --- a/test/screenshot.spec.ts +++ b/test/screenshot.spec.ts @@ -142,6 +142,17 @@ describe('Screenshots', function () { }); expect(screenshot).toBeGolden('white.jpg'); }); + itFailsFirefox('should work with webp', async () => { + const { page, server } = getTestState(); + + await page.setViewport({ width: 100, height: 100 }); + await page.goto(server.PREFIX + '/grid.html'); + const screenshot = await page.screenshot({ + type: 'webp', + }); + + expect(screenshot).toBeInstanceOf(Buffer); + }); it('should work with odd clip size on Retina displays', async () => { const { page } = getTestState();