827 lines
24 KiB
JavaScript
827 lines
24 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.BindingCall = exports.Page = void 0;
|
|
|
|
var _events = require("./events");
|
|
|
|
var _utils = require("../utils/utils");
|
|
|
|
var _timeoutSettings = require("../utils/timeoutSettings");
|
|
|
|
var _serializers = require("../protocol/serializers");
|
|
|
|
var _accessibility = require("./accessibility");
|
|
|
|
var _channelOwner = require("./channelOwner");
|
|
|
|
var _consoleMessage = require("./consoleMessage");
|
|
|
|
var _dialog = require("./dialog");
|
|
|
|
var _download = require("./download");
|
|
|
|
var _elementHandle = require("./elementHandle");
|
|
|
|
var _worker = require("./worker");
|
|
|
|
var _frame = require("./frame");
|
|
|
|
var _input = require("./input");
|
|
|
|
var _jsHandle = require("./jsHandle");
|
|
|
|
var _network = require("./network");
|
|
|
|
var _fileChooser = require("./fileChooser");
|
|
|
|
var _buffer = require("buffer");
|
|
|
|
var _coverage = require("./coverage");
|
|
|
|
var _waiter = require("./waiter");
|
|
|
|
var _fs = _interopRequireDefault(require("fs"));
|
|
|
|
var _path = _interopRequireDefault(require("path"));
|
|
|
|
var _clientHelper = require("./clientHelper");
|
|
|
|
var _errors = require("../utils/errors");
|
|
|
|
var _video = require("./video");
|
|
|
|
var _artifact = require("./artifact");
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
/**
|
|
* Copyright 2017 Google Inc. All rights reserved.
|
|
* Modifications copyright (c) Microsoft Corporation.
|
|
*
|
|
* 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.
|
|
*/
|
|
class Page extends _channelOwner.ChannelOwner {
|
|
static from(page) {
|
|
return page._object;
|
|
}
|
|
|
|
static fromNullable(page) {
|
|
return page ? Page.from(page) : null;
|
|
}
|
|
|
|
constructor(parent, type, guid, initializer) {
|
|
super(parent, type, guid, initializer);
|
|
this._browserContext = void 0;
|
|
this._ownedContext = void 0;
|
|
this._mainFrame = void 0;
|
|
this._frames = new Set();
|
|
this._workers = new Set();
|
|
this._closed = false;
|
|
this._closedOrCrashedPromise = void 0;
|
|
this._viewportSize = void 0;
|
|
this._routes = [];
|
|
this.accessibility = void 0;
|
|
this.coverage = void 0;
|
|
this.keyboard = void 0;
|
|
this.mouse = void 0;
|
|
this._request = void 0;
|
|
this.touchscreen = void 0;
|
|
this._bindings = new Map();
|
|
this._timeoutSettings = void 0;
|
|
this._video = null;
|
|
this._opener = void 0;
|
|
this._browserContext = parent;
|
|
this._timeoutSettings = new _timeoutSettings.TimeoutSettings(this._browserContext._timeoutSettings);
|
|
this.accessibility = new _accessibility.Accessibility(this._channel);
|
|
this.keyboard = new _input.Keyboard(this);
|
|
this.mouse = new _input.Mouse(this);
|
|
this._request = this._browserContext._request;
|
|
this.touchscreen = new _input.Touchscreen(this);
|
|
this._mainFrame = _frame.Frame.from(initializer.mainFrame);
|
|
this._mainFrame._page = this;
|
|
|
|
this._frames.add(this._mainFrame);
|
|
|
|
this._viewportSize = initializer.viewportSize || null;
|
|
this._closed = initializer.isClosed;
|
|
this._opener = Page.fromNullable(initializer.opener);
|
|
|
|
this._channel.on('bindingCall', ({
|
|
binding
|
|
}) => this._onBinding(BindingCall.from(binding)));
|
|
|
|
this._channel.on('close', () => this._onClose());
|
|
|
|
this._channel.on('console', ({
|
|
message
|
|
}) => this.emit(_events.Events.Page.Console, _consoleMessage.ConsoleMessage.from(message)));
|
|
|
|
this._channel.on('crash', () => this._onCrash());
|
|
|
|
this._channel.on('dialog', ({
|
|
dialog
|
|
}) => {
|
|
const dialogObj = _dialog.Dialog.from(dialog);
|
|
|
|
if (!this.emit(_events.Events.Page.Dialog, dialogObj)) {
|
|
if (dialogObj.type() === 'beforeunload') dialog.accept({}).catch(() => {});else dialog.dismiss().catch(() => {});
|
|
}
|
|
});
|
|
|
|
this._channel.on('domcontentloaded', () => this.emit(_events.Events.Page.DOMContentLoaded, this));
|
|
|
|
this._channel.on('download', ({
|
|
url,
|
|
suggestedFilename,
|
|
artifact
|
|
}) => {
|
|
const artifactObject = _artifact.Artifact.from(artifact);
|
|
|
|
artifactObject._isRemote = !!this._browserContext._browser && !!this._browserContext._browser._remoteType;
|
|
this.emit(_events.Events.Page.Download, new _download.Download(this, url, suggestedFilename, artifactObject));
|
|
});
|
|
|
|
this._channel.on('fileChooser', ({
|
|
element,
|
|
isMultiple
|
|
}) => this.emit(_events.Events.Page.FileChooser, new _fileChooser.FileChooser(this, _elementHandle.ElementHandle.from(element), isMultiple)));
|
|
|
|
this._channel.on('frameAttached', ({
|
|
frame
|
|
}) => this._onFrameAttached(_frame.Frame.from(frame)));
|
|
|
|
this._channel.on('frameDetached', ({
|
|
frame
|
|
}) => this._onFrameDetached(_frame.Frame.from(frame)));
|
|
|
|
this._channel.on('load', () => this.emit(_events.Events.Page.Load, this));
|
|
|
|
this._channel.on('pageError', ({
|
|
error
|
|
}) => this.emit(_events.Events.Page.PageError, (0, _serializers.parseError)(error)));
|
|
|
|
this._channel.on('route', ({
|
|
route,
|
|
request
|
|
}) => this._onRoute(_network.Route.from(route), _network.Request.from(request)));
|
|
|
|
this._channel.on('video', ({
|
|
artifact
|
|
}) => {
|
|
const artifactObject = _artifact.Artifact.from(artifact);
|
|
|
|
this._forceVideo()._artifactReady(artifactObject);
|
|
});
|
|
|
|
this._channel.on('webSocket', ({
|
|
webSocket
|
|
}) => this.emit(_events.Events.Page.WebSocket, _network.WebSocket.from(webSocket)));
|
|
|
|
this._channel.on('worker', ({
|
|
worker
|
|
}) => this._onWorker(_worker.Worker.from(worker)));
|
|
|
|
this.coverage = new _coverage.Coverage(this._channel);
|
|
this._closedOrCrashedPromise = Promise.race([new Promise(f => this.once(_events.Events.Page.Close, f)), new Promise(f => this.once(_events.Events.Page.Crash, f))]);
|
|
}
|
|
|
|
_onFrameAttached(frame) {
|
|
frame._page = this;
|
|
|
|
this._frames.add(frame);
|
|
|
|
if (frame._parentFrame) frame._parentFrame._childFrames.add(frame);
|
|
this.emit(_events.Events.Page.FrameAttached, frame);
|
|
}
|
|
|
|
_onFrameDetached(frame) {
|
|
this._frames.delete(frame);
|
|
|
|
frame._detached = true;
|
|
if (frame._parentFrame) frame._parentFrame._childFrames.delete(frame);
|
|
this.emit(_events.Events.Page.FrameDetached, frame);
|
|
}
|
|
|
|
_onRoute(route, request) {
|
|
for (const routeHandler of this._routes) {
|
|
if (routeHandler.matches(request.url())) {
|
|
routeHandler.handle(route, request);
|
|
return;
|
|
}
|
|
}
|
|
|
|
this._browserContext._onRoute(route, request);
|
|
}
|
|
|
|
async _onBinding(bindingCall) {
|
|
const func = this._bindings.get(bindingCall._initializer.name);
|
|
|
|
if (func) {
|
|
await bindingCall.call(func);
|
|
return;
|
|
}
|
|
|
|
await this._browserContext._onBinding(bindingCall);
|
|
}
|
|
|
|
_onWorker(worker) {
|
|
this._workers.add(worker);
|
|
|
|
worker._page = this;
|
|
this.emit(_events.Events.Page.Worker, worker);
|
|
}
|
|
|
|
_onClose() {
|
|
this._closed = true;
|
|
|
|
this._browserContext._pages.delete(this);
|
|
|
|
this._browserContext._backgroundPages.delete(this);
|
|
|
|
this.emit(_events.Events.Page.Close, this);
|
|
}
|
|
|
|
_onCrash() {
|
|
this.emit(_events.Events.Page.Crash, this);
|
|
}
|
|
|
|
context() {
|
|
return this._browserContext;
|
|
}
|
|
|
|
async opener() {
|
|
if (!this._opener || this._opener.isClosed()) return null;
|
|
return this._opener;
|
|
}
|
|
|
|
mainFrame() {
|
|
return this._mainFrame;
|
|
}
|
|
|
|
frame(frameSelector) {
|
|
const name = (0, _utils.isString)(frameSelector) ? frameSelector : frameSelector.name;
|
|
const url = (0, _utils.isObject)(frameSelector) ? frameSelector.url : undefined;
|
|
(0, _utils.assert)(name || url, 'Either name or url matcher should be specified');
|
|
return this.frames().find(f => {
|
|
if (name) return f.name() === name;
|
|
return (0, _clientHelper.urlMatches)(this._browserContext._options.baseURL, f.url(), url);
|
|
}) || null;
|
|
}
|
|
|
|
frames() {
|
|
return [...this._frames];
|
|
}
|
|
|
|
setDefaultNavigationTimeout(timeout) {
|
|
this._timeoutSettings.setDefaultNavigationTimeout(timeout);
|
|
|
|
this._channel.setDefaultNavigationTimeoutNoReply({
|
|
timeout
|
|
});
|
|
}
|
|
|
|
setDefaultTimeout(timeout) {
|
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
|
|
|
this._channel.setDefaultTimeoutNoReply({
|
|
timeout
|
|
});
|
|
}
|
|
|
|
_forceVideo() {
|
|
if (!this._video) this._video = new _video.Video(this);
|
|
return this._video;
|
|
}
|
|
|
|
video() {
|
|
// Note: we are creating Video object lazily, because we do not know
|
|
// BrowserContextOptions when constructing the page - it is assigned
|
|
// too late during launchPersistentContext.
|
|
if (!this._browserContext._options.recordVideo) return null;
|
|
return this._forceVideo();
|
|
}
|
|
|
|
async $(selector, options) {
|
|
return this._mainFrame.$(selector, options);
|
|
}
|
|
|
|
async waitForSelector(selector, options) {
|
|
return this._mainFrame.waitForSelector(selector, options);
|
|
}
|
|
|
|
async dispatchEvent(selector, type, eventInit, options) {
|
|
return this._mainFrame.dispatchEvent(selector, type, eventInit, options);
|
|
}
|
|
|
|
async evaluateHandle(pageFunction, arg) {
|
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
|
return this._mainFrame.evaluateHandle(pageFunction, arg);
|
|
}
|
|
|
|
async $eval(selector, pageFunction, arg) {
|
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
|
return this._mainFrame.$eval(selector, pageFunction, arg);
|
|
}
|
|
|
|
async $$eval(selector, pageFunction, arg) {
|
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 3);
|
|
return this._mainFrame.$$eval(selector, pageFunction, arg);
|
|
}
|
|
|
|
async $$(selector) {
|
|
return this._mainFrame.$$(selector);
|
|
}
|
|
|
|
async addScriptTag(options = {}) {
|
|
return this._mainFrame.addScriptTag(options);
|
|
}
|
|
|
|
async addStyleTag(options = {}) {
|
|
return this._mainFrame.addStyleTag(options);
|
|
}
|
|
|
|
async exposeFunction(name, callback) {
|
|
return this._wrapApiCall(async channel => {
|
|
await channel.exposeBinding({
|
|
name
|
|
});
|
|
|
|
const binding = (source, ...args) => callback(...args);
|
|
|
|
this._bindings.set(name, binding);
|
|
});
|
|
}
|
|
|
|
async exposeBinding(name, callback, options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
await channel.exposeBinding({
|
|
name,
|
|
needsHandle: options.handle
|
|
});
|
|
|
|
this._bindings.set(name, callback);
|
|
});
|
|
}
|
|
|
|
async setExtraHTTPHeaders(headers) {
|
|
return this._wrapApiCall(async channel => {
|
|
(0, _network.validateHeaders)(headers);
|
|
await channel.setExtraHTTPHeaders({
|
|
headers: (0, _utils.headersObjectToArray)(headers)
|
|
});
|
|
});
|
|
}
|
|
|
|
url() {
|
|
return this._mainFrame.url();
|
|
}
|
|
|
|
async content() {
|
|
return this._mainFrame.content();
|
|
}
|
|
|
|
async setContent(html, options) {
|
|
return this._mainFrame.setContent(html, options);
|
|
}
|
|
|
|
async goto(url, options) {
|
|
return this._mainFrame.goto(url, options);
|
|
}
|
|
|
|
async reload(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
|
return _network.Response.fromNullable((await channel.reload({ ...options,
|
|
waitUntil
|
|
})).response);
|
|
});
|
|
}
|
|
|
|
async waitForLoadState(state, options) {
|
|
return this._mainFrame.waitForLoadState(state, options);
|
|
}
|
|
|
|
async waitForNavigation(options) {
|
|
return this._mainFrame.waitForNavigation(options);
|
|
}
|
|
|
|
async waitForURL(url, options) {
|
|
return this._mainFrame.waitForURL(url, options);
|
|
}
|
|
|
|
async waitForRequest(urlOrPredicate, options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const predicate = request => {
|
|
if ((0, _utils.isString)(urlOrPredicate) || (0, _utils.isRegExp)(urlOrPredicate)) return (0, _clientHelper.urlMatches)(this._browserContext._options.baseURL, request.url(), urlOrPredicate);
|
|
return urlOrPredicate(request);
|
|
};
|
|
|
|
const trimmedUrl = trimUrl(urlOrPredicate);
|
|
const logLine = trimmedUrl ? `waiting for request ${trimmedUrl}` : undefined;
|
|
return this._waitForEvent(_events.Events.Page.Request, {
|
|
predicate,
|
|
timeout: options.timeout
|
|
}, logLine);
|
|
});
|
|
}
|
|
|
|
async waitForResponse(urlOrPredicate, options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const predicate = response => {
|
|
if ((0, _utils.isString)(urlOrPredicate) || (0, _utils.isRegExp)(urlOrPredicate)) return (0, _clientHelper.urlMatches)(this._browserContext._options.baseURL, response.url(), urlOrPredicate);
|
|
return urlOrPredicate(response);
|
|
};
|
|
|
|
const trimmedUrl = trimUrl(urlOrPredicate);
|
|
const logLine = trimmedUrl ? `waiting for response ${trimmedUrl}` : undefined;
|
|
return this._waitForEvent(_events.Events.Page.Response, {
|
|
predicate,
|
|
timeout: options.timeout
|
|
}, logLine);
|
|
});
|
|
}
|
|
|
|
async waitForEvent(event, optionsOrPredicate = {}) {
|
|
return this._waitForEvent(event, optionsOrPredicate, `waiting for event "${event}"`);
|
|
}
|
|
|
|
async _waitForEvent(event, optionsOrPredicate, logLine) {
|
|
const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === 'function' ? {} : optionsOrPredicate);
|
|
|
|
const predicate = typeof optionsOrPredicate === 'function' ? optionsOrPredicate : optionsOrPredicate.predicate;
|
|
|
|
const waiter = _waiter.Waiter.createForEvent(this, event);
|
|
|
|
if (logLine) waiter.log(logLine);
|
|
waiter.rejectOnTimeout(timeout, `Timeout while waiting for event "${event}"`);
|
|
if (event !== _events.Events.Page.Crash) waiter.rejectOnEvent(this, _events.Events.Page.Crash, new Error('Page crashed'));
|
|
if (event !== _events.Events.Page.Close) waiter.rejectOnEvent(this, _events.Events.Page.Close, new Error('Page closed'));
|
|
const result = await waiter.waitForEvent(this, event, predicate);
|
|
waiter.dispose();
|
|
return result;
|
|
}
|
|
|
|
async goBack(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
|
return _network.Response.fromNullable((await channel.goBack({ ...options,
|
|
waitUntil
|
|
})).response);
|
|
});
|
|
}
|
|
|
|
async goForward(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const waitUntil = (0, _frame.verifyLoadState)('waitUntil', options.waitUntil === undefined ? 'load' : options.waitUntil);
|
|
return _network.Response.fromNullable((await channel.goForward({ ...options,
|
|
waitUntil
|
|
})).response);
|
|
});
|
|
}
|
|
|
|
async emulateMedia(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
await channel.emulateMedia({
|
|
media: options.media === null ? 'null' : options.media,
|
|
colorScheme: options.colorScheme === null ? 'null' : options.colorScheme,
|
|
reducedMotion: options.reducedMotion === null ? 'null' : options.reducedMotion,
|
|
forcedColors: options.forcedColors === null ? 'null' : options.forcedColors
|
|
});
|
|
});
|
|
}
|
|
|
|
async setViewportSize(viewportSize) {
|
|
return this._wrapApiCall(async channel => {
|
|
this._viewportSize = viewportSize;
|
|
await channel.setViewportSize({
|
|
viewportSize
|
|
});
|
|
});
|
|
}
|
|
|
|
viewportSize() {
|
|
return this._viewportSize;
|
|
}
|
|
|
|
async evaluate(pageFunction, arg) {
|
|
(0, _jsHandle.assertMaxArguments)(arguments.length, 2);
|
|
return this._mainFrame.evaluate(pageFunction, arg);
|
|
}
|
|
|
|
async addInitScript(script, arg) {
|
|
return this._wrapApiCall(async channel => {
|
|
const source = await (0, _clientHelper.evaluationScript)(script, arg);
|
|
await channel.addInitScript({
|
|
source
|
|
});
|
|
});
|
|
}
|
|
|
|
async route(url, handler, options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
this._routes.unshift(new _network.RouteHandler(this._browserContext._options.baseURL, url, handler, options.times));
|
|
|
|
if (this._routes.length === 1) await channel.setNetworkInterceptionEnabled({
|
|
enabled: true
|
|
});
|
|
});
|
|
}
|
|
|
|
async unroute(url, handler) {
|
|
return this._wrapApiCall(async channel => {
|
|
this._routes = this._routes.filter(route => route.url !== url || handler && route.handler !== handler);
|
|
if (this._routes.length === 0) await channel.setNetworkInterceptionEnabled({
|
|
enabled: false
|
|
});
|
|
});
|
|
}
|
|
|
|
async screenshot(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const copy = { ...options
|
|
};
|
|
if (!copy.type) copy.type = (0, _elementHandle.determineScreenshotType)(options);
|
|
const result = await channel.screenshot(copy);
|
|
|
|
const buffer = _buffer.Buffer.from(result.binary, 'base64');
|
|
|
|
if (options.path) {
|
|
await (0, _utils.mkdirIfNeeded)(options.path);
|
|
await _fs.default.promises.writeFile(options.path, buffer);
|
|
}
|
|
|
|
return buffer;
|
|
});
|
|
}
|
|
|
|
async title() {
|
|
return this._mainFrame.title();
|
|
}
|
|
|
|
async bringToFront() {
|
|
return this._wrapApiCall(async channel => {
|
|
await channel.bringToFront();
|
|
});
|
|
}
|
|
|
|
async close(options = {
|
|
runBeforeUnload: undefined
|
|
}) {
|
|
try {
|
|
await this._wrapApiCall(async channel => {
|
|
if (this._ownedContext) await this._ownedContext.close();else await channel.close(options);
|
|
});
|
|
} catch (e) {
|
|
if ((0, _errors.isSafeCloseError)(e)) return;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
isClosed() {
|
|
return this._closed;
|
|
}
|
|
|
|
async click(selector, options) {
|
|
return this._mainFrame.click(selector, options);
|
|
}
|
|
|
|
async dragAndDrop(source, target, options) {
|
|
return this._mainFrame.dragAndDrop(source, target, options);
|
|
}
|
|
|
|
async dblclick(selector, options) {
|
|
return this._mainFrame.dblclick(selector, options);
|
|
}
|
|
|
|
async tap(selector, options) {
|
|
return this._mainFrame.tap(selector, options);
|
|
}
|
|
|
|
async fill(selector, value, options) {
|
|
return this._mainFrame.fill(selector, value, options);
|
|
}
|
|
|
|
locator(selector) {
|
|
return this.mainFrame().locator(selector);
|
|
}
|
|
|
|
async focus(selector, options) {
|
|
return this._mainFrame.focus(selector, options);
|
|
}
|
|
|
|
async textContent(selector, options) {
|
|
return this._mainFrame.textContent(selector, options);
|
|
}
|
|
|
|
async innerText(selector, options) {
|
|
return this._mainFrame.innerText(selector, options);
|
|
}
|
|
|
|
async innerHTML(selector, options) {
|
|
return this._mainFrame.innerHTML(selector, options);
|
|
}
|
|
|
|
async getAttribute(selector, name, options) {
|
|
return this._mainFrame.getAttribute(selector, name, options);
|
|
}
|
|
|
|
async inputValue(selector, options) {
|
|
return this._mainFrame.inputValue(selector, options);
|
|
}
|
|
|
|
async isChecked(selector, options) {
|
|
return this._mainFrame.isChecked(selector, options);
|
|
}
|
|
|
|
async isDisabled(selector, options) {
|
|
return this._mainFrame.isDisabled(selector, options);
|
|
}
|
|
|
|
async isEditable(selector, options) {
|
|
return this._mainFrame.isEditable(selector, options);
|
|
}
|
|
|
|
async isEnabled(selector, options) {
|
|
return this._mainFrame.isEnabled(selector, options);
|
|
}
|
|
|
|
async isHidden(selector, options) {
|
|
return this._mainFrame.isHidden(selector, options);
|
|
}
|
|
|
|
async isVisible(selector, options) {
|
|
return this._mainFrame.isVisible(selector, options);
|
|
}
|
|
|
|
async hover(selector, options) {
|
|
return this._mainFrame.hover(selector, options);
|
|
}
|
|
|
|
async selectOption(selector, values, options) {
|
|
return this._mainFrame.selectOption(selector, values, options);
|
|
}
|
|
|
|
async setInputFiles(selector, files, options) {
|
|
return this._mainFrame.setInputFiles(selector, files, options);
|
|
}
|
|
|
|
async type(selector, text, options) {
|
|
return this._mainFrame.type(selector, text, options);
|
|
}
|
|
|
|
async press(selector, key, options) {
|
|
return this._mainFrame.press(selector, key, options);
|
|
}
|
|
|
|
async check(selector, options) {
|
|
return this._mainFrame.check(selector, options);
|
|
}
|
|
|
|
async uncheck(selector, options) {
|
|
return this._mainFrame.uncheck(selector, options);
|
|
}
|
|
|
|
async setChecked(selector, checked, options) {
|
|
return this._mainFrame.setChecked(selector, checked, options);
|
|
}
|
|
|
|
async waitForTimeout(timeout) {
|
|
return this._mainFrame.waitForTimeout(timeout);
|
|
}
|
|
|
|
async waitForFunction(pageFunction, arg, options) {
|
|
return this._mainFrame.waitForFunction(pageFunction, arg, options);
|
|
}
|
|
|
|
workers() {
|
|
return [...this._workers];
|
|
}
|
|
|
|
on(event, listener) {
|
|
if (event === _events.Events.Page.FileChooser && !this.listenerCount(event)) this._channel.setFileChooserInterceptedNoReply({
|
|
intercepted: true
|
|
});
|
|
super.on(event, listener);
|
|
return this;
|
|
}
|
|
|
|
addListener(event, listener) {
|
|
if (event === _events.Events.Page.FileChooser && !this.listenerCount(event)) this._channel.setFileChooserInterceptedNoReply({
|
|
intercepted: true
|
|
});
|
|
super.addListener(event, listener);
|
|
return this;
|
|
}
|
|
|
|
off(event, listener) {
|
|
super.off(event, listener);
|
|
if (event === _events.Events.Page.FileChooser && !this.listenerCount(event)) this._channel.setFileChooserInterceptedNoReply({
|
|
intercepted: false
|
|
});
|
|
return this;
|
|
}
|
|
|
|
removeListener(event, listener) {
|
|
super.removeListener(event, listener);
|
|
if (event === _events.Events.Page.FileChooser && !this.listenerCount(event)) this._channel.setFileChooserInterceptedNoReply({
|
|
intercepted: false
|
|
});
|
|
return this;
|
|
}
|
|
|
|
async pause() {
|
|
return this.context()._wrapApiCall(async channel => {
|
|
await channel.pause();
|
|
});
|
|
}
|
|
|
|
async pdf(options = {}) {
|
|
return this._wrapApiCall(async channel => {
|
|
const transportOptions = { ...options
|
|
};
|
|
if (transportOptions.margin) transportOptions.margin = { ...transportOptions.margin
|
|
};
|
|
if (typeof options.width === 'number') transportOptions.width = options.width + 'px';
|
|
if (typeof options.height === 'number') transportOptions.height = options.height + 'px';
|
|
|
|
for (const margin of ['top', 'right', 'bottom', 'left']) {
|
|
const index = margin;
|
|
if (options.margin && typeof options.margin[index] === 'number') transportOptions.margin[index] = transportOptions.margin[index] + 'px';
|
|
}
|
|
|
|
const result = await channel.pdf(transportOptions);
|
|
|
|
const buffer = _buffer.Buffer.from(result.pdf, 'base64');
|
|
|
|
if (options.path) {
|
|
await _fs.default.promises.mkdir(_path.default.dirname(options.path), {
|
|
recursive: true
|
|
});
|
|
await _fs.default.promises.writeFile(options.path, buffer);
|
|
}
|
|
|
|
return buffer;
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
exports.Page = Page;
|
|
|
|
class BindingCall extends _channelOwner.ChannelOwner {
|
|
static from(channel) {
|
|
return channel._object;
|
|
}
|
|
|
|
constructor(parent, type, guid, initializer) {
|
|
super(parent, type, guid, initializer);
|
|
}
|
|
|
|
async call(func) {
|
|
try {
|
|
const frame = _frame.Frame.from(this._initializer.frame);
|
|
|
|
const source = {
|
|
context: frame._page.context(),
|
|
page: frame._page,
|
|
frame
|
|
};
|
|
let result;
|
|
if (this._initializer.handle) result = await func(source, _jsHandle.JSHandle.from(this._initializer.handle));else result = await func(source, ...this._initializer.args.map(_jsHandle.parseResult));
|
|
|
|
this._channel.resolve({
|
|
result: (0, _jsHandle.serializeArgument)(result)
|
|
}).catch(() => {});
|
|
} catch (e) {
|
|
this._channel.reject({
|
|
error: (0, _serializers.serializeError)(e)
|
|
}).catch(() => {});
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
exports.BindingCall = BindingCall;
|
|
|
|
function trimEnd(s) {
|
|
if (s.length > 50) s = s.substring(0, 50) + '\u2026';
|
|
return s;
|
|
}
|
|
|
|
function trimUrl(param) {
|
|
if ((0, _utils.isRegExp)(param)) return `/${trimEnd(param.source)}/${param.flags}`;
|
|
if ((0, _utils.isString)(param)) return `"${trimEnd(param)}"`;
|
|
} |