chore: move helper.js to util.js (#8510)

This commit is contained in:
jrandolf 2022-06-14 13:16:21 +02:00 committed by GitHub
parent 6efb660f4d
commit 0678343b53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 222 additions and 229 deletions

View File

@ -16,7 +16,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['mocha', '@typescript-eslint', 'unicorn', 'import'],
plugins: ['mocha', '@typescript-eslint', 'import'],
extends: ['plugin:prettier/recommended'],
@ -100,9 +100,6 @@ module.exports = {
// ensure we don't have any it.only or describe.only in prod
'mocha/no-exclusive-tests': 'error',
// enforce the variable in a catch block is named error
'unicorn/catch-error-name': 'error',
'no-restricted-imports': [
'error',
{
@ -173,15 +170,8 @@ module.exports = {
},
},
],
'@typescript-eslint/array-type': [
2,
{
default: 'array-simple',
},
],
// By default this is a warning but we want it to error.
'@typescript-eslint/explicit-module-boundary-types': 2,
'no-restricted-syntax': [
'error',
{

View File

@ -108,7 +108,6 @@
"eslint-plugin-mocha": "10.0.5",
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-tsdoc": "0.2.16",
"eslint-plugin-unicorn": "42.0.0",
"esprima": "4.0.1",
"expect": "25.2.7",
"husky": "8.0.1",

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import { helper } from './helper.js';
import { Target } from './Target.js';
import { EventEmitter } from './EventEmitter.js';
import { Connection, ConnectionEmittedEvents } from './Connection.js';
import { Protocol } from 'devtools-protocol';
import { Page } from './Page.js';
import { TaskQueue } from './TaskQueue.js';
import { ChildProcess } from 'child_process';
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { Connection, ConnectionEmittedEvents } from './Connection.js';
import { EventEmitter } from './EventEmitter.js';
import { waitWithTimeout } from './util.js';
import { Page } from './Page.js';
import { Viewport } from './PuppeteerViewport.js';
import { Target } from './Target.js';
import { TaskQueue } from './TaskQueue.js';
/**
* BrowserContext options.
@ -582,7 +582,7 @@ export class Browser extends EventEmitter {
try {
if (!timeout) return await targetPromise;
this.targets().forEach(check);
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
return await waitWithTimeout(targetPromise, 'target', timeout);
} finally {
this.off(BrowserEmittedEvents.TargetCreated, check);
this.off(BrowserEmittedEvents.TargetChanged, check);

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { debugError, isErrorLike } from '../common/helper.js';
import { debugError, isErrorLike } from './util.js';
import { isNode } from '../environment.js';
import { assert } from './assert.js';
import {

View File

@ -15,11 +15,16 @@
*/
import { assert } from './assert.js';
import { helper, debugError, PuppeteerEventListener } from './helper.js';
import {
addEventListener,
debugError,
PuppeteerEventListener,
} from './util.js';
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';
import { EVALUATION_SCRIPT_URL } from './ExecutionContext.js';
import { removeEventListeners } from './util.js';
/**
* @internal
@ -216,12 +221,12 @@ export class JSCoverage {
this.#scriptURLs.clear();
this.#scriptSources.clear();
this.#eventListeners = [
helper.addEventListener(
addEventListener(
this.#client,
'Debugger.scriptParsed',
this.#onScriptParsed.bind(this)
),
helper.addEventListener(
addEventListener(
this.#client,
'Runtime.executionContextsCleared',
this.#onExecutionContextsCleared.bind(this)
@ -274,7 +279,7 @@ export class JSCoverage {
this.#client.send('Debugger.disable'),
]);
helper.removeEventListeners(this.#eventListeners);
removeEventListeners(this.#eventListeners);
const coverage = [];
const profileResponse = result[0];
@ -321,12 +326,12 @@ export class CSSCoverage {
this.#stylesheetURLs.clear();
this.#stylesheetSources.clear();
this.#eventListeners = [
helper.addEventListener(
addEventListener(
this.#client,
'CSS.styleSheetAdded',
this.#onStyleSheet.bind(this)
),
helper.addEventListener(
addEventListener(
this.#client,
'Runtime.executionContextsCleared',
this.#onExecutionContextsCleared.bind(this)
@ -371,7 +376,7 @@ export class CSSCoverage {
this.#client.send('CSS.disable'),
this.#client.send('DOM.disable'),
]);
helper.removeEventListeners(this.#eventListeners);
removeEventListeners(this.#eventListeners);
// aggregate by styleSheetId
const styleSheetIdToCoverage = new Map();

View File

@ -28,7 +28,13 @@ import {
} from './EvalTypes.js';
import { ExecutionContext } from './ExecutionContext.js';
import { Frame, FrameManager } from './FrameManager.js';
import { debugError, helper } from './helper.js';
import {
debugError,
isNumber,
isString,
makePredicateString,
pageBindingInitString,
} from './util.js';
import { MouseButton } from './Input.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import {
@ -609,7 +615,7 @@ export class DOMWorld {
}
const bind = async (name: string) => {
const expression = helper.pageBindingInitString('internal', name);
const expression = pageBindingInitString('internal', name);
try {
// TODO: In theory, it would be enough to call this just once
await context._client.send('Runtime.addBinding', {
@ -725,7 +731,7 @@ export class DOMWorld {
}
const waitTaskOptions: WaitTaskOptions = {
domWorld: this,
predicateBody: helper.makePredicateString(predicate, queryOne),
predicateBody: makePredicateString(predicate, queryOne),
predicateAcceptsContextElement: true,
title,
polling,
@ -772,7 +778,7 @@ export class DOMWorld {
}
const waitTaskOptions: WaitTaskOptions = {
domWorld: this,
predicateBody: helper.makePredicateString(predicate),
predicateBody: makePredicateString(predicate),
predicateAcceptsContextElement: true,
title,
polling,
@ -853,12 +859,12 @@ export class WaitTask {
promise: Promise<JSHandle>;
constructor(options: WaitTaskOptions) {
if (helper.isString(options.polling))
if (isString(options.polling))
assert(
options.polling === 'raf' || options.polling === 'mutation',
'Unknown polling option: ' + options.polling
);
else if (helper.isNumber(options.polling))
else if (isNumber(options.polling))
assert(
options.polling > 0,
'Cannot poll with non-positive interval: ' + options.polling
@ -866,7 +872,7 @@ export class WaitTask {
else throw new Error('Unknown polling options: ' + options.polling);
function getPredicateBody(predicateBody: Function | string) {
if (helper.isString(predicateBody)) return `return (${predicateBody});`;
if (isString(predicateBody)) return `return (${predicateBody});`;
return `return (${predicateBody})(...args);`;
}

View File

@ -14,14 +14,19 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { helper } from './helper.js';
import { _createJSHandle, JSHandle, ElementHandle } from './JSHandle.js';
import { CDPSession } from './Connection.js';
import { DOMWorld } from './DOMWorld.js';
import { Frame } from './FrameManager.js';
import { Protocol } from 'devtools-protocol';
import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes.js';
import { Frame } from './FrameManager.js';
import {
getExceptionMessage,
isString,
valueFromRemoteObject,
} from './util.js';
import { ElementHandle, JSHandle, _createJSHandle } from './JSHandle.js';
/**
* @public
*/
@ -196,7 +201,7 @@ export class ExecutionContext {
): Promise<ReturnType> {
const suffix = `//# sourceURL=${EVALUATION_SCRIPT_URL}`;
if (helper.isString(pageFunction)) {
if (isString(pageFunction)) {
const contextId = this._contextId;
const expression = pageFunction;
const expressionWithSourceUrl = SOURCE_URL_REGEX.test(expression)
@ -215,11 +220,11 @@ export class ExecutionContext {
if (exceptionDetails)
throw new Error(
'Evaluation failed: ' + helper.getExceptionMessage(exceptionDetails)
'Evaluation failed: ' + getExceptionMessage(exceptionDetails)
);
return returnByValue
? helper.valueFromRemoteObject(remoteObject)
? valueFromRemoteObject(remoteObject)
: _createJSHandle(this, remoteObject);
}
@ -268,10 +273,10 @@ export class ExecutionContext {
await callFunctionOnPromise.catch(rewriteError);
if (exceptionDetails)
throw new Error(
'Evaluation failed: ' + helper.getExceptionMessage(exceptionDetails)
'Evaluation failed: ' + getExceptionMessage(exceptionDetails)
);
return returnByValue
? helper.valueFromRemoteObject(remoteObject)
? valueFromRemoteObject(remoteObject)
: _createJSHandle(this, remoteObject);
function convertArgument(

View File

@ -14,31 +14,31 @@
* limitations under the License.
*/
import { EventEmitter } from './EventEmitter.js';
import { Protocol } from 'devtools-protocol';
import { assert } from './assert.js';
import { helper, debugError, isErrorLike } from './helper.js';
import { ExecutionContext, EVALUATION_SCRIPT_URL } from './ExecutionContext.js';
import { CDPSession, Connection } from './Connection.js';
import { DOMWorld, WaitForSelectorOptions } from './DOMWorld.js';
import {
EvaluateFn,
EvaluateFnReturnType,
EvaluateHandleFn,
SerializableOrJSHandle,
UnwrapPromiseLike,
WrapElementHandle,
} from './EvalTypes.js';
import { EventEmitter } from './EventEmitter.js';
import { EVALUATION_SCRIPT_URL, ExecutionContext } from './ExecutionContext.js';
import { HTTPResponse } from './HTTPResponse.js';
import { MouseButton } from './Input.js';
import { ElementHandle, JSHandle } from './JSHandle.js';
import {
LifecycleWatcher,
PuppeteerLifeCycleEvent,
} from './LifecycleWatcher.js';
import { DOMWorld, WaitForSelectorOptions } from './DOMWorld.js';
import { NetworkManager } from './NetworkManager.js';
import { TimeoutSettings } from './TimeoutSettings.js';
import { Connection, CDPSession } from './Connection.js';
import { JSHandle, ElementHandle } from './JSHandle.js';
import { MouseButton } from './Input.js';
import { Page } from './Page.js';
import { HTTPResponse } from './HTTPResponse.js';
import { Protocol } from 'devtools-protocol';
import {
SerializableOrJSHandle,
EvaluateHandleFn,
WrapElementHandle,
EvaluateFn,
EvaluateFnReturnType,
UnwrapPromiseLike,
} from './EvalTypes.js';
import { TimeoutSettings } from './TimeoutSettings.js';
import { debugError, isErrorLike, isNumber, isString } from './util.js';
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
const xPathPattern = /^\(\/\/[^\)]+\)|^\/\//;
@ -1235,12 +1235,12 @@ export class Frame {
'waitFor is deprecated and will be removed in a future release. See https://github.com/puppeteer/puppeteer/issues/6214 for details and how to migrate your code.'
);
if (helper.isString(selectorOrFunctionOrTimeout)) {
if (isString(selectorOrFunctionOrTimeout)) {
const string = selectorOrFunctionOrTimeout;
if (xPathPattern.test(string)) return this.waitForXPath(string, options);
return this.waitForSelector(string, options);
}
if (helper.isNumber(selectorOrFunctionOrTimeout))
if (isNumber(selectorOrFunctionOrTimeout))
return new Promise((fulfill) =>
setTimeout(fulfill, selectorOrFunctionOrTimeout)
);

View File

@ -13,15 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import { assert } from './assert.js';
import { ProtocolError } from './Errors.js';
import { EventEmitter } from './EventEmitter.js';
import { Frame } from './FrameManager.js';
import { debugError, isString } from './util.js';
import { HTTPResponse } from './HTTPResponse.js';
import { assert } from './assert.js';
import { helper, debugError } from './helper.js';
import { Protocol } from 'devtools-protocol';
import { ProtocolError } from './Errors.js';
/**
* @public
@ -557,7 +556,7 @@ export class HTTPRequest {
this.#interceptionHandled = true;
const responseBody: Buffer | null =
response.body && helper.isString(response.body)
response.body && isString(response.body)
? Buffer.from(response.body)
: (response.body as Buffer) || null;

View File

@ -27,11 +27,16 @@ import {
} from './EvalTypes.js';
import { ExecutionContext } from './ExecutionContext.js';
import { Frame, FrameManager } from './FrameManager.js';
import { debugError, helper } from './helper.js';
import { MouseButton } from './Input.js';
import { Page, ScreenshotOptions } from './Page.js';
import { _getQueryHandlerAndSelector } from './QueryHandler.js';
import { KeyInput } from './USKeyboardLayout.js';
import {
debugError,
isString,
releaseObject,
valueFromRemoteObject,
} from './util.js';
/**
* @public
@ -268,9 +273,9 @@ export class JSHandle<HandleObjectType = unknown> {
returnByValue: true,
awaitPromise: true,
});
return helper.valueFromRemoteObject(response.result) as T;
return valueFromRemoteObject(response.result) as T;
}
return helper.valueFromRemoteObject(this.#remoteObject) as T;
return valueFromRemoteObject(this.#remoteObject) as T;
}
/**
@ -291,7 +296,7 @@ export class JSHandle<HandleObjectType = unknown> {
async dispose(): Promise<void> {
if (this.#disposed) return;
this.#disposed = true;
await helper.releaseObject(this.#client, this.#remoteObject);
await releaseObject(this.#client, this.#remoteObject);
}
/**
@ -304,7 +309,7 @@ export class JSHandle<HandleObjectType = unknown> {
const type = this.#remoteObject.subtype || this.#remoteObject.type;
return 'JSHandle@' + type;
}
return 'JSHandle:' + helper.valueFromRemoteObject(this.#remoteObject);
return 'JSHandle:' + valueFromRemoteObject(this.#remoteObject);
}
}
@ -784,7 +789,7 @@ export class ElementHandle<
async select(...values: string[]): Promise<string[]> {
for (const value of values) {
assert(
helper.isString(value),
isString(value),
'Values must be strings. Found value "' +
value +
'" of type "' +

View File

@ -15,7 +15,11 @@
*/
import { assert } from './assert.js';
import { helper, PuppeteerEventListener } from './helper.js';
import {
addEventListener,
PuppeteerEventListener,
removeEventListeners,
} from './util.js';
import { TimeoutError } from './Errors.js';
import {
FrameManager,
@ -114,7 +118,7 @@ export class LifecycleWatcher {
this.#frame = frame;
this.#timeout = timeout;
this.#eventListeners = [
helper.addEventListener(
addEventListener(
frameManager._client,
CDPSessionEmittedEvents.Disconnected,
this.#terminate.bind(
@ -122,32 +126,32 @@ export class LifecycleWatcher {
new Error('Navigation failed because browser has disconnected!')
)
),
helper.addEventListener(
addEventListener(
this.#frameManager,
FrameManagerEmittedEvents.LifecycleEvent,
this.#checkLifecycleComplete.bind(this)
),
helper.addEventListener(
addEventListener(
this.#frameManager,
FrameManagerEmittedEvents.FrameNavigatedWithinDocument,
this.#navigatedWithinDocument.bind(this)
),
helper.addEventListener(
addEventListener(
this.#frameManager,
FrameManagerEmittedEvents.FrameNavigated,
this.#navigated.bind(this)
),
helper.addEventListener(
addEventListener(
this.#frameManager,
FrameManagerEmittedEvents.FrameSwapped,
this.#frameSwapped.bind(this)
),
helper.addEventListener(
addEventListener(
this.#frameManager,
FrameManagerEmittedEvents.FrameDetached,
this.#onFrameDetached.bind(this)
),
helper.addEventListener(
addEventListener(
this.#frameManager.networkManager(),
NetworkManagerEmittedEvents.Request,
this.#onRequest.bind(this)
@ -257,7 +261,7 @@ export class LifecycleWatcher {
}
dispose(): void {
helper.removeEventListeners(this.#eventListeners);
removeEventListeners(this.#eventListeners);
this.#maximumTimer !== undefined && clearTimeout(this.#maximumTimer);
}
}

View File

@ -14,15 +14,15 @@
* limitations under the License.
*/
import { Protocol } from 'devtools-protocol';
import { ProtocolMapping } from 'devtools-protocol/types/protocol-mapping.js';
import { assert } from './assert.js';
import { EventEmitter } from './EventEmitter.js';
import { Frame } from './FrameManager.js';
import { assert } from './assert.js';
import { helper, debugError } from './helper.js';
import { Protocol } from 'devtools-protocol';
import { HTTPRequest } from './HTTPRequest.js';
import { HTTPResponse } from './HTTPResponse.js';
import { FetchRequestId, NetworkEventManager } from './NetworkEventManager.js';
import { debugError, isString } from './util.js';
/**
* @public
@ -151,7 +151,7 @@ export class NetworkManager extends EventEmitter {
for (const key of Object.keys(extraHTTPHeaders)) {
const value = extraHTTPHeaders[key];
assert(
helper.isString(value),
isString(value),
`Expected value of header "${key}" to be String, but "${typeof value}" is found.`
);
this.#extraHTTPHeaders[key.toLowerCase()] = value;

View File

@ -43,11 +43,28 @@ import {
FrameManager,
FrameManagerEmittedEvents,
} from './FrameManager.js';
import { debugError, helper, isErrorLike } from './helper.js';
import {
debugError,
evaluationString,
getExceptionMessage,
getReadableAsBuffer,
getReadableFromProtocolStream,
isErrorLike,
isNumber,
isString,
pageBindingDeliverErrorString,
pageBindingDeliverErrorValueString,
pageBindingDeliverResultString,
pageBindingInitString,
releaseObject,
valueFromRemoteObject,
waitForEvent,
waitWithTimeout,
} from './util.js';
import { HTTPRequest } from './HTTPRequest.js';
import { HTTPResponse } from './HTTPResponse.js';
import { Keyboard, Mouse, MouseButton, Touchscreen } from './Input.js';
import { _createJSHandle, ElementHandle, JSHandle } from './JSHandle.js';
import { ElementHandle, JSHandle, _createJSHandle } from './JSHandle.js';
import { PuppeteerLifeCycleEvent } from './LifecycleWatcher.js';
import {
Credentials,
@ -56,8 +73,8 @@ import {
} from './NetworkManager.js';
import {
LowerCasePaperFormat,
_paperFormats,
PDFOptions,
_paperFormats,
} from './PDFOptions.js';
import { Viewport } from './PuppeteerViewport.js';
import { Target } from './Target.js';
@ -703,16 +720,14 @@ export class Page extends EventEmitter {
let callback!: (value: FileChooser | PromiseLike<FileChooser>) => void;
const promise = new Promise<FileChooser>((x) => (callback = x));
this.#fileChooserInterceptors.add(callback);
return helper
.waitWithTimeout<FileChooser>(
promise,
'waiting for file chooser',
timeout
)
.catch((error) => {
this.#fileChooserInterceptors.delete(callback);
throw error;
});
return waitWithTimeout<FileChooser>(
promise,
'waiting for file chooser',
timeout
).catch((error) => {
this.#fileChooserInterceptors.delete(callback);
throw error;
});
}
/**
@ -780,7 +795,7 @@ export class Page extends EventEmitter {
#onLogEntryAdded(event: Protocol.Log.EntryAddedEvent): void {
const { level, text, args, source, url, lineNumber } = event.entry;
if (args) args.map((arg) => helper.releaseObject(this.#client, arg));
if (args) args.map((arg) => releaseObject(this.#client, arg));
if (source !== 'worker')
this.emit(
PageEmittedEvents.Console,
@ -1413,7 +1428,7 @@ export class Page extends EventEmitter {
this.#pageBindings.set(name, exposedFunction);
const expression = helper.pageBindingInitString('exposedFun', name);
const expression = pageBindingInitString('exposedFun', name);
await this.#client.send('Runtime.addBinding', { name: name });
await this.#client.send('Page.addScriptToEvaluateOnNewDocument', {
source: expression,
@ -1520,7 +1535,7 @@ export class Page extends EventEmitter {
}
#handleException(exceptionDetails: Protocol.Runtime.ExceptionDetails): void {
const message = helper.getExceptionMessage(exceptionDetails);
const message = getExceptionMessage(exceptionDetails);
const err = new Error(message);
err.stack = ''; // Don't report clientside error with a node stack attached
this.emit(PageEmittedEvents.PageError, err);
@ -1571,21 +1586,16 @@ export class Page extends EventEmitter {
const pageBinding = this.#pageBindings.get(name);
assert(pageBinding);
const result = await pageBinding(...args);
expression = helper.pageBindingDeliverResultString(name, seq, result);
expression = pageBindingDeliverResultString(name, seq, result);
} catch (error) {
if (isErrorLike(error))
expression = helper.pageBindingDeliverErrorString(
expression = pageBindingDeliverErrorString(
name,
seq,
error.message,
error.stack
);
else
expression = helper.pageBindingDeliverErrorValueString(
name,
seq,
error
);
else expression = pageBindingDeliverErrorValueString(name, seq, error);
}
this.#client
.send('Runtime.evaluate', {
@ -1608,7 +1618,7 @@ export class Page extends EventEmitter {
for (const arg of args) {
const remoteObject = arg._remoteObject;
if (remoteObject.objectId) textTokens.push(arg.toString());
else textTokens.push(helper.valueFromRemoteObject(remoteObject));
else textTokens.push(valueFromRemoteObject(remoteObject));
}
const stackTraceLocations = [];
if (stackTrace) {
@ -1882,12 +1892,11 @@ export class Page extends EventEmitter {
options: { timeout?: number } = {}
): Promise<HTTPRequest> {
const { timeout = this.#timeoutSettings.timeout() } = options;
return helper.waitForEvent(
return waitForEvent(
this.#frameManager.networkManager(),
NetworkManagerEmittedEvents.Request,
(request) => {
if (helper.isString(urlOrPredicate))
return urlOrPredicate === request.url();
if (isString(urlOrPredicate)) return urlOrPredicate === request.url();
if (typeof urlOrPredicate === 'function')
return !!urlOrPredicate(request);
return false;
@ -1929,12 +1938,11 @@ export class Page extends EventEmitter {
options: { timeout?: number } = {}
): Promise<HTTPResponse> {
const { timeout = this.#timeoutSettings.timeout() } = options;
return helper.waitForEvent(
return waitForEvent(
this.#frameManager.networkManager(),
NetworkManagerEmittedEvents.Response,
async (response) => {
if (helper.isString(urlOrPredicate))
return urlOrPredicate === response.url();
if (isString(urlOrPredicate)) return urlOrPredicate === response.url();
if (typeof urlOrPredicate === 'function')
return !!(await urlOrPredicate(response));
return false;
@ -1988,13 +1996,7 @@ export class Page extends EventEmitter {
};
const listenToEvent = (event: symbol) =>
helper.waitForEvent(
networkManager,
event,
eventHandler,
timeout,
abortPromise
);
waitForEvent(networkManager, event, eventHandler, timeout, abortPromise);
const eventPromises = [
listenToEvent(NetworkManagerEmittedEvents.Request),
@ -2041,7 +2043,7 @@ export class Page extends EventEmitter {
const { timeout = this.#timeoutSettings.timeout() } = options;
let predicate: (frame: Frame) => Promise<boolean>;
if (helper.isString(urlOrPredicate)) {
if (isString(urlOrPredicate)) {
predicate = (frame: Frame) =>
Promise.resolve(urlOrPredicate === frame.url());
} else {
@ -2055,14 +2057,14 @@ export class Page extends EventEmitter {
}
const eventRace: Promise<Frame> = Promise.race([
helper.waitForEvent(
waitForEvent(
this.#frameManager,
FrameManagerEmittedEvents.FrameAttached,
predicate,
timeout,
this.#sessionClosePromise()
),
helper.waitForEvent(
waitForEvent(
this.#frameManager,
FrameManagerEmittedEvents.FrameNavigated,
predicate,
@ -2605,7 +2607,7 @@ export class Page extends EventEmitter {
pageFunction: Function | string,
...args: unknown[]
): Promise<void> {
const source = helper.evaluationString(pageFunction, ...args);
const source = evaluationString(pageFunction, ...args);
await this.#client.send('Page.addScriptToEvaluateOnNewDocument', {
source,
});
@ -2919,7 +2921,7 @@ export class Page extends EventEmitter {
preferCSSPageSize,
});
const result = await helper.waitWithTimeout(
const result = await waitWithTimeout(
printCommandPromise,
'Page.printToPDF',
timeout
@ -2930,7 +2932,7 @@ export class Page extends EventEmitter {
}
assert(result.stream, '`stream` is missing from `Page.printToPDF');
return helper.getReadableFromProtocolStream(this.#client, result.stream);
return getReadableFromProtocolStream(this.#client, result.stream);
}
/**
@ -2940,7 +2942,7 @@ export class Page extends EventEmitter {
async pdf(options: PDFOptions = {}): Promise<Buffer> {
const { path = undefined } = options;
const readable = await this.createPDFStream(options);
const buffer = await helper.getReadableAsBuffer(readable, path);
const buffer = await getReadableAsBuffer(readable, path);
assert(buffer, 'Could not create buffer');
return buffer;
}
@ -3414,10 +3416,10 @@ function convertPrintParameterToInches(
): number | undefined {
if (typeof parameter === 'undefined') return undefined;
let pixels;
if (helper.isNumber(parameter)) {
if (isNumber(parameter)) {
// Treat numbers as pixel values to be aligned with phantom's paperSize.
pixels = parameter;
} else if (helper.isString(parameter)) {
} else if (isString(parameter)) {
const text = parameter;
let unit = text.substring(text.length - 2).toLowerCase();
let valueText = '';

View File

@ -14,7 +14,11 @@
* limitations under the License.
*/
import { assert } from './assert.js';
import { helper, isErrorLike } from './helper.js';
import {
getReadableAsBuffer,
getReadableFromProtocolStream,
isErrorLike,
} from './util.js';
import { CDPSession } from './Connection.js';
/**
@ -116,11 +120,11 @@ export class Tracing {
});
this.#client.once('Tracing.tracingComplete', async (event) => {
try {
const readable = await helper.getReadableFromProtocolStream(
const readable = await getReadableFromProtocolStream(
this.#client,
event.stream
);
const buffer = await helper.getReadableAsBuffer(readable, this.#path);
const buffer = await getReadableAsBuffer(readable, this.#path);
resolve(buffer ?? undefined);
} catch (error) {
if (isErrorLike(error)) {

View File

@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from './EventEmitter.js';
import { debugError } from './helper.js';
import { ExecutionContext } from './ExecutionContext.js';
import { JSHandle } from './JSHandle.js';
import { CDPSession } from './Connection.js';
import { Protocol } from 'devtools-protocol';
import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes.js';
import { CDPSession } from './Connection.js';
import { ConsoleMessageType } from './ConsoleMessage.js';
import { EvaluateHandleFn, SerializableOrJSHandle } from './EvalTypes.js';
import { EventEmitter } from './EventEmitter.js';
import { ExecutionContext } from './ExecutionContext.js';
import { debugError } from './util.js';
import { JSHandle } from './JSHandle.js';
/**
* @internal

View File

@ -25,7 +25,7 @@ import { CommonEventEmitter } from './EventEmitter.js';
export const debugError = debug('puppeteer:error');
function getExceptionMessage(
export function getExceptionMessage(
exceptionDetails: Protocol.Runtime.ExceptionDetails
): string {
if (exceptionDetails.exception)
@ -48,7 +48,7 @@ function getExceptionMessage(
return message;
}
function valueFromRemoteObject(
export function valueFromRemoteObject(
remoteObject: Protocol.Runtime.RemoteObject
): any {
assert(!remoteObject.objectId, 'Cannot extract value when objectId is given');
@ -74,7 +74,7 @@ function valueFromRemoteObject(
return remoteObject.value;
}
async function releaseObject(
export async function releaseObject(
client: CDPSession,
remoteObject: Protocol.Runtime.RemoteObject
): Promise<void> {
@ -88,16 +88,13 @@ async function releaseObject(
});
}
/**
* @public
*/
export interface PuppeteerEventListener {
emitter: CommonEventEmitter;
eventName: string | symbol;
handler: (...args: any[]) => void;
}
function addEventListener(
export function addEventListener(
emitter: CommonEventEmitter,
eventName: string | symbol,
handler: (...args: any[]) => void
@ -106,7 +103,7 @@ function addEventListener(
return { emitter, eventName, handler };
}
function removeEventListeners(
export function removeEventListeners(
listeners: Array<{
emitter: CommonEventEmitter;
eventName: string | symbol;
@ -118,15 +115,15 @@ function removeEventListeners(
listeners.length = 0;
}
function isString(obj: unknown): obj is string {
export const isString = (obj: unknown): obj is string => {
return typeof obj === 'string' || obj instanceof String;
}
};
function isNumber(obj: unknown): obj is number {
export const isNumber = (obj: unknown): obj is number => {
return typeof obj === 'number' || obj instanceof Number;
}
};
async function waitForEvent<T>(
export async function waitForEvent<T>(
emitter: CommonEventEmitter,
eventName: string | symbol,
predicate: (event: T) => Promise<boolean> | boolean,
@ -172,7 +169,10 @@ async function waitForEvent<T>(
return result;
}
function evaluationString(fun: Function | string, ...args: unknown[]): string {
export function evaluationString(
fun: Function | string,
...args: unknown[]
): string {
if (isString(fun)) {
assert(args.length === 0, 'Cannot evaluate a string with arguments');
return fun;
@ -186,7 +186,7 @@ function evaluationString(fun: Function | string, ...args: unknown[]): string {
return `(${fun})(${args.map(serializeArgument).join(',')})`;
}
function pageBindingInitString(type: string, name: string): string {
export function pageBindingInitString(type: string, name: string): string {
function addPageBinding(type: string, bindingName: string): void {
/* Cast window to any here as we're about to add properties to it
* via win[bindingName] which TypeScript doesn't like.
@ -213,7 +213,7 @@ function pageBindingInitString(type: string, name: string): string {
return evaluationString(addPageBinding, type, name);
}
function pageBindingDeliverResultString(
export function pageBindingDeliverResultString(
name: string,
seq: number,
result: unknown
@ -225,7 +225,7 @@ function pageBindingDeliverResultString(
return evaluationString(deliverResult, name, seq, result);
}
function pageBindingDeliverErrorString(
export function pageBindingDeliverErrorString(
name: string,
seq: number,
message: string,
@ -245,7 +245,7 @@ function pageBindingDeliverErrorString(
return evaluationString(deliverError, name, seq, message, stack);
}
function pageBindingDeliverErrorValueString(
export function pageBindingDeliverErrorValueString(
name: string,
seq: number,
value: unknown
@ -257,7 +257,7 @@ function pageBindingDeliverErrorValueString(
return evaluationString(deliverErrorValue, name, seq, value);
}
function makePredicateString(
export function makePredicateString(
predicate: Function,
predicateQueryHandler?: Function
): string {
@ -296,7 +296,7 @@ function makePredicateString(
})() `;
}
async function waitWithTimeout<T>(
export async function waitWithTimeout<T>(
promise: Promise<T>,
taskName: string,
timeout: number
@ -315,7 +315,7 @@ async function waitWithTimeout<T>(
}
}
async function getReadableAsBuffer(
export async function getReadableAsBuffer(
readable: Readable,
path?: string
): Promise<Buffer | null> {
@ -350,7 +350,7 @@ async function getReadableAsBuffer(
}
}
async function getReadableFromProtocolStream(
export async function getReadableFromProtocolStream(
client: CDPSession,
handle: string
): Promise<Readable> {
@ -395,23 +395,3 @@ export function isErrnoException(obj: unknown): obj is NodeJS.ErrnoException {
('errno' in obj || 'code' in obj || 'path' in obj || 'syscall' in obj)
);
}
export const helper = {
evaluationString,
pageBindingInitString,
pageBindingDeliverResultString,
pageBindingDeliverErrorString,
pageBindingDeliverErrorValueString,
makePredicateString,
getReadableAsBuffer,
getReadableFromProtocolStream,
waitWithTimeout,
waitForEvent,
isString,
isNumber,
addEventListener,
removeEventListeners,
valueFromRemoteObject,
getExceptionMessage,
releaseObject,
};

View File

@ -14,29 +14,28 @@
* limitations under the License.
*/
import { debug } from '../common/Debug.js';
import * as childProcess from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as readline from 'readline';
import removeFolder from 'rimraf';
import { promisify } from 'util';
import { assert } from '../common/assert.js';
import {
helper,
debugError,
PuppeteerEventListener,
isErrorLike,
isErrnoException,
} from '../common/helper.js';
import { LaunchOptions } from './LaunchOptions.js';
import { Connection } from '../common/Connection.js';
import { NodeWebSocketTransport as WebSocketTransport } from '../node/NodeWebSocketTransport.js';
import { PipeTransport } from './PipeTransport.js';
import { Product } from '../common/Product.js';
import { debug } from '../common/Debug.js';
import { TimeoutError } from '../common/Errors.js';
import {
debugError,
addEventListener,
isErrnoException,
isErrorLike,
PuppeteerEventListener,
removeEventListeners,
} from '../common/util.js';
import { Product } from '../common/Product.js';
import { NodeWebSocketTransport as WebSocketTransport } from '../node/NodeWebSocketTransport.js';
import { LaunchOptions } from './LaunchOptions.js';
import { PipeTransport } from './PipeTransport.js';
const removeFolderAsync = promisify(removeFolder);
const renameAsync = promisify(fs.rename);
@ -147,23 +146,21 @@ export class BrowserRunner {
}
});
});
this.#listeners = [
helper.addEventListener(process, 'exit', this.kill.bind(this)),
];
this.#listeners = [addEventListener(process, 'exit', this.kill.bind(this))];
if (handleSIGINT)
this.#listeners.push(
helper.addEventListener(process, 'SIGINT', () => {
addEventListener(process, 'SIGINT', () => {
this.kill();
process.exit(130);
})
);
if (handleSIGTERM)
this.#listeners.push(
helper.addEventListener(process, 'SIGTERM', this.close.bind(this))
addEventListener(process, 'SIGTERM', this.close.bind(this))
);
if (handleSIGHUP)
this.#listeners.push(
helper.addEventListener(process, 'SIGHUP', this.close.bind(this))
addEventListener(process, 'SIGHUP', this.close.bind(this))
);
}
@ -180,7 +177,7 @@ export class BrowserRunner {
}
// Cleanup this listener last, as that makes sure the full callback runs. If we
// perform this earlier, then the previous function calls would not happen.
helper.removeEventListeners(this.#listeners);
removeEventListeners(this.#listeners);
return this.#processClosing;
}
@ -232,7 +229,7 @@ export class BrowserRunner {
// Cleanup this listener last, as that makes sure the full callback runs. If we
// perform this earlier, then the previous function calls would not happen.
helper.removeEventListeners(this.#listeners);
removeEventListeners(this.#listeners);
}
async setupConnection(options: {
@ -277,12 +274,10 @@ function waitForWSEndpoint(
return new Promise((resolve, reject) => {
const listeners = [
helper.addEventListener(rl, 'line', onLine),
helper.addEventListener(rl, 'close', () => onClose()),
helper.addEventListener(browserProcess, 'exit', () => onClose()),
helper.addEventListener(browserProcess, 'error', (error) =>
onClose(error)
),
addEventListener(rl, 'line', onLine),
addEventListener(rl, 'close', () => onClose()),
addEventListener(browserProcess, 'exit', () => onClose()),
addEventListener(browserProcess, 'error', (error) => onClose(error)),
];
const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;
@ -322,7 +317,7 @@ function waitForWSEndpoint(
function cleanup(): void {
if (timeoutId) clearTimeout(timeoutId);
helper.removeEventListeners(listeners);
removeEventListeners(listeners);
}
});
}

View File

@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { assert } from '../common/assert.js';
import { ConnectionTransport } from '../common/ConnectionTransport.js';
import {
helper,
addEventListener,
debugError,
PuppeteerEventListener,
} from '../common/helper.js';
import { ConnectionTransport } from '../common/ConnectionTransport.js';
import { assert } from '../common/assert.js';
removeEventListeners,
} from '../common/util.js';
export class PipeTransport implements ConnectionTransport {
#pipeWrite: NodeJS.WritableStream;
@ -37,16 +38,14 @@ export class PipeTransport implements ConnectionTransport {
) {
this.#pipeWrite = pipeWrite;
this.#eventListeners = [
helper.addEventListener(pipeRead, 'data', (buffer) =>
this.#dispatch(buffer)
),
helper.addEventListener(pipeRead, 'close', () => {
addEventListener(pipeRead, 'data', (buffer) => this.#dispatch(buffer)),
addEventListener(pipeRead, 'close', () => {
if (this.onclose) {
this.onclose.call(null);
}
}),
helper.addEventListener(pipeRead, 'error', debugError),
helper.addEventListener(pipeWrite, 'error', debugError),
addEventListener(pipeRead, 'error', debugError),
addEventListener(pipeWrite, 'error', debugError),
];
}
@ -84,6 +83,6 @@ export class PipeTransport implements ConnectionTransport {
close(): void {
this.#isClosed = true;
helper.removeEventListeners(this.#eventListeners);
removeEventListeners(this.#eventListeners);
}
}

View File

@ -25,7 +25,7 @@ import {
Browser,
BrowserContext,
} from '../lib/cjs/puppeteer/common/Browser.js';
import { isErrorLike } from '../lib/cjs/puppeteer/common/helper.js';
import { isErrorLike } from '../lib/cjs/puppeteer/common/util.js';
import { Page } from '../lib/cjs/puppeteer/common/Page.js';
import { PuppeteerNode } from '../lib/cjs/puppeteer/node/Puppeteer.js';
import puppeteer from '../lib/cjs/puppeteer/puppeteer.js';