chore: add basic screenshot to BiDi (#9923)

This commit is contained in:
Nikolay Vitkov 2023-03-28 13:02:59 +02:00 committed by GitHub
parent 3936600ba9
commit 3866e462bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 34 deletions

View File

@ -58,7 +58,7 @@ import type {
HandleFor,
NodeFor,
} from '../common/types.js';
import {isNumber, isString} from '../common/util.js';
import {importFSPromises, isNumber, isString} from '../common/util.js';
import type {WebWorker} from '../common/WebWorker.js';
import {assert} from '../util/assert.js';
@ -2083,6 +2083,31 @@ export class Page extends EventEmitter {
throw new Error('Not implemented');
}
/**
* @internal
*/
async _maybeWriteBufferToFile(
path: string | undefined,
buffer: Buffer
): Promise<void> {
if (!path) {
return;
}
try {
const fs = await importFSPromises();
await fs.writeFile(path, buffer);
} catch (error) {
if (error instanceof TypeError) {
throw new Error(
'Can only pass a file path in a Node-like environment.'
);
}
throw error;
}
}
/**
* @remarks
* Options object which might have the following properties:

View File

@ -91,7 +91,6 @@ import {
getExceptionMessage,
getReadableAsBuffer,
getReadableFromProtocolStream,
importFSPromises,
isString,
pageBindingInitString,
releaseObject,
@ -1440,24 +1439,13 @@ export class CDPPage extends Page {
await this.setViewport(this.#viewport);
}
const buffer =
options.encoding === 'base64'
? result.data
: Buffer.from(result.data, 'base64');
if (options.path) {
try {
const fs = await importFSPromises();
await fs.writeFile(options.path, buffer);
} catch (error) {
if (error instanceof TypeError) {
throw new Error(
'Screenshots can only be written to a file path in a Node-like environment.'
);
}
throw error;
}
if (options.encoding === 'base64') {
return result.data;
}
const buffer = Buffer.from(result.data, 'base64');
await this._maybeWriteBufferToFile(options.path, buffer);
return buffer;
function processClip(clip: ScreenshotClip): ScreenshotClip {

View File

@ -59,6 +59,10 @@ interface Commands {
params: Bidi.BrowsingContext.PrintParameters;
returnType: Bidi.BrowsingContext.PrintResult;
};
'browsingContext.captureScreenshot': {
params: Bidi.BrowsingContext.CaptureScreenshotParameters;
returnType: Bidi.BrowsingContext.CaptureScreenshotResult;
};
'session.new': {
params: {capabilities?: Record<any, unknown>}; // TODO: Update Types in chromium bidi

View File

@ -22,6 +22,7 @@ import {HTTPResponse} from '../../api/HTTPResponse.js';
import {
Page as PageBase,
PageEmittedEvents,
ScreenshotOptions,
WaitForOptions,
} from '../../api/Page.js';
import {isErrorLike} from '../../util/ErrorLike.js';
@ -29,7 +30,7 @@ import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js';
import {Handler} from '../EventEmitter.js';
import {PDFOptions} from '../PDFOptions.js';
import {EvaluateFunc, HandleFor} from '../types.js';
import {debugError, importFSPromises, waitWithTimeout} from '../util.js';
import {debugError, waitWithTimeout} from '../util.js';
import {Context, getBidiHandle} from './Context.js';
import {BidiSerializer} from './Serializer.js';
@ -226,20 +227,7 @@ export class Page extends PageBase {
const buffer = Buffer.from(result.data, 'base64');
try {
if (path) {
const fs = await importFSPromises();
await fs.writeFile(path, buffer);
}
} catch (error) {
if (error instanceof TypeError) {
throw new Error(
'Can only pass a file path in a Node-like environment.'
);
}
throw error;
}
await this._maybeWriteBufferToFile(path, buffer);
return buffer;
}
@ -260,6 +248,37 @@ export class Page extends PageBase {
throw error;
}
}
override screenshot(
options: ScreenshotOptions & {encoding: 'base64'}
): Promise<string>;
override screenshot(
options?: ScreenshotOptions & {encoding?: 'binary'}
): never;
override async screenshot(
options: ScreenshotOptions = {}
): Promise<Buffer | string> {
const {path = undefined, encoding, ...args} = options;
if (Object.keys(args).length >= 1) {
throw new Error('BiDi only supports "encoding" and "path" options');
}
const {result} = await this.#context.connection.send(
'browsingContext.captureScreenshot',
{
context: this.#context._contextId,
}
);
if (encoding === 'base64') {
return result.data;
}
const buffer = Buffer.from(result.data, 'base64');
await this._maybeWriteBufferToFile(path, buffer);
return buffer;
}
}
function isConsoleLogEntry(