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, HandleFor,
NodeFor, NodeFor,
} from '../common/types.js'; } 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 type {WebWorker} from '../common/WebWorker.js';
import {assert} from '../util/assert.js'; import {assert} from '../util/assert.js';
@ -2083,6 +2083,31 @@ export class Page extends EventEmitter {
throw new Error('Not implemented'); 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 * @remarks
* Options object which might have the following properties: * Options object which might have the following properties:

View File

@ -91,7 +91,6 @@ import {
getExceptionMessage, getExceptionMessage,
getReadableAsBuffer, getReadableAsBuffer,
getReadableFromProtocolStream, getReadableFromProtocolStream,
importFSPromises,
isString, isString,
pageBindingInitString, pageBindingInitString,
releaseObject, releaseObject,
@ -1440,24 +1439,13 @@ export class CDPPage extends Page {
await this.setViewport(this.#viewport); await this.setViewport(this.#viewport);
} }
const buffer = if (options.encoding === 'base64') {
options.encoding === 'base64' return result.data;
? 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;
}
} }
const buffer = Buffer.from(result.data, 'base64');
await this._maybeWriteBufferToFile(options.path, buffer);
return buffer; return buffer;
function processClip(clip: ScreenshotClip): ScreenshotClip { function processClip(clip: ScreenshotClip): ScreenshotClip {

View File

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

View File

@ -22,6 +22,7 @@ import {HTTPResponse} from '../../api/HTTPResponse.js';
import { import {
Page as PageBase, Page as PageBase,
PageEmittedEvents, PageEmittedEvents,
ScreenshotOptions,
WaitForOptions, WaitForOptions,
} from '../../api/Page.js'; } from '../../api/Page.js';
import {isErrorLike} from '../../util/ErrorLike.js'; import {isErrorLike} from '../../util/ErrorLike.js';
@ -29,7 +30,7 @@ import {ConsoleMessage, ConsoleMessageLocation} from '../ConsoleMessage.js';
import {Handler} from '../EventEmitter.js'; import {Handler} from '../EventEmitter.js';
import {PDFOptions} from '../PDFOptions.js'; import {PDFOptions} from '../PDFOptions.js';
import {EvaluateFunc, HandleFor} from '../types.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 {Context, getBidiHandle} from './Context.js';
import {BidiSerializer} from './Serializer.js'; import {BidiSerializer} from './Serializer.js';
@ -226,20 +227,7 @@ export class Page extends PageBase {
const buffer = Buffer.from(result.data, 'base64'); const buffer = Buffer.from(result.data, 'base64');
try { await this._maybeWriteBufferToFile(path, buffer);
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;
}
return buffer; return buffer;
} }
@ -260,6 +248,37 @@ export class Page extends PageBase {
throw error; 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( function isConsoleLogEntry(