/** * Copyright 2023 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 type Protocol from 'devtools-protocol'; import type {ClickOptions, ElementHandle} from '../api/ElementHandle.js'; import type {HTTPResponse} from '../api/HTTPResponse.js'; import type { Page, WaitForSelectorOptions, WaitTimeoutOptions, } from '../api/Page.js'; import type {DeviceRequestPrompt} from '../cdp/DeviceRequestPrompt.js'; import type {IsolatedWorldChart} from '../cdp/IsolatedWorld.js'; import type {PuppeteerLifeCycleEvent} from '../cdp/LifecycleWatcher.js'; import {EventEmitter, type EventType} from '../common/EventEmitter.js'; import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js'; import {transposeIterableHandle} from '../common/HandleIterator.js'; import {LazyArg} from '../common/LazyArg.js'; import type { Awaitable, EvaluateFunc, EvaluateFuncWith, HandleFor, NodeFor, } from '../common/types.js'; import { getPageContent, importFSPromises, withSourcePuppeteerURLIfNone, } from '../common/util.js'; import {assert} from '../util/assert.js'; import {throwIfDisposed} from '../util/decorators.js'; import type {CDPSession} from './CDPSession.js'; import type {KeyboardTypeOptions} from './Input.js'; import { FunctionLocator, type Locator, NodeLocator, } from './locators/locators.js'; import type {Realm} from './Realm.js'; /** * @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; /** * When to consider waiting succeeds. Given an array of event strings, waiting * is considered to be successful after all events have been fired. * * @defaultValue `'load'` */ waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[]; } /** * @public */ export interface GoToOptions extends WaitForOptions { /** * If provided, it will take preference over the referer header value set by * {@link Page.setExtraHTTPHeaders | page.setExtraHTTPHeaders()}. */ referer?: string; /** * If provided, it will take preference over the referer-policy header value * set by {@link Page.setExtraHTTPHeaders | page.setExtraHTTPHeaders()}. */ referrerPolicy?: string; } /** * @public */ export interface FrameWaitForFunctionOptions { /** * An interval at which the `pageFunction` is executed, defaults to `raf`. If * `polling` is a number, then it is treated as an interval in milliseconds at * which the function would be executed. If `polling` is a string, then it can * be one of the following values: * * - `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` * callback. This is the tightest polling mode which is suitable to observe * styling changes. * * - `mutation` - to execute `pageFunction` on every DOM mutation. */ polling?: 'raf' | 'mutation' | number; /** * Maximum time to wait in milliseconds. Defaults to `30000` (30 seconds). * Pass `0` to disable the timeout. Puppeteer's default timeout can be changed * using {@link Page.setDefaultTimeout}. */ timeout?: number; /** * A signal object that allows you to cancel a waitForFunction call. */ signal?: AbortSignal; } /** * @public */ export interface FrameAddScriptTagOptions { /** * URL of the script to be added. */ url?: string; /** * Path to a JavaScript file to be injected into the frame. * * @remarks * If `path` is a relative path, it is resolved relative to the current * working directory (`process.cwd()` in Node.js). */ path?: string; /** * JavaScript to be injected into the frame. */ content?: string; /** * Sets the `type` of the script. Use `module` in order to load an ES2015 module. */ type?: string; /** * Sets the `id` of the script. */ id?: string; } /** * @public */ export interface FrameAddStyleTagOptions { /** * the URL of the CSS file to be added. */ url?: string; /** * The path to a CSS file to be injected into the frame. * @remarks * If `path` is a relative path, it is resolved relative to the current * working directory (`process.cwd()` in Node.js). */ path?: string; /** * Raw CSS content to be injected into the frame. */ content?: string; } /** * @public */ export interface FrameEvents extends Record { /** @internal */ [FrameEvent.FrameNavigated]: Protocol.Page.NavigationType; /** @internal */ [FrameEvent.FrameSwapped]: undefined; /** @internal */ [FrameEvent.LifecycleEvent]: undefined; /** @internal */ [FrameEvent.FrameNavigatedWithinDocument]: undefined; /** @internal */ [FrameEvent.FrameDetached]: Frame; /** @internal */ [FrameEvent.FrameSwappedByActivation]: undefined; } /** * We use symbols to prevent external parties listening to these events. * They are internal to Puppeteer. * * @internal */ // eslint-disable-next-line @typescript-eslint/no-namespace export namespace FrameEvent { export const FrameNavigated = Symbol('Frame.FrameNavigated'); export const FrameSwapped = Symbol('Frame.FrameSwapped'); export const LifecycleEvent = Symbol('Frame.LifecycleEvent'); export const FrameNavigatedWithinDocument = Symbol( 'Frame.FrameNavigatedWithinDocument' ); export const FrameDetached = Symbol('Frame.FrameDetached'); export const FrameSwappedByActivation = Symbol( 'Frame.FrameSwappedByActivation' ); } /** * @internal */ export const throwIfDetached = throwIfDisposed(frame => { return `Attempted to use detached Frame '${frame._id}'.`; }); /** * Represents a DOM frame. * * To understand frames, you can think of frames as `