UNPKG

puppeteer-core

Version:

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

1,009 lines 55.4 kB
/** * 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. */ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _CDPPage_instances, _CDPPage_closed, _CDPPage_client, _CDPPage_target, _CDPPage_keyboard, _CDPPage_mouse, _CDPPage_timeoutSettings, _CDPPage_touchscreen, _CDPPage_accessibility, _CDPPage_frameManager, _CDPPage_emulationManager, _CDPPage_tracing, _CDPPage_pageBindings, _CDPPage_coverage, _CDPPage_javascriptEnabled, _CDPPage_viewport, _CDPPage_screenshotTaskQueue, _CDPPage_workers, _CDPPage_fileChooserPromises, _CDPPage_disconnectPromise, _CDPPage_userDragInterceptionEnabled, _CDPPage_onDetachedFromTarget, _CDPPage_onAttachedToTarget, _CDPPage_initialize, _CDPPage_onFileChooser, _CDPPage_onTargetCrashed, _CDPPage_onLogEntryAdded, _CDPPage_emitMetrics, _CDPPage_buildMetricsObject, _CDPPage_handleException, _CDPPage_onConsoleAPI, _CDPPage_onBindingCalled, _CDPPage_addConsoleMessage, _CDPPage_onDialog, _CDPPage_resetDefaultBackgroundColor, _CDPPage_setTransparentBackgroundColor, _CDPPage_sessionClosePromise, _CDPPage_go, _CDPPage_screenshotTask; import { Page, } from '../api/Page.js'; import { assert } from '../util/assert.js'; import { createDeferredPromise, } from '../util/DeferredPromise.js'; import { isErrorLike } from '../util/ErrorLike.js'; import { Accessibility } from './Accessibility.js'; import { CDPSessionEmittedEvents, isTargetClosedError, } from './Connection.js'; import { ConsoleMessage } from './ConsoleMessage.js'; import { Coverage } from './Coverage.js'; import { Dialog } from './Dialog.js'; import { EmulationManager } from './EmulationManager.js'; import { FileChooser } from './FileChooser.js'; import { FrameManager, FrameManagerEmittedEvents } from './FrameManager.js'; import { Keyboard, Mouse, Touchscreen } from './Input.js'; import { MAIN_WORLD } from './IsolatedWorlds.js'; import { NetworkManagerEmittedEvents, } from './NetworkManager.js'; import { _paperFormats } from './PDFOptions.js'; import { TimeoutSettings } from './TimeoutSettings.js'; import { Tracing } from './Tracing.js'; import { createJSHandle, debugError, evaluationString, getExceptionMessage, getReadableAsBuffer, getReadableFromProtocolStream, importFS, isNumber, isString, pageBindingDeliverErrorString, pageBindingDeliverErrorValueString, pageBindingDeliverResultString, pageBindingInitString, releaseObject, valueFromRemoteObject, waitForEvent, waitWithTimeout, } from './util.js'; import { WebWorker } from './WebWorker.js'; /** * @internal */ export class CDPPage extends Page { /** * @internal */ static async _create(client, target, ignoreHTTPSErrors, defaultViewport, screenshotTaskQueue) { const page = new CDPPage(client, target, ignoreHTTPSErrors, screenshotTaskQueue); await __classPrivateFieldGet(page, _CDPPage_instances, "m", _CDPPage_initialize).call(page); if (defaultViewport) { try { await page.setViewport(defaultViewport); } catch (err) { if (isErrorLike(err) && isTargetClosedError(err)) { debugError(err); } else { throw err; } } } return page; } /** * @internal */ constructor(client, target, ignoreHTTPSErrors, screenshotTaskQueue) { super(); _CDPPage_instances.add(this); _CDPPage_closed.set(this, false); _CDPPage_client.set(this, void 0); _CDPPage_target.set(this, void 0); _CDPPage_keyboard.set(this, void 0); _CDPPage_mouse.set(this, void 0); _CDPPage_timeoutSettings.set(this, new TimeoutSettings()); _CDPPage_touchscreen.set(this, void 0); _CDPPage_accessibility.set(this, void 0); _CDPPage_frameManager.set(this, void 0); _CDPPage_emulationManager.set(this, void 0); _CDPPage_tracing.set(this, void 0); _CDPPage_pageBindings.set(this, new Map()); _CDPPage_coverage.set(this, void 0); _CDPPage_javascriptEnabled.set(this, true); _CDPPage_viewport.set(this, void 0); _CDPPage_screenshotTaskQueue.set(this, void 0); _CDPPage_workers.set(this, new Map()); _CDPPage_fileChooserPromises.set(this, new Set()); _CDPPage_disconnectPromise.set(this, void 0); _CDPPage_userDragInterceptionEnabled.set(this, false); _CDPPage_onDetachedFromTarget.set(this, (target) => { var _a; const sessionId = (_a = target._session()) === null || _a === void 0 ? void 0 : _a.id(); const worker = __classPrivateFieldGet(this, _CDPPage_workers, "f").get(sessionId); if (!worker) { return; } __classPrivateFieldGet(this, _CDPPage_workers, "f").delete(sessionId); this.emit("workerdestroyed" /* PageEmittedEvents.WorkerDestroyed */, worker); }); _CDPPage_onAttachedToTarget.set(this, (createdTarget) => { __classPrivateFieldGet(this, _CDPPage_frameManager, "f").onAttachedToTarget(createdTarget); if (createdTarget._getTargetInfo().type === 'worker') { const session = createdTarget._session(); assert(session); const worker = new WebWorker(session, createdTarget.url(), __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_addConsoleMessage).bind(this), __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_handleException).bind(this)); __classPrivateFieldGet(this, _CDPPage_workers, "f").set(session.id(), worker); this.emit("workercreated" /* PageEmittedEvents.WorkerCreated */, worker); } if (createdTarget._session()) { __classPrivateFieldGet(this, _CDPPage_target, "f") ._targetManager() .addTargetInterceptor(createdTarget._session(), __classPrivateFieldGet(this, _CDPPage_onAttachedToTarget, "f")); } }); __classPrivateFieldSet(this, _CDPPage_client, client, "f"); __classPrivateFieldSet(this, _CDPPage_target, target, "f"); __classPrivateFieldSet(this, _CDPPage_keyboard, new Keyboard(client), "f"); __classPrivateFieldSet(this, _CDPPage_mouse, new Mouse(client, __classPrivateFieldGet(this, _CDPPage_keyboard, "f")), "f"); __classPrivateFieldSet(this, _CDPPage_touchscreen, new Touchscreen(client, __classPrivateFieldGet(this, _CDPPage_keyboard, "f")), "f"); __classPrivateFieldSet(this, _CDPPage_accessibility, new Accessibility(client), "f"); __classPrivateFieldSet(this, _CDPPage_frameManager, new FrameManager(client, this, ignoreHTTPSErrors, __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f")), "f"); __classPrivateFieldSet(this, _CDPPage_emulationManager, new EmulationManager(client), "f"); __classPrivateFieldSet(this, _CDPPage_tracing, new Tracing(client), "f"); __classPrivateFieldSet(this, _CDPPage_coverage, new Coverage(client), "f"); __classPrivateFieldSet(this, _CDPPage_screenshotTaskQueue, screenshotTaskQueue, "f"); __classPrivateFieldSet(this, _CDPPage_viewport, null, "f"); __classPrivateFieldGet(this, _CDPPage_target, "f") ._targetManager() .addTargetInterceptor(__classPrivateFieldGet(this, _CDPPage_client, "f"), __classPrivateFieldGet(this, _CDPPage_onAttachedToTarget, "f")); __classPrivateFieldGet(this, _CDPPage_target, "f") ._targetManager() .on("targetGone" /* TargetManagerEmittedEvents.TargetGone */, __classPrivateFieldGet(this, _CDPPage_onDetachedFromTarget, "f")); __classPrivateFieldGet(this, _CDPPage_frameManager, "f").on(FrameManagerEmittedEvents.FrameAttached, event => { return this.emit("frameattached" /* PageEmittedEvents.FrameAttached */, event); }); __classPrivateFieldGet(this, _CDPPage_frameManager, "f").on(FrameManagerEmittedEvents.FrameDetached, event => { return this.emit("framedetached" /* PageEmittedEvents.FrameDetached */, event); }); __classPrivateFieldGet(this, _CDPPage_frameManager, "f").on(FrameManagerEmittedEvents.FrameNavigated, event => { return this.emit("framenavigated" /* PageEmittedEvents.FrameNavigated */, event); }); const networkManager = __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager; networkManager.on(NetworkManagerEmittedEvents.Request, event => { return this.emit("request" /* PageEmittedEvents.Request */, event); }); networkManager.on(NetworkManagerEmittedEvents.RequestServedFromCache, event => { return this.emit("requestservedfromcache" /* PageEmittedEvents.RequestServedFromCache */, event); }); networkManager.on(NetworkManagerEmittedEvents.Response, event => { return this.emit("response" /* PageEmittedEvents.Response */, event); }); networkManager.on(NetworkManagerEmittedEvents.RequestFailed, event => { return this.emit("requestfailed" /* PageEmittedEvents.RequestFailed */, event); }); networkManager.on(NetworkManagerEmittedEvents.RequestFinished, event => { return this.emit("requestfinished" /* PageEmittedEvents.RequestFinished */, event); }); client.on('Page.domContentEventFired', () => { return this.emit("domcontentloaded" /* PageEmittedEvents.DOMContentLoaded */); }); client.on('Page.loadEventFired', () => { return this.emit("load" /* PageEmittedEvents.Load */); }); client.on('Runtime.consoleAPICalled', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onConsoleAPI).call(this, event); }); client.on('Runtime.bindingCalled', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onBindingCalled).call(this, event); }); client.on('Page.javascriptDialogOpening', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onDialog).call(this, event); }); client.on('Runtime.exceptionThrown', exception => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_handleException).call(this, exception.exceptionDetails); }); client.on('Inspector.targetCrashed', () => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onTargetCrashed).call(this); }); client.on('Performance.metrics', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_emitMetrics).call(this, event); }); client.on('Log.entryAdded', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onLogEntryAdded).call(this, event); }); client.on('Page.fileChooserOpened', event => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_onFileChooser).call(this, event); }); __classPrivateFieldGet(this, _CDPPage_target, "f")._isClosedPromise.then(() => { __classPrivateFieldGet(this, _CDPPage_target, "f") ._targetManager() .removeTargetInterceptor(__classPrivateFieldGet(this, _CDPPage_client, "f"), __classPrivateFieldGet(this, _CDPPage_onAttachedToTarget, "f")); __classPrivateFieldGet(this, _CDPPage_target, "f") ._targetManager() .off("targetGone" /* TargetManagerEmittedEvents.TargetGone */, __classPrivateFieldGet(this, _CDPPage_onDetachedFromTarget, "f")); this.emit("close" /* PageEmittedEvents.Close */); __classPrivateFieldSet(this, _CDPPage_closed, true, "f"); }); } /** * @internal */ _client() { return __classPrivateFieldGet(this, _CDPPage_client, "f"); } isDragInterceptionEnabled() { return __classPrivateFieldGet(this, _CDPPage_userDragInterceptionEnabled, "f"); } isJavaScriptEnabled() { return __classPrivateFieldGet(this, _CDPPage_javascriptEnabled, "f"); } waitForFileChooser(options = {}) { const needsEnable = __classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f").size === 0; const { timeout = __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout() } = options; const promise = createDeferredPromise({ message: `Waiting for \`FileChooser\` failed: ${timeout}ms exceeded`, timeout, }); __classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f").add(promise); let enablePromise; if (needsEnable) { enablePromise = __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.setInterceptFileChooserDialog', { enabled: true, }); } return Promise.all([promise, enablePromise]) .then(([result]) => { return result; }) .catch(error => { __classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f").delete(promise); throw error; }); } async setGeolocation(options) { const { longitude, latitude, accuracy = 0 } = options; if (longitude < -180 || longitude > 180) { throw new Error(`Invalid longitude "${longitude}": precondition -180 <= LONGITUDE <= 180 failed.`); } if (latitude < -90 || latitude > 90) { throw new Error(`Invalid latitude "${latitude}": precondition -90 <= LATITUDE <= 90 failed.`); } if (accuracy < 0) { throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`); } await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setGeolocationOverride', { longitude, latitude, accuracy, }); } target() { return __classPrivateFieldGet(this, _CDPPage_target, "f"); } browser() { return __classPrivateFieldGet(this, _CDPPage_target, "f").browser(); } browserContext() { return __classPrivateFieldGet(this, _CDPPage_target, "f").browserContext(); } mainFrame() { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame(); } get keyboard() { return __classPrivateFieldGet(this, _CDPPage_keyboard, "f"); } get touchscreen() { return __classPrivateFieldGet(this, _CDPPage_touchscreen, "f"); } get coverage() { return __classPrivateFieldGet(this, _CDPPage_coverage, "f"); } get tracing() { return __classPrivateFieldGet(this, _CDPPage_tracing, "f"); } get accessibility() { return __classPrivateFieldGet(this, _CDPPage_accessibility, "f"); } frames() { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").frames(); } workers() { return Array.from(__classPrivateFieldGet(this, _CDPPage_workers, "f").values()); } async setRequestInterception(value) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.setRequestInterception(value); } async setDragInterception(enabled) { __classPrivateFieldSet(this, _CDPPage_userDragInterceptionEnabled, enabled, "f"); return __classPrivateFieldGet(this, _CDPPage_client, "f").send('Input.setInterceptDrags', { enabled }); } setOfflineMode(enabled) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.setOfflineMode(enabled); } emulateNetworkConditions(networkConditions) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.emulateNetworkConditions(networkConditions); } setDefaultNavigationTimeout(timeout) { __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").setDefaultNavigationTimeout(timeout); } setDefaultTimeout(timeout) { __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").setDefaultTimeout(timeout); } getDefaultTimeout() { return __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout(); } async $(selector) { return this.mainFrame().$(selector); } async $$(selector) { return this.mainFrame().$$(selector); } async evaluateHandle(pageFunction, ...args) { const context = await this.mainFrame().executionContext(); return context.evaluateHandle(pageFunction, ...args); } async queryObjects(prototypeHandle) { const context = await this.mainFrame().executionContext(); assert(!prototypeHandle.disposed, 'Prototype JSHandle is disposed!'); const remoteObject = prototypeHandle.remoteObject(); assert(remoteObject.objectId, 'Prototype JSHandle must not be referencing primitive value'); const response = await context._client.send('Runtime.queryObjects', { prototypeObjectId: remoteObject.objectId, }); return createJSHandle(context, response.objects); } async $eval(selector, pageFunction, ...args) { return this.mainFrame().$eval(selector, pageFunction, ...args); } async $$eval(selector, pageFunction, ...args) { return this.mainFrame().$$eval(selector, pageFunction, ...args); } async $x(expression) { return this.mainFrame().$x(expression); } async cookies(...urls) { const originalCookies = (await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Network.getCookies', { urls: urls.length ? urls : [this.url()], })).cookies; const unsupportedCookieAttributes = ['priority']; const filterUnsupportedAttributes = (cookie) => { for (const attr of unsupportedCookieAttributes) { delete cookie[attr]; } return cookie; }; return originalCookies.map(filterUnsupportedAttributes); } async deleteCookie(...cookies) { const pageURL = this.url(); for (const cookie of cookies) { const item = Object.assign({}, cookie); if (!cookie.url && pageURL.startsWith('http')) { item.url = pageURL; } await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Network.deleteCookies', item); } } async setCookie(...cookies) { const pageURL = this.url(); const startsWithHTTP = pageURL.startsWith('http'); const items = cookies.map(cookie => { const item = Object.assign({}, cookie); if (!item.url && startsWithHTTP) { item.url = pageURL; } assert(item.url !== 'about:blank', `Blank page can not have cookie "${item.name}"`); assert(!String.prototype.startsWith.call(item.url || '', 'data:'), `Data URL page can not have cookie "${item.name}"`); return item; }); await this.deleteCookie(...items); if (items.length) { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Network.setCookies', { cookies: items }); } } async addScriptTag(options) { return this.mainFrame().addScriptTag(options); } async addStyleTag(options) { return this.mainFrame().addStyleTag(options); } async exposeFunction(name, pptrFunction) { if (__classPrivateFieldGet(this, _CDPPage_pageBindings, "f").has(name)) { throw new Error(`Failed to add page binding with name ${name}: window['${name}'] already exists!`); } let exposedFunction; switch (typeof pptrFunction) { case 'function': exposedFunction = pptrFunction; break; default: exposedFunction = pptrFunction.default; break; } __classPrivateFieldGet(this, _CDPPage_pageBindings, "f").set(name, exposedFunction); const expression = pageBindingInitString('exposedFun', name); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Runtime.addBinding', { name: name }); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.addScriptToEvaluateOnNewDocument', { source: expression, }); await Promise.all(this.frames().map(frame => { return frame.evaluate(expression).catch(debugError); })); } async authenticate(credentials) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.authenticate(credentials); } async setExtraHTTPHeaders(headers) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.setExtraHTTPHeaders(headers); } async setUserAgent(userAgent, userAgentMetadata) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.setUserAgent(userAgent, userAgentMetadata); } async metrics() { const response = await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Performance.getMetrics'); return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_buildMetricsObject).call(this, response.metrics); } url() { return this.mainFrame().url(); } async content() { return await __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame().content(); } async setContent(html, options = {}) { await __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame().setContent(html, options); } async goto(url, options = {}) { return await __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame().goto(url, options); } async reload(options) { const result = await Promise.all([ this.waitForNavigation(options), __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.reload'), ]); return result[0]; } async waitForNavigation(options = {}) { return await __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame().waitForNavigation(options); } async waitForRequest(urlOrPredicate, options = {}) { const { timeout = __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout() } = options; return waitForEvent(__classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager, NetworkManagerEmittedEvents.Request, async (request) => { if (isString(urlOrPredicate)) { return urlOrPredicate === request.url(); } if (typeof urlOrPredicate === 'function') { return !!(await urlOrPredicate(request)); } return false; }, timeout, __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_sessionClosePromise).call(this)); } async waitForResponse(urlOrPredicate, options = {}) { const { timeout = __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout() } = options; return waitForEvent(__classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager, NetworkManagerEmittedEvents.Response, async (response) => { if (isString(urlOrPredicate)) { return urlOrPredicate === response.url(); } if (typeof urlOrPredicate === 'function') { return !!(await urlOrPredicate(response)); } return false; }, timeout, __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_sessionClosePromise).call(this)); } async waitForNetworkIdle(options = {}) { const { idleTime = 500, timeout = __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout() } = options; const networkManager = __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager; let idleResolveCallback; const idlePromise = new Promise(resolve => { idleResolveCallback = resolve; }); let abortRejectCallback; const abortPromise = new Promise((_, reject) => { abortRejectCallback = reject; }); let idleTimer; const onIdle = () => { return idleResolveCallback(); }; const cleanup = () => { idleTimer && clearTimeout(idleTimer); abortRejectCallback(new Error('abort')); }; const evaluate = () => { idleTimer && clearTimeout(idleTimer); if (networkManager.numRequestsInProgress() === 0) { idleTimer = setTimeout(onIdle, idleTime); } }; evaluate(); const eventHandler = () => { evaluate(); return false; }; const listenToEvent = (event) => { return waitForEvent(networkManager, event, eventHandler, timeout, abortPromise); }; const eventPromises = [ listenToEvent(NetworkManagerEmittedEvents.Request), listenToEvent(NetworkManagerEmittedEvents.Response), ]; await Promise.race([ idlePromise, ...eventPromises, __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_sessionClosePromise).call(this), ]).then(r => { cleanup(); return r; }, error => { cleanup(); throw error; }); } async waitForFrame(urlOrPredicate, options = {}) { const { timeout = __classPrivateFieldGet(this, _CDPPage_timeoutSettings, "f").timeout() } = options; let predicate; if (isString(urlOrPredicate)) { predicate = (frame) => { return Promise.resolve(urlOrPredicate === frame.url()); }; } else { predicate = (frame) => { const value = urlOrPredicate(frame); if (typeof value === 'boolean') { return Promise.resolve(value); } return value; }; } const eventRace = Promise.race([ waitForEvent(__classPrivateFieldGet(this, _CDPPage_frameManager, "f"), FrameManagerEmittedEvents.FrameAttached, predicate, timeout, __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_sessionClosePromise).call(this)), waitForEvent(__classPrivateFieldGet(this, _CDPPage_frameManager, "f"), FrameManagerEmittedEvents.FrameNavigated, predicate, timeout, __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_sessionClosePromise).call(this)), ...this.frames().map(async (frame) => { if (await predicate(frame)) { return frame; } return await eventRace; }), ]); return eventRace; } async goBack(options = {}) { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_go).call(this, -1, options); } async goForward(options = {}) { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_go).call(this, +1, options); } async bringToFront() { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.bringToFront'); } async setJavaScriptEnabled(enabled) { if (__classPrivateFieldGet(this, _CDPPage_javascriptEnabled, "f") === enabled) { return; } __classPrivateFieldSet(this, _CDPPage_javascriptEnabled, enabled, "f"); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setScriptExecutionDisabled', { value: !enabled, }); } async setBypassCSP(enabled) { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.setBypassCSP', { enabled }); } async emulateMediaType(type) { assert(type === 'screen' || type === 'print' || (type !== null && type !== void 0 ? type : undefined) === undefined, 'Unsupported media type: ' + type); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setEmulatedMedia', { media: type || '', }); } async emulateCPUThrottling(factor) { assert(factor === null || factor >= 1, 'Throttling rate should be greater or equal to 1'); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setCPUThrottlingRate', { rate: factor !== null ? factor : 1, }); } async emulateMediaFeatures(features) { if (!features) { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setEmulatedMedia', {}); } if (Array.isArray(features)) { for (const mediaFeature of features) { const name = mediaFeature.name; assert(/^(?:prefers-(?:color-scheme|reduced-motion)|color-gamut)$/.test(name), 'Unsupported media feature: ' + name); } await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setEmulatedMedia', { features: features, }); } } async emulateTimezone(timezoneId) { try { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setTimezoneOverride', { timezoneId: timezoneId || '', }); } catch (error) { if (isErrorLike(error) && error.message.includes('Invalid timezone')) { throw new Error(`Invalid timezone ID: ${timezoneId}`); } throw error; } } async emulateIdleState(overrides) { if (overrides) { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setIdleOverride', { isUserActive: overrides.isUserActive, isScreenUnlocked: overrides.isScreenUnlocked, }); } else { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.clearIdleOverride'); } } async emulateVisionDeficiency(type) { const visionDeficiencies = new Set([ 'none', 'achromatopsia', 'blurredVision', 'deuteranopia', 'protanopia', 'tritanopia', ]); try { assert(!type || visionDeficiencies.has(type), `Unsupported vision deficiency: ${type}`); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setEmulatedVisionDeficiency', { type: type || 'none', }); } catch (error) { throw error; } } async setViewport(viewport) { const needsReload = await __classPrivateFieldGet(this, _CDPPage_emulationManager, "f").emulateViewport(viewport); __classPrivateFieldSet(this, _CDPPage_viewport, viewport, "f"); if (needsReload) { await this.reload(); } } viewport() { return __classPrivateFieldGet(this, _CDPPage_viewport, "f"); } async evaluate(pageFunction, ...args) { return __classPrivateFieldGet(this, _CDPPage_frameManager, "f").mainFrame().evaluate(pageFunction, ...args); } async evaluateOnNewDocument(pageFunction, ...args) { const source = evaluationString(pageFunction, ...args); await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.addScriptToEvaluateOnNewDocument', { source, }); } async setCacheEnabled(enabled = true) { await __classPrivateFieldGet(this, _CDPPage_frameManager, "f").networkManager.setCacheEnabled(enabled); } async screenshot(options = {}) { let screenshotType = "png" /* Protocol.Page.CaptureScreenshotRequestFormat.Png */; // options.type takes precedence over inferring the type from options.path // because it may be a 0-length file with no extension created beforehand // (i.e. as a temp file). if (options.type) { screenshotType = options.type; } else if (options.path) { const filePath = options.path; const extension = filePath .slice(filePath.lastIndexOf('.') + 1) .toLowerCase(); switch (extension) { case 'png': screenshotType = "png" /* Protocol.Page.CaptureScreenshotRequestFormat.Png */; break; case 'jpeg': case 'jpg': screenshotType = "jpeg" /* Protocol.Page.CaptureScreenshotRequestFormat.Jpeg */; break; case 'webp': screenshotType = "webp" /* Protocol.Page.CaptureScreenshotRequestFormat.Webp */; break; default: throw new Error(`Unsupported screenshot type for extension \`.${extension}\``); } } if (options.quality) { assert(screenshotType === "jpeg" /* Protocol.Page.CaptureScreenshotRequestFormat.Jpeg */ || screenshotType === "webp" /* Protocol.Page.CaptureScreenshotRequestFormat.Webp */, 'options.quality is unsupported for the ' + screenshotType + ' screenshots'); assert(typeof options.quality === 'number', 'Expected options.quality to be a number but found ' + typeof options.quality); assert(Number.isInteger(options.quality), 'Expected options.quality to be an integer'); assert(options.quality >= 0 && options.quality <= 100, 'Expected options.quality to be between 0 and 100 (inclusive), got ' + options.quality); } assert(!options.clip || !options.fullPage, 'options.clip and options.fullPage are exclusive'); if (options.clip) { assert(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' + typeof options.clip.x); assert(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' + typeof options.clip.y); assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' + typeof options.clip.width); assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' + typeof options.clip.height); assert(options.clip.width !== 0, 'Expected options.clip.width not to be 0.'); assert(options.clip.height !== 0, 'Expected options.clip.height not to be 0.'); } return __classPrivateFieldGet(this, _CDPPage_screenshotTaskQueue, "f").postTask(() => { return __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_screenshotTask).call(this, screenshotType, options); }); } async createPDFStream(options = {}) { const { scale = 1, displayHeaderFooter = false, headerTemplate = '', footerTemplate = '', printBackground = false, landscape = false, pageRanges = '', preferCSSPageSize = false, margin = {}, omitBackground = false, timeout = 30000, } = options; let paperWidth = 8.5; let paperHeight = 11; if (options.format) { const format = _paperFormats[options.format.toLowerCase()]; assert(format, 'Unknown paper format: ' + options.format); paperWidth = format.width; paperHeight = format.height; } else { paperWidth = convertPrintParameterToInches(options.width) || paperWidth; paperHeight = convertPrintParameterToInches(options.height) || paperHeight; } const marginTop = convertPrintParameterToInches(margin.top) || 0; const marginLeft = convertPrintParameterToInches(margin.left) || 0; const marginBottom = convertPrintParameterToInches(margin.bottom) || 0; const marginRight = convertPrintParameterToInches(margin.right) || 0; if (omitBackground) { await __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_setTransparentBackgroundColor).call(this); } const printCommandPromise = __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.printToPDF', { transferMode: 'ReturnAsStream', landscape, displayHeaderFooter, headerTemplate, footerTemplate, printBackground, scale, paperWidth, paperHeight, marginTop, marginBottom, marginLeft, marginRight, pageRanges, preferCSSPageSize, }); const result = await waitWithTimeout(printCommandPromise, 'Page.printToPDF', timeout); if (omitBackground) { await __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_resetDefaultBackgroundColor).call(this); } assert(result.stream, '`stream` is missing from `Page.printToPDF'); return getReadableFromProtocolStream(__classPrivateFieldGet(this, _CDPPage_client, "f"), result.stream); } async pdf(options = {}) { const { path = undefined } = options; const readable = await this.createPDFStream(options); const buffer = await getReadableAsBuffer(readable, path); assert(buffer, 'Could not create buffer'); return buffer; } async title() { return this.mainFrame().title(); } async close(options = { runBeforeUnload: undefined }) { const connection = __classPrivateFieldGet(this, _CDPPage_client, "f").connection(); assert(connection, 'Protocol error: Connection closed. Most likely the page has been closed.'); const runBeforeUnload = !!options.runBeforeUnload; if (runBeforeUnload) { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Page.close'); } else { await connection.send('Target.closeTarget', { targetId: __classPrivateFieldGet(this, _CDPPage_target, "f")._targetId, }); await __classPrivateFieldGet(this, _CDPPage_target, "f")._isClosedPromise; } } isClosed() { return __classPrivateFieldGet(this, _CDPPage_closed, "f"); } get mouse() { return __classPrivateFieldGet(this, _CDPPage_mouse, "f"); } click(selector, options = {}) { return this.mainFrame().click(selector, options); } focus(selector) { return this.mainFrame().focus(selector); } hover(selector) { return this.mainFrame().hover(selector); } select(selector, ...values) { return this.mainFrame().select(selector, ...values); } tap(selector) { return this.mainFrame().tap(selector); } type(selector, text, options) { return this.mainFrame().type(selector, text, options); } waitForTimeout(milliseconds) { return this.mainFrame().waitForTimeout(milliseconds); } async waitForSelector(selector, options = {}) { return await this.mainFrame().waitForSelector(selector, options); } waitForXPath(xpath, options = {}) { return this.mainFrame().waitForXPath(xpath, options); } waitForFunction(pageFunction, options = {}, ...args) { return this.mainFrame().waitForFunction(pageFunction, options, ...args); } } _CDPPage_closed = new WeakMap(), _CDPPage_client = new WeakMap(), _CDPPage_target = new WeakMap(), _CDPPage_keyboard = new WeakMap(), _CDPPage_mouse = new WeakMap(), _CDPPage_timeoutSettings = new WeakMap(), _CDPPage_touchscreen = new WeakMap(), _CDPPage_accessibility = new WeakMap(), _CDPPage_frameManager = new WeakMap(), _CDPPage_emulationManager = new WeakMap(), _CDPPage_tracing = new WeakMap(), _CDPPage_pageBindings = new WeakMap(), _CDPPage_coverage = new WeakMap(), _CDPPage_javascriptEnabled = new WeakMap(), _CDPPage_viewport = new WeakMap(), _CDPPage_screenshotTaskQueue = new WeakMap(), _CDPPage_workers = new WeakMap(), _CDPPage_fileChooserPromises = new WeakMap(), _CDPPage_disconnectPromise = new WeakMap(), _CDPPage_userDragInterceptionEnabled = new WeakMap(), _CDPPage_onDetachedFromTarget = new WeakMap(), _CDPPage_onAttachedToTarget = new WeakMap(), _CDPPage_instances = new WeakSet(), _CDPPage_initialize = async function _CDPPage_initialize() { try { await Promise.all([ __classPrivateFieldGet(this, _CDPPage_frameManager, "f").initialize(), __classPrivateFieldGet(this, _CDPPage_client, "f").send('Performance.enable'), __classPrivateFieldGet(this, _CDPPage_client, "f").send('Log.enable'), ]); } catch (err) { if (isErrorLike(err) && isTargetClosedError(err)) { debugError(err); } else { throw err; } } }, _CDPPage_onFileChooser = async function _CDPPage_onFileChooser(event) { if (!__classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f").size) { return; } const frame = __classPrivateFieldGet(this, _CDPPage_frameManager, "f").frame(event.frameId); assert(frame, 'This should never happen.'); // This is guaranteed to be an HTMLInputElement handle by the event. const handle = (await frame.worlds[MAIN_WORLD].adoptBackendNode(event.backendNodeId)); const fileChooser = new FileChooser(handle, event); for (const promise of __classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f")) { promise.resolve(fileChooser); } __classPrivateFieldGet(this, _CDPPage_fileChooserPromises, "f").clear(); }, _CDPPage_onTargetCrashed = function _CDPPage_onTargetCrashed() { this.emit('error', new Error('Page crashed!')); }, _CDPPage_onLogEntryAdded = function _CDPPage_onLogEntryAdded(event) { const { level, text, args, source, url, lineNumber } = event.entry; if (args) { args.map(arg => { return releaseObject(__classPrivateFieldGet(this, _CDPPage_client, "f"), arg); }); } if (source !== 'worker') { this.emit("console" /* PageEmittedEvents.Console */, new ConsoleMessage(level, text, [], [{ url, lineNumber }])); } }, _CDPPage_emitMetrics = function _CDPPage_emitMetrics(event) { this.emit("metrics" /* PageEmittedEvents.Metrics */, { title: event.title, metrics: __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_buildMetricsObject).call(this, event.metrics), }); }, _CDPPage_buildMetricsObject = function _CDPPage_buildMetricsObject(metrics) { const result = {}; for (const metric of metrics || []) { if (supportedMetrics.has(metric.name)) { result[metric.name] = metric.value; } } return result; }, _CDPPage_handleException = function _CDPPage_handleException(exceptionDetails) { const message = getExceptionMessage(exceptionDetails); const err = new Error(message); err.stack = ''; // Don't report clientside error with a node stack attached this.emit("pageerror" /* PageEmittedEvents.PageError */, err); }, _CDPPage_onConsoleAPI = async function _CDPPage_onConsoleAPI(event) { if (event.executionContextId === 0) { // DevTools protocol stores the last 1000 console messages. These // messages are always reported even for removed execution contexts. In // this case, they are marked with executionContextId = 0 and are // reported upon enabling Runtime agent. // // Ignore these messages since: // - there's no execution context we can use to operate with message // arguments // - these messages are reported before Puppeteer clients can subscribe // to the 'console' // page event. // // @see https://github.com/puppeteer/puppeteer/issues/3865 return; } const context = __classPrivateFieldGet(this, _CDPPage_frameManager, "f").executionContextById(event.executionContextId, __classPrivateFieldGet(this, _CDPPage_client, "f")); const values = event.args.map(arg => { return createJSHandle(context, arg); }); __classPrivateFieldGet(this, _CDPPage_instances, "m", _CDPPage_addConsoleMessage).call(this, event.type, values, event.stackTrace); }, _CDPPage_onBindingCalled = async function _CDPPage_onBindingCalled(event) { let payload; try { payload = JSON.parse(event.payload); } catch { // The binding was either called by something in the page or it was // called before our wrapper was initialized. return; } const { type, name, seq, args } = payload; if (type !== 'exposedFun' || !__classPrivateFieldGet(this, _CDPPage_pageBindings, "f").has(name)) { return; } let expression = null; try { const pageBinding = __classPrivateFieldGet(this, _CDPPage_pageBindings, "f").get(name); assert(pageBinding); const result = await pageBinding(...args); expression = pageBindingDeliverResultString(name, seq, result); } catch (error) { if (isErrorLike(error)) { expression = pageBindingDeliverErrorString(name, seq, error.message, error.stack); } else { expression = pageBindingDeliverErrorValueString(name, seq, error); } } __classPrivateFieldGet(this, _CDPPage_client, "f") .send('Runtime.evaluate', { expression, contextId: event.executionContextId, }) .catch(debugError); }, _CDPPage_addConsoleMessage = function _CDPPage_addConsoleMessage(eventType, args, stackTrace) { if (!this.listenerCount("console" /* PageEmittedEvents.Console */)) { args.forEach(arg => { return arg.dispose(); }); return; } const textTokens = []; for (const arg of args) { const remoteObject = arg.remoteObject(); if (remoteObject.objectId) { textTokens.push(arg.toString()); } else { textTokens.push(valueFromRemoteObject(remoteObject)); } } const stackTraceLocations = []; if (stackTrace) { for (const callFrame of stackTrace.callFrames) { stackTraceLocations.push({ url: callFrame.url, lineNumber: callFrame.lineNumber, columnNumber: callFrame.columnNumber, }); } } const message = new ConsoleMessage(eventType, textTokens.join(' '), args, stackTraceLocations); this.emit("console" /* PageEmittedEvents.Console */, message); }, _CDPPage_onDialog = function _CDPPage_onDialog(event) { let dialogType = null; const validDialogTypes = new Set([ 'alert', 'confirm', 'prompt', 'beforeunload', ]); if (validDialogTypes.has(event.type)) { dialogType = event.type; } assert(dialogType, 'Unknown javascript dialog type: ' + event.type); const dialog = new Dialog(__classPrivateFieldGet(this, _CDPPage_client, "f"), dialogType, event.message, event.defaultPrompt); this.emit("dialog" /* PageEmittedEvents.Dialog */, dialog); }, _CDPPage_resetDefaultBackgroundColor = /** * Resets default white background */ async function _CDPPage_resetDefaultBackgroundColor() { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setDefaultBackgroundColorOverride'); }, _CDPPage_setTransparentBackgroundColor = /** * Hides default white background */ async function _CDPPage_setTransparentBackgroundColor() { await __classPrivateFieldGet(this, _CDPPage_client, "f").send('Emulation.setDefaultBackgroundColorOverride', { color: { r: 0, g: 0, b: 0, a: 0 }, }); }, _CDPPage_sessionClosePromise = function _CDPPage_sessionClosePromise() { if (!__classPrivateFieldGet(this, _CDPPage_disconnectPromise, "f")) { __classPrivateFieldSet(this, _CDPPage_disconnectPromise, new Promise(fulfill => { return __classPrivateFieldGet(this, _CDPPage_client, "f").once(CDPSessionEmittedEvents.Disconnected, () => { return fulfill(new Error('Target closed')); }); }), "f"); } return __classPrivate