diff --git a/docs/api/puppeteer.page.addstyletag_2.md b/docs/api/puppeteer.page.addstyletag_2.md new file mode 100644 index 00000000..ebc64045 --- /dev/null +++ b/docs/api/puppeteer.page.addstyletag_2.md @@ -0,0 +1,25 @@ +--- +sidebar_label: Page.addStyleTag_2 +--- + +# Page.addStyleTag() method + +**Signature:** + +```typescript +class Page { + addStyleTag( + options: FrameAddStyleTagOptions + ): Promise>; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ----------------------------------------------------------------- | ----------- | +| options | [FrameAddStyleTagOptions](./puppeteer.frameaddstyletagoptions.md) | | + +**Returns:** + +Promise<[ElementHandle](./puppeteer.elementhandle.md)<HTMLStyleElement \| HTMLLinkElement>> diff --git a/docs/api/puppeteer.page.md b/docs/api/puppeteer.page.md index b3f47b2f..abfc4da5 100644 --- a/docs/api/puppeteer.page.md +++ b/docs/api/puppeteer.page.md @@ -84,6 +84,7 @@ page.off('request', logRequest); | [addScriptTag(options)](./puppeteer.page.addscripttag.md) | | Adds a <script> tag into the page with the desired URL or content. | | [addStyleTag(options)](./puppeteer.page.addstyletag.md) | |

Adds a <link rel="stylesheet"> tag into the page with the desired URL or a <style type="text/css"> tag with the content.

Shortcut for .

