UNPKG

puppeteer-core

Version:

A high-level API to control headless Chrome over the DevTools Protocol

208 lines (194 loc) 5.88 kB
/** * @license * Copyright 2023 Google Inc. * SPDX-License-Identifier: Apache-2.0 */ import type {TimeoutSettings} from '../common/TimeoutSettings.js'; import type {EvaluateFunc, HandleFor} from '../common/types.js'; import {TaskManager, WaitTask} from '../common/WaitTask.js'; import {disposeSymbol} from '../util/disposable.js'; import type {ElementHandle} from './ElementHandle.js'; import type {Environment} from './Environment.js'; import type {Extension} from './Extension.js'; import type {JSHandle} from './JSHandle.js'; /** * @public */ export abstract class Realm { /** @internal */ protected readonly timeoutSettings: TimeoutSettings; /** @internal */ readonly taskManager = new TaskManager(); /** @internal */ constructor(timeoutSettings: TimeoutSettings) { this.timeoutSettings = timeoutSettings; } /** @internal */ abstract get environment(): Environment; /** * Returns the origin that created the Realm. * For example, if the realm was created by an extension content script, * this will return the origin of the extension * (e.g., `chrome-extension://<extension-id>`). * * @experimental * @example * `chrome-extension://<chrome-extension-id>` */ abstract get origin(): string | undefined; /** * Returns the {@link Extension} that created this realm, if applicable. * This is typically populated when the realm was created by an extension * content script injected into a page. * * @returns A promise that resolves to the {@link Extension} * or `null` if not created by an extension. * @experimental */ abstract extension(): Promise<Extension | null>; /** @internal */ abstract adoptHandle<T extends JSHandle<Node>>(handle: T): Promise<T>; /** @internal */ abstract transferHandle<T extends JSHandle<Node>>(handle: T): Promise<T>; /** * Evaluates a function in the realm's context and returns a * {@link JSHandle} to the result. * * If the function passed to `realm.evaluateHandle` returns a Promise, * the method will wait for the promise to resolve and return its value. * * {@link JSHandle} instances can be passed as arguments to the function. * * @example * * ```ts * const aHandle = await realm.evaluateHandle(() => document.body); * const resultHandle = await realm.evaluateHandle( * body => body.innerHTML, * aHandle, * ); * ``` * * @param pageFunction - A function to be evaluated in the realm. * @param args - Arguments to be passed to the `pageFunction`. * @returns A promise that resolves to a {@link JSHandle} containing * the result. * @public */ abstract evaluateHandle< Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>, >( pageFunction: Func | string, ...args: Params ): Promise<HandleFor<Awaited<ReturnType<Func>>>>; /** * Evaluates a function in the realm's context and returns the * resulting value. * * If the function passed to `realm.evaluate` returns a Promise, * the method will wait for the promise to resolve and return its value. * * {@link JSHandle} instances can be passed as arguments to the function. * * @example * * ```ts * const result = await realm.evaluate(() => { * return Promise.resolve(8 * 7); * }); * console.log(result); // prints "56" * ``` * * @param pageFunction - A function to be evaluated in the realm. * @param args - Arguments to be passed to the `pageFunction`. * @returns A promise that resolves to the return value of the function. * @public */ abstract evaluate< Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>, >( pageFunction: Func | string, ...args: Params ): Promise<Awaited<ReturnType<Func>>>; /** * Waits for a function to return a truthy value when evaluated in * the realm's context. * * Arguments can be passed from Node.js to `pageFunction`. * * @example * * ```ts * const selector = '.foo'; * await realm.waitForFunction( * selector => !!document.querySelector(selector), * {}, * selector, * ); * ``` * * @param pageFunction - A function to evaluate in the realm. * @param options - Options for polling and timeouts. * @param args - Arguments to pass to the function. * @returns A promise that resolves when the function returns a truthy * value. * @public */ async waitForFunction< Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>, >( pageFunction: Func | string, options: { polling?: 'raf' | 'mutation' | number; timeout?: number; root?: ElementHandle<Node>; signal?: AbortSignal; } = {}, ...args: Params ): Promise<HandleFor<Awaited<ReturnType<Func>>>> { const { polling = 'raf', timeout = this.timeoutSettings.timeout(), root, signal, } = options; if (typeof polling === 'number' && polling < 0) { throw new Error('Cannot poll with non-positive interval'); } const waitTask = new WaitTask( this, { polling, root, timeout, signal, }, pageFunction as unknown as | ((...args: unknown[]) => Promise<Awaited<ReturnType<Func>>>) | string, ...args, ); return await waitTask.result; } /** @internal */ abstract adoptBackendNode(backendNodeId?: number): Promise<JSHandle<Node>>; /** @internal */ get disposed(): boolean { return this.#disposed; } #disposed = false; /** @internal */ dispose(): void { this.#disposed = true; this.taskManager.terminateAll( new Error('waitForFunction failed: frame got detached.'), ); } /** @internal */ [disposeSymbol](): void { this.dispose(); } }