| | [addStyleTag(options)](./puppeteer.page.addstyletag_1.md) | | | +| [addStyleTag(options)](./puppeteer.page.addstyletag_2.md) | | | | [authenticate(credentials)](./puppeteer.page.authenticate.md) | | Provide credentials for HTTP authentication. | | [bringToFront()](./puppeteer.page.bringtofront.md) | | Brings page to front (activates tab). | | [browser()](./puppeteer.page.browser.md) | | Get the browser the page belongs to. | diff --git a/src/api/Browser.ts b/src/api/Browser.ts index 24ffcdff..21cfdbbd 100644 --- a/src/api/Browser.ts +++ b/src/api/Browser.ts @@ -19,7 +19,7 @@ import {ChildProcess} from 'child_process'; import {Protocol} from 'devtools-protocol'; import {EventEmitter} from '../common/EventEmitter.js'; -import type {Page} from '../common/Page.js'; // TODO: move to ./api +import type {Page} from './Page.js'; // TODO: move to ./api import type {Target} from '../common/Target.js'; // TODO: move to ./api /** diff --git a/src/api/Page.ts b/src/api/Page.ts new file mode 100644 index 00000000..17f0abbe --- /dev/null +++ b/src/api/Page.ts @@ -0,0 +1,2587 @@ +/** + * Copyright 2017 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {Protocol} from 'devtools-protocol'; +import type {Readable} from 'stream'; +import type {Accessibility} from '../common/Accessibility.js'; +import type {Browser, BrowserContext} from './Browser.js'; +import type {ConsoleMessage} from '../common/ConsoleMessage.js'; +import type {Coverage} from '../common/Coverage.js'; +import type {Dialog} from '../common/Dialog.js'; +import type {ElementHandle} from '../common/ElementHandle.js'; +import {EventEmitter, Handler} from '../common/EventEmitter.js'; +import type {FileChooser} from '../common/FileChooser.js'; +import type { + Frame, + FrameAddScriptTagOptions, + FrameAddStyleTagOptions, + FrameWaitForFunctionOptions, +} from '../common/Frame.js'; +import type {HTTPRequest} from '../common/HTTPRequest.js'; +import type {HTTPResponse} from '../common/HTTPResponse.js'; +import type { + Keyboard, + Mouse, + MouseButton, + Touchscreen, +} from '../common/Input.js'; +import type {WaitForSelectorOptions} from '../common/IsolatedWorld.js'; +import type {JSHandle} from '../common/JSHandle.js'; +import type {PuppeteerLifeCycleEvent} from '../common/LifecycleWatcher.js'; +import type {Credentials, NetworkConditions} from '../common/NetworkManager.js'; +import type {PDFOptions} from '../common/PDFOptions.js'; +import type {Viewport} from '../common/PuppeteerViewport.js'; +import type {Target} from '../common/Target.js'; +import type {Tracing} from '../common/Tracing.js'; +import type {EvaluateFunc, HandleFor, NodeFor} from '../common/types.js'; +import type {WebWorker} from '../common/WebWorker.js'; + +/** + * @public + */ +export interface Metrics { + Timestamp?: number; + Documents?: number; + Frames?: number; + JSEventListeners?: number; + Nodes?: number; + LayoutCount?: number; + RecalcStyleCount?: number; + LayoutDuration?: number; + RecalcStyleDuration?: number; + ScriptDuration?: number; + TaskDuration?: number; + JSHeapUsedSize?: number; + JSHeapTotalSize?: number; +} + +/** + * @public + */ +export interface WaitTimeoutOptions { + /** + * Maximum wait time in milliseconds. Pass 0 to disable the timeout. + * + * The default value can be changed by using the + * {@link Page.setDefaultTimeout} method. + * + * @defaultValue `30000` + */ + timeout?: number; +} + +/** + * @public + */ +export interface WaitForOptions { + /** + * Maximum wait time in milliseconds. Pass 0 to disable the timeout. + * + * The default value can be changed by using the + * {@link Page.setDefaultTimeout} or {@link Page.setDefaultNavigationTimeout} + * methods. + * + * @defaultValue `30000` + */ + timeout?: number; + waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[]; +} + +/** + * @public + */ +export interface GeolocationOptions { + /** + * Latitude between `-90` and `90`. + */ + longitude: number; + /** + * Longitude between `-180` and `180`. + */ + latitude: number; + /** + * Optional non-negative accuracy value. + */ + accuracy?: number; +} + +/** + * @public + */ +export interface MediaFeature { + name: string; + value: string; +} + +/** + * @public + */ +export interface ScreenshotClip { + x: number; + y: number; + width: number; + height: number; + /** + * @defaultValue 1 + */ + scale?: number; +} + +/** + * @public + */ +export interface ScreenshotOptions { + /** + * @defaultValue `png` + */ + 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 + * relative to current working directory. If no path is provided, the image + * won't be saved to the disk. + */ + path?: string; + /** + * When `true`, takes a screenshot of the full page. + * @defaultValue `false` + */ + fullPage?: boolean; + /** + * An object which specifies the clipping region of the page. + */ + clip?: ScreenshotClip; + /** + * Quality of the image, between 0-100. Not applicable to `png` images. + */ + quality?: number; + /** + * Hides default white background and allows capturing screenshots with transparency. + * @defaultValue `false` + */ + omitBackground?: boolean; + /** + * Encoding of the image. + * @defaultValue `binary` + */ + encoding?: 'base64' | 'binary'; + /** + * Capture the screenshot beyond the viewport. + * @defaultValue `true` + */ + captureBeyondViewport?: boolean; + /** + * Capture the screenshot from the surface, rather than the view. + * @defaultValue `true` + */ + fromSurface?: boolean; +} + +/** + * All the events that a page instance may emit. + * + * @public + */ +export const enum PageEmittedEvents { + /** + * Emitted when the page closes. + * @eventProperty + */ + Close = 'close', + /** + * Emitted when JavaScript within the page calls one of console API methods, + * e.g. `console.log` or `console.dir`. Also emitted if the page throws an + * error or a warning. + * + * @remarks + * A `console` event provides a {@link ConsoleMessage} representing the + * console message that was logged. + * + * @example + * An example of handling `console` event: + * + * ```ts + * page.on('console', msg => { + * for (let i = 0; i < msg.args().length; ++i) + * console.log(`${i}: ${msg.args()[i]}`); + * }); + * page.evaluate(() => console.log('hello', 5, {foo: 'bar'})); + * ``` + */ + Console = 'console', + /** + * Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, + * `confirm` or `beforeunload`. Puppeteer can respond to the dialog via + * {@link Dialog.accept} or {@link Dialog.dismiss}. + */ + Dialog = 'dialog', + /** + * Emitted when the JavaScript + * {@link https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded | DOMContentLoaded } + * event is dispatched. + */ + DOMContentLoaded = 'domcontentloaded', + /** + * Emitted when the page crashes. Will contain an `Error`. + */ + Error = 'error', + /** Emitted when a frame is attached. Will contain a {@link Frame}. */ + FrameAttached = 'frameattached', + /** Emitted when a frame is detached. Will contain a {@link Frame}. */ + FrameDetached = 'framedetached', + /** + * Emitted when a frame is navigated to a new URL. Will contain a + * {@link Frame}. + */ + FrameNavigated = 'framenavigated', + /** + * Emitted when the JavaScript + * {@link https://developer.mozilla.org/en-US/docs/Web/Events/load | load} + * event is dispatched. + */ + Load = 'load', + /** + * Emitted when the JavaScript code makes a call to `console.timeStamp`. For + * the list of metrics see {@link Page.metrics | page.metrics}. + * + * @remarks + * Contains an object with two properties: + * + * - `title`: the title passed to `console.timeStamp` + * - `metrics`: objec containing metrics as key/value pairs. The values will + * be `number`s. + */ + Metrics = 'metrics', + /** + * Emitted when an uncaught exception happens within the page. Contains an + * `Error`. + */ + PageError = 'pageerror', + /** + * Emitted when the page opens a new tab or window. + * + * Contains a {@link Page} corresponding to the popup window. + * + * @example + * + * ```ts + * const [popup] = await Promise.all([ + * new Promise(resolve => page.once('popup', resolve)), + * page.click('a[target=_blank]'), + * ]); + * ``` + * + * ```ts + * const [popup] = await Promise.all([ + * new Promise(resolve => page.once('popup', resolve)), + * page.evaluate(() => window.open('https://example.com')), + * ]); + * ``` + */ + Popup = 'popup', + /** + * Emitted when a page issues a request and contains a {@link HTTPRequest}. + * + * @remarks + * The object is readonly. See {@link Page.setRequestInterception} for + * intercepting and mutating requests. + */ + Request = 'request', + /** + * Emitted when a request ended up loading from cache. Contains a + * {@link HTTPRequest}. + * + * @remarks + * For certain requests, might contain undefined. + * {@link https://crbug.com/750469} + */ + RequestServedFromCache = 'requestservedfromcache', + /** + * Emitted when a request fails, for example by timing out. + * + * Contains a {@link HTTPRequest}. + * + * @remarks + * HTTP Error responses, such as 404 or 503, are still successful responses + * from HTTP standpoint, so request will complete with `requestfinished` event + * and not with `requestfailed`. + */ + RequestFailed = 'requestfailed', + /** + * Emitted when a request finishes successfully. Contains a + * {@link HTTPRequest}. + */ + RequestFinished = 'requestfinished', + /** + * Emitted when a response is received. Contains a {@link HTTPResponse}. + */ + Response = 'response', + /** + * Emitted when a dedicated + * {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker} + * is spawned by the page. + */ + WorkerCreated = 'workercreated', + /** + * Emitted when a dedicated + * {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | WebWorker} + * is destroyed by the page. + */ + WorkerDestroyed = 'workerdestroyed', +} + +/** + * Denotes the objects received by callback functions for page events. + * + * See {@link PageEmittedEvents} for more detail on the events and when they are + * emitted. + * + * @public + */ +export interface PageEventObject { + close: never; + console: ConsoleMessage; + dialog: Dialog; + domcontentloaded: never; + error: Error; + frameattached: Frame; + framedetached: Frame; + framenavigated: Frame; + load: never; + metrics: {title: string; metrics: Metrics}; + pageerror: Error; + popup: Page; + request: HTTPRequest; + response: HTTPResponse; + requestfailed: HTTPRequest; + requestfinished: HTTPRequest; + requestservedfromcache: HTTPRequest; + workercreated: WebWorker; + workerdestroyed: WebWorker; +} + +/** + * Page provides methods to interact with a single tab or + * {@link https://developer.chrome.com/extensions/background_pages | extension background page} + * in Chromium. + * + * :::note + * + * One Browser instance might have multiple Page instances. + * + * ::: + * + * @example + * This example creates a page, navigates it to a URL, and then saves a screenshot: + * + * ```ts + * const puppeteer = require('puppeteer'); + * + * (async () => { + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.goto('https://example.com'); + * await page.screenshot({path: 'screenshot.png'}); + * await browser.close(); + * })(); + * ``` + * + * The Page class extends from Puppeteer's {@link EventEmitter} class and will + * emit various events which are documented in the {@link PageEmittedEvents} enum. + * + * @example + * This example logs a message for a single page `load` event: + * + * ```ts + * page.once('load', () => console.log('Page loaded!')); + * ``` + * + * To unsubscribe from events use the {@link Page.off} method: + * + * ```ts + * function logRequest(interceptedRequest) { + * console.log('A request was made:', interceptedRequest.url()); + * } + * page.on('request', logRequest); + * // Sometime later... + * page.off('request', logRequest); + * ``` + * + * @public + */ +export class Page extends EventEmitter { + #handlerMap = new WeakMap(); + + /** + * @internal + */ + constructor() { + super(); + } + + /** + * @returns `true` if drag events are being intercepted, `false` otherwise. + */ + isDragInterceptionEnabled(): boolean { + throw new Error('Not implemented'); + } + + /** + * @returns `true` if the page has JavaScript enabled, `false` otherwise. + */ + isJavaScriptEnabled(): boolean { + throw new Error('Not implemented'); + } + + /** + * Listen to page events. + * + * :::note + * + * This method exists to define event typings and handle proper wireup of + * cooperative request interception. Actual event listening and dispatching is + * delegated to {@link EventEmitter}. + * + * ::: + */ + override on( + eventName: K, + handler: (event: PageEventObject[K]) => void + ): EventEmitter { + if (eventName === 'request') { + const wrap = + this.#handlerMap.get(handler) || + ((event: HTTPRequest) => { + event.enqueueInterceptAction(() => { + return handler(event as PageEventObject[K]); + }); + }); + + this.#handlerMap.set(handler, wrap); + + return super.on(eventName, wrap); + } + return super.on(eventName, handler); + } + + override once( + eventName: K, + handler: (event: PageEventObject[K]) => void + ): EventEmitter { + // Note: this method only exists to define the types; we delegate the impl + // to EventEmitter. + return super.once(eventName, handler); + } + + override off( + eventName: K, + handler: (event: PageEventObject[K]) => void + ): EventEmitter { + if (eventName === 'request') { + handler = this.#handlerMap.get(handler) || handler; + } + + return super.off(eventName, handler); + } + + /** + * This method is typically coupled with an action that triggers file + * choosing. + * + * :::caution + * + * This must be called before the file chooser is launched. It will not return + * a currently active file chooser. + * + * ::: + * + * @remarks + * In non-headless Chromium, this method results in the native file picker + * dialog `not showing up` for the user. + * + * @example + * The following example clicks a button that issues a file chooser + * and then responds with `/tmp/myfile.pdf` as if a user has selected this file. + * + * ```ts + * const [fileChooser] = await Promise.all([ + * page.waitForFileChooser(), + * page.click('#upload-file-button'), + * // some button that triggers file selection + * ]); + * await fileChooser.accept(['/tmp/myfile.pdf']); + * ``` + */ + waitForFileChooser(options?: WaitTimeoutOptions): Promise; + waitForFileChooser(): Promise { + throw new Error('Not implemented'); + } + + /** + * Sets the page's geolocation. + * + * @remarks + * Consider using {@link BrowserContext.overridePermissions} to grant + * permissions for the page to read its geolocation. + * + * @example + * + * ```ts + * await page.setGeolocation({latitude: 59.95, longitude: 30.31667}); + * ``` + */ + async setGeolocation(options: GeolocationOptions): Promise; + async setGeolocation(): Promise { + throw new Error('Not implemented'); + } + + /** + * @returns A target this page was created from. + */ + target(): Target { + throw new Error('Not implemented'); + } + + /** + * Get the browser the page belongs to. + */ + browser(): Browser { + throw new Error('Not implemented'); + } + + /** + * Get the browser context that the page belongs to. + */ + browserContext(): BrowserContext { + throw new Error('Not implemented'); + } + + /** + * @returns The page's main frame. + * + * @remarks + * Page is guaranteed to have a main frame which persists during navigations. + */ + mainFrame(): Frame { + throw new Error('Not implemented'); + } + + get keyboard(): Keyboard { + throw new Error('Not implemented'); + } + + get touchscreen(): Touchscreen { + throw new Error('Not implemented'); + } + + get coverage(): Coverage { + throw new Error('Not implemented'); + } + + get tracing(): Tracing { + throw new Error('Not implemented'); + } + + get accessibility(): Accessibility { + throw new Error('Not implemented'); + } + + /** + * @returns An array of all frames attached to the page. + */ + frames(): Frame[] { + throw new Error('Not implemented'); + } + + /** + * @returns all of the dedicated {@link + * https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | + * WebWorkers} associated with the page. + * + * @remarks + * This does not contain ServiceWorkers + */ + workers(): WebWorker[] { + throw new Error('Not implemented'); + } + + /** + * Activating request interception enables {@link HTTPRequest.abort}, + * {@link HTTPRequest.continue} and {@link HTTPRequest.respond} methods. This + * provides the capability to modify network requests that are made by a page. + * + * Once request interception is enabled, every request will stall unless it's + * continued, responded or aborted; or completed using the browser cache. + * + * Enabling request interception disables page caching. + * + * See the + * {@link https://pptr.dev/next/guides/request-interception|Request interception guide} + * for more details. + * + * @example + * An example of a naïve request interceptor that aborts all image requests: + * + * ```ts + * const puppeteer = require('puppeteer'); + * (async () => { + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.setRequestInterception(true); + * page.on('request', interceptedRequest => { + * if ( + * interceptedRequest.url().endsWith('.png') || + * interceptedRequest.url().endsWith('.jpg') + * ) + * interceptedRequest.abort(); + * else interceptedRequest.continue(); + * }); + * await page.goto('https://example.com'); + * await browser.close(); + * })(); + * ``` + * + * @param value - Whether to enable request interception. + */ + async setRequestInterception(value: boolean): Promise; + async setRequestInterception(): Promise { + throw new Error('Not implemented'); + } + + /** + * @param enabled - Whether to enable drag interception. + * + * @remarks + * Activating drag interception enables the `Input.drag`, + * methods This provides the capability to capture drag events emitted + * on the page, which can then be used to simulate drag-and-drop. + */ + async setDragInterception(enabled: boolean): Promise; + async setDragInterception(): Promise { + throw new Error('Not implemented'); + } + + /** + * @param enabled - When `true`, enables offline mode for the page. + * @remarks + * NOTE: while this method sets the network connection to offline, it does + * not change the parameters used in [page.emulateNetworkConditions(networkConditions)] + * (#pageemulatenetworkconditionsnetworkconditions) + */ + setOfflineMode(enabled: boolean): Promise; + setOfflineMode(): Promise { + throw new Error('Not implemented'); + } + + /** + * @param networkConditions - Passing `null` disables network condition emulation. + * @example + * + * ```ts + * const puppeteer = require('puppeteer'); + * const slow3G = puppeteer.networkConditions['Slow 3G']; + * + * (async () => { + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.emulateNetworkConditions(slow3G); + * await page.goto('https://www.google.com'); + * // other actions... + * await browser.close(); + * })(); + * ``` + * + * @remarks + * NOTE: This does not affect WebSockets and WebRTC PeerConnections (see + * https://crbug.com/563644). To set the page offline, you can use + * [page.setOfflineMode(enabled)](#pagesetofflinemodeenabled). + */ + emulateNetworkConditions( + networkConditions: NetworkConditions | null + ): Promise; + emulateNetworkConditions(): Promise { + throw new Error('Not implemented'); + } + + /** + * This setting will change the default maximum navigation time for the + * following methods and related shortcuts: + * + * - {@link Page.goBack | page.goBack(options)} + * + * - {@link Page.goForward | page.goForward(options)} + * + * - {@link Page.goto | page.goto(url,options)} + * + * - {@link Page.reload | page.reload(options)} + * + * - {@link Page.setContent | page.setContent(html,options)} + * + * - {@link Page.waitForNavigation | page.waitForNavigation(options)} + * @param timeout - Maximum navigation time in milliseconds. + */ + setDefaultNavigationTimeout(timeout: number): void; + setDefaultNavigationTimeout(): void { + throw new Error('Not implemented'); + } + + /** + * @param timeout - Maximum time in milliseconds. + */ + setDefaultTimeout(timeout: number): void; + setDefaultTimeout(): void { + throw new Error('Not implemented'); + } + + /** + * @returns Maximum time in milliseconds. + */ + getDefaultTimeout(): number { + throw new Error('Not implemented'); + } + + /** + * Runs `document.querySelector` within the page. If no element matches the + * selector, the return value resolves to `null`. + * + * @param selector - A `selector` to query page for + * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector} + * to query page for. + */ + async $( + selector: Selector + ): Promise> | null>; + async $(): Promise + > | null> { + throw new Error('Not implemented'); + } + + /** + * The method runs `document.querySelectorAll` within the page. If no elements + * match the selector, the return value resolves to `[]`. + * @remarks + * Shortcut for {@link Frame.$$ | Page.mainFrame().$$(selector) }. + * @param selector - A `selector` to query page for + */ + async $$( + selector: Selector + ): Promise>>>; + async $$(): Promise< + Array>> + > { + throw new Error('Not implemented'); + } + + /** + * @remarks + * + * The only difference between {@link Page.evaluate | page.evaluate} and + * `page.evaluateHandle` is that `evaluateHandle` will return the value + * wrapped in an in-page object. + * + * If the function passed to `page.evaluteHandle` returns a Promise, the + * function will wait for the promise to resolve and return its value. + * + * You can pass a string instead of a function (although functions are + * recommended as they are easier to debug and use with TypeScript): + * + * @example + * + * ```ts + * const aHandle = await page.evaluateHandle('document'); + * ``` + * + * @example + * {@link JSHandle} instances can be passed as arguments to the `pageFunction`: + * + * ```ts + * const aHandle = await page.evaluateHandle(() => document.body); + * const resultHandle = await page.evaluateHandle( + * body => body.innerHTML, + * aHandle + * ); + * console.log(await resultHandle.jsonValue()); + * await resultHandle.dispose(); + * ``` + * + * Most of the time this function returns a {@link JSHandle}, + * but if `pageFunction` returns a reference to an element, + * you instead get an {@link ElementHandle} back: + * + * @example + * + * ```ts + * const button = await page.evaluateHandle(() => + * document.querySelector('button') + * ); + * // can call `click` because `button` is an `ElementHandle` + * await button.click(); + * ``` + * + * The TypeScript definitions assume that `evaluateHandle` returns + * a `JSHandle`, but if you know it's going to return an + * `ElementHandle`, pass it as the generic argument: + * + * ```ts + * const button = await page.evaluateHandle(...); + * ``` + * + * @param pageFunction - a function that is run within the page + * @param args - arguments to be passed to the pageFunction + */ + async evaluateHandle< + Params extends unknown[], + Func extends EvaluateFunc = EvaluateFunc + >( + pageFunction: Func | string, + ...args: Params + ): Promise>>>; + async evaluateHandle< + Params extends unknown[], + Func extends EvaluateFunc = EvaluateFunc + >(): Promise>>> { + throw new Error('Not implemented'); + } + + /** + * This method iterates the JavaScript heap and finds all objects with the + * given prototype. + * + * @example + * + * ```ts + * // Create a Map object + * await page.evaluate(() => (window.map = new Map())); + * // Get a handle to the Map object prototype + * const mapPrototype = await page.evaluateHandle(() => Map.prototype); + * // Query all map instances into an array + * const mapInstances = await page.queryObjects(mapPrototype); + * // Count amount of map objects in heap + * const count = await page.evaluate(maps => maps.length, mapInstances); + * await mapInstances.dispose(); + * await mapPrototype.dispose(); + * ``` + * + * @param prototypeHandle - a handle to the object prototype. + * @returns Promise which resolves to a handle to an array of objects with + * this prototype. + */ + async queryObjects( + prototypeHandle: JSHandle + ): Promise>; + async queryObjects(): Promise> { + throw new Error('Not implemented'); + } + + /** + * This method runs `document.querySelector` within the page and passes the + * result as the first argument to the `pageFunction`. + * + * @remarks + * + * If no element is found matching `selector`, the method will throw an error. + * + * If `pageFunction` returns a promise `$eval` will wait for the promise to + * resolve and then return its value. + * + * @example + * + * ```ts + * const searchValue = await page.$eval('#search', el => el.value); + * const preloadHref = await page.$eval('link[rel=preload]', el => el.href); + * const html = await page.$eval('.main-container', el => el.outerHTML); + * ``` + * + * If you are using TypeScript, you may have to provide an explicit type to the + * first argument of the `pageFunction`. + * By default it is typed as `Element`, but you may need to provide a more + * specific sub-type: + * + * @example + * + * ```ts + * // if you don't provide HTMLInputElement here, TS will error + * // as `value` is not on `Element` + * const searchValue = await page.$eval( + * '#search', + * (el: HTMLInputElement) => el.value + * ); + * ``` + * + * The compiler should be able to infer the return type + * from the `pageFunction` you provide. If it is unable to, you can use the generic + * type to tell the compiler what return type you expect from `$eval`: + * + * @example + * + * ```ts + * // The compiler can infer the return type in this case, but if it can't + * // or if you want to be more explicit, provide it as the generic type. + * const searchValue = await page.$eval( + * '#search', + * (el: HTMLInputElement) => el.value + * ); + * ``` + * + * @param selector - the + * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector} + * to query for + * @param pageFunction - the function to be evaluated in the page context. + * Will be passed the result of `document.querySelector(selector)` as its + * first argument. + * @param args - any additional arguments to pass through to `pageFunction`. + * + * @returns The result of calling `pageFunction`. If it returns an element it + * is wrapped in an {@link ElementHandle}, else the raw value itself is + * returned. + */ + async $eval< + Selector extends string, + Params extends unknown[], + Func extends EvaluateFunc< + [ElementHandle>, ...Params] + > = EvaluateFunc<[ElementHandle>, ...Params]> + >( + selector: Selector, + pageFunction: Func | string, + ...args: Params + ): Promise>>; + async $eval< + Selector extends string, + Params extends unknown[], + Func extends EvaluateFunc< + [ElementHandle>, ...Params] + > = EvaluateFunc<[ElementHandle>, ...Params]> + >(): Promise>> { + throw new Error('Not implemented'); + } + + /** + * This method runs `Array.from(document.querySelectorAll(selector))` within + * the page and passes the result as the first argument to the `pageFunction`. + * + * @remarks + * If `pageFunction` returns a promise `$$eval` will wait for the promise to + * resolve and then return its value. + * + * @example + * + * ```ts + * // get the amount of divs on the page + * const divCount = await page.$$eval('div', divs => divs.length); + * + * // get the text content of all the `.options` elements: + * const options = await page.$$eval('div > span.options', options => { + * return options.map(option => option.textContent); + * }); + * ``` + * + * If you are using TypeScript, you may have to provide an explicit type to the + * first argument of the `pageFunction`. + * By default it is typed as `Element[]`, but you may need to provide a more + * specific sub-type: + * + * @example + * + * ```ts + * // if you don't provide HTMLInputElement here, TS will error + * // as `value` is not on `Element` + * await page.$$eval('input', (elements: HTMLInputElement[]) => { + * return elements.map(e => e.value); + * }); + * ``` + * + * The compiler should be able to infer the return type + * from the `pageFunction` you provide. If it is unable to, you can use the generic + * type to tell the compiler what return type you expect from `$$eval`: + * + * @example + * + * ```ts + * // The compiler can infer the return type in this case, but if it can't + * // or if you want to be more explicit, provide it as the generic type. + * const allInputValues = await page.$$eval( + * 'input', + * (elements: HTMLInputElement[]) => elements.map(e => e.textContent) + * ); + * ``` + * + * @param selector - the + * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector} + * to query for + * @param pageFunction - the function to be evaluated in the page context. + * Will be passed the result of + * `Array.from(document.querySelectorAll(selector))` as its first argument. + * @param args - any additional arguments to pass through to `pageFunction`. + * + * @returns The result of calling `pageFunction`. If it returns an element it + * is wrapped in an {@link ElementHandle}, else the raw value itself is + * returned. + */ + async $$eval< + Selector extends string, + Params extends unknown[], + Func extends EvaluateFunc< + [Array>, ...Params] + > = EvaluateFunc<[Array>, ...Params]> + >( + selector: Selector, + pageFunction: Func | string, + ...args: Params + ): Promise>>; + async $$eval< + Selector extends string, + Params extends unknown[], + Func extends EvaluateFunc< + [Array>, ...Params] + > = EvaluateFunc<[Array>, ...Params]> + >(): Promise>> { + throw new Error('Not implemented'); + } + + /** + * The method evaluates the XPath expression relative to the page document as + * its context node. If there are no such elements, the method resolves to an + * empty array. + * + * @remarks + * Shortcut for {@link Frame.$x | Page.mainFrame().$x(expression) }. + * + * @param expression - Expression to evaluate + */ + async $x(expression: string): Promise>>; + async $x(): Promise>> { + throw new Error('Not implemented'); + } + + /** + * If no URLs are specified, this method returns cookies for the current page + * URL. If URLs are specified, only cookies for those URLs are returned. + */ + async cookies(...urls: string[]): Promise; + async cookies(): Promise { + throw new Error('Not implemented'); + } + + async deleteCookie( + ...cookies: Protocol.Network.DeleteCookiesRequest[] + ): Promise; + async deleteCookie(): Promise { + throw new Error('Not implemented'); + } + + /** + * @example + * + * ```ts + * await page.setCookie(cookieObject1, cookieObject2); + * ``` + */ + async setCookie(...cookies: Protocol.Network.CookieParam[]): Promise; + async setCookie(): Promise { + throw new Error('Not implemented'); + } + + /** + * Adds a `