diff --git a/dist/bidi.js b/dist/bidi.js
index 9123495..b954732 100644
--- a/dist/bidi.js
+++ b/dist/bidi.js
@@ -1,9 +1,9 @@
'use strict';
var index = require('./index.js');
-require('./vm2/bridge.js');
+var vm2_bridge = require('./vm2/bridge.js');
+var require$$5 = require('crypto');
require('os');
-require('crypto');
require('fs');
require('path');
require('http');
@@ -52,6 +52,8 @@ require('module');
require('process');
require('http2');
require('inspector');
+require('chromium-bidi/lib/cjs/bidiMapper/BidiMapper');
+require('chromium-bidi/lib/cjs/cdp/CdpConnection');
/**
* Copyright 2023 Google Inc. All rights reserved.
@@ -1691,6 +1693,5481 @@ function createProtocolError(object) {
return message;
}
+var bidiMapper = {};
+
+var BidiServer$1 = {};
+
+var EventEmitter$1 = {};
+
+var mitt=function(n){return {all:n=n||new Map,on:function(e,t){var i=n.get(e);i?i.push(t):n.set(e,[t]);},off:function(e,t){var i=n.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):n.set(e,[]));},emit:function(e,t){var i=n.get(e);i&&i.slice().map(function(n){n(t);}),(i=n.get("*"))&&i.slice().map(function(n){n(e,t);});}}};
+
+var __importDefault = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(EventEmitter$1, "__esModule", { value: true });
+EventEmitter$1.EventEmitter = void 0;
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+const mitt_1 = __importDefault(mitt);
+class EventEmitter {
+ #emitter = (0, mitt_1.default)();
+ on(type, handler) {
+ this.#emitter.on(type, handler);
+ return this;
+ }
+ /**
+ * Like `on` but the listener will only be fired once and then it will be removed.
+ * @param event The event you'd like to listen to
+ * @param handler The handler function to run when the event occurs
+ * @return `this` to enable chaining method calls.
+ */
+ once(event, handler) {
+ const onceHandler = (eventData) => {
+ handler(eventData);
+ this.off(event, onceHandler);
+ };
+ return this.on(event, onceHandler);
+ }
+ off(type, handler) {
+ this.#emitter.off(type, handler);
+ return this;
+ }
+ /**
+ * Emits an event and call any associated listeners.
+ *
+ * @param event The event to emit.
+ * @param eventData Any data to emit with the event.
+ * @return `true` if there are any listeners, `false` otherwise.
+ */
+ emit(event, eventData) {
+ this.#emitter.emit(event, eventData);
+ }
+}
+EventEmitter$1.EventEmitter = EventEmitter;
+
+var log = {};
+
+(function (exports) {
+ /**
+ * Copyright 2021 Google LLC.
+ * 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.
+ */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.LogType = void 0;
+ (function (LogType) {
+ // keep-sorted start
+ LogType["bidi"] = "BiDi Messages";
+ LogType["browsingContexts"] = "Browsing Contexts";
+ LogType["cdp"] = "CDP";
+ LogType["system"] = "System";
+ // keep-sorted end
+ })(exports.LogType || (exports.LogType = {}));
+
+} (log));
+
+var processingQueue = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(processingQueue, "__esModule", { value: true });
+processingQueue.ProcessingQueue = void 0;
+const log_js_1$6 = log;
+class ProcessingQueue {
+ #logger;
+ #processor;
+ #queue = [];
+ // Flag to keep only 1 active processor.
+ #isProcessing = false;
+ constructor(processor, logger) {
+ this.#processor = processor;
+ this.#logger = logger;
+ }
+ add(entry) {
+ this.#queue.push(entry);
+ // No need in waiting. Just initialise processor if needed.
+ void this.#processIfNeeded();
+ }
+ async #processIfNeeded() {
+ if (this.#isProcessing) {
+ return;
+ }
+ this.#isProcessing = true;
+ while (this.#queue.length > 0) {
+ const entryPromise = this.#queue.shift();
+ if (entryPromise !== undefined) {
+ await entryPromise
+ .then((entry) => this.#processor(entry))
+ .catch((e) => {
+ this.#logger?.(log_js_1$6.LogType.system, 'Event was not processed:', e);
+ });
+ }
+ }
+ this.#isProcessing = false;
+ }
+}
+processingQueue.ProcessingQueue = ProcessingQueue;
+
+var CommandProcessor$1 = {};
+
+var protocol = {};
+
+(function (exports) {
+ /**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.Input = exports.CDP = exports.Network = exports.Log = exports.BrowsingContext = exports.Script = exports.Message = void 0;
+ (function (Message) {
+ // keep-sorted end;
+ let ErrorCode;
+ (function (ErrorCode) {
+ // keep-sorted start
+ ErrorCode["InvalidArgument"] = "invalid argument";
+ ErrorCode["InvalidSessionId"] = "invalid session id";
+ ErrorCode["MoveTargetOutOfBounds"] = "move target out of bounds";
+ ErrorCode["NoSuchAlert"] = "no such alert";
+ ErrorCode["NoSuchFrame"] = "no such frame";
+ ErrorCode["NoSuchHandle"] = "no such handle";
+ ErrorCode["NoSuchNode"] = "no such node";
+ ErrorCode["NoSuchScript"] = "no such script";
+ ErrorCode["SessionNotCreated"] = "session not created";
+ ErrorCode["UnknownCommand"] = "unknown command";
+ ErrorCode["UnknownError"] = "unknown error";
+ ErrorCode["UnsupportedOperation"] = "unsupported operation";
+ // keep-sorted end
+ })(ErrorCode = Message.ErrorCode || (Message.ErrorCode = {}));
+ class ErrorResponse {
+ error;
+ message;
+ stacktrace;
+ constructor(error, message, stacktrace) {
+ this.error = error;
+ this.message = message;
+ this.stacktrace = stacktrace;
+ }
+ toErrorResponse(commandId) {
+ return {
+ id: commandId,
+ error: this.error,
+ message: this.message,
+ stacktrace: this.stacktrace,
+ };
+ }
+ }
+ Message.ErrorResponse = ErrorResponse;
+ class InvalidArgumentException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.InvalidArgument, message, stacktrace);
+ }
+ }
+ Message.InvalidArgumentException = InvalidArgumentException;
+ class MoveTargetOutOfBoundsException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.MoveTargetOutOfBounds, message, stacktrace);
+ }
+ }
+ Message.MoveTargetOutOfBoundsException = MoveTargetOutOfBoundsException;
+ class NoSuchHandleException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.NoSuchHandle, message, stacktrace);
+ }
+ }
+ Message.NoSuchHandleException = NoSuchHandleException;
+ class InvalidSessionIdException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.InvalidSessionId, message, stacktrace);
+ }
+ }
+ Message.InvalidSessionIdException = InvalidSessionIdException;
+ class NoSuchAlertException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.NoSuchAlert, message, stacktrace);
+ }
+ }
+ Message.NoSuchAlertException = NoSuchAlertException;
+ class NoSuchFrameException extends ErrorResponse {
+ constructor(message) {
+ super(ErrorCode.NoSuchFrame, message);
+ }
+ }
+ Message.NoSuchFrameException = NoSuchFrameException;
+ class NoSuchNodeException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.NoSuchNode, message, stacktrace);
+ }
+ }
+ Message.NoSuchNodeException = NoSuchNodeException;
+ class NoSuchScriptException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.NoSuchScript, message, stacktrace);
+ }
+ }
+ Message.NoSuchScriptException = NoSuchScriptException;
+ class SessionNotCreatedException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.SessionNotCreated, message, stacktrace);
+ }
+ }
+ Message.SessionNotCreatedException = SessionNotCreatedException;
+ class UnknownCommandException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.UnknownCommand, message, stacktrace);
+ }
+ }
+ Message.UnknownCommandException = UnknownCommandException;
+ class UnknownErrorException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.UnknownError, message, stacktrace);
+ }
+ }
+ Message.UnknownErrorException = UnknownErrorException;
+ class UnsupportedOperationException extends ErrorResponse {
+ constructor(message, stacktrace) {
+ super(ErrorCode.UnsupportedOperation, message, stacktrace);
+ }
+ }
+ Message.UnsupportedOperationException = UnsupportedOperationException;
+ })(exports.Message || (exports.Message = {}));
+ (function (Script) {
+ (function (EventNames) {
+ EventNames["MessageEvent"] = "script.message";
+ })(Script.EventNames || (Script.EventNames = {}));
+ Script.AllEvents = 'script';
+ })(exports.Script || (exports.Script = {}));
+ (function (BrowsingContext) {
+ (function (EventNames) {
+ EventNames["LoadEvent"] = "browsingContext.load";
+ EventNames["DomContentLoadedEvent"] = "browsingContext.domContentLoaded";
+ EventNames["ContextCreatedEvent"] = "browsingContext.contextCreated";
+ EventNames["ContextDestroyedEvent"] = "browsingContext.contextDestroyed";
+ })(BrowsingContext.EventNames || (BrowsingContext.EventNames = {}));
+ BrowsingContext.AllEvents = 'browsingContext';
+ })(exports.BrowsingContext || (exports.BrowsingContext = {}));
+ (function (Log) {
+ Log.AllEvents = 'log';
+ (function (EventNames) {
+ EventNames["LogEntryAddedEvent"] = "log.entryAdded";
+ })(Log.EventNames || (Log.EventNames = {}));
+ })(exports.Log || (exports.Log = {}));
+ (function (Network) {
+ Network.AllEvents = 'network';
+ (function (EventNames) {
+ EventNames["BeforeRequestSentEvent"] = "network.beforeRequestSent";
+ EventNames["FetchErrorEvent"] = "network.fetchError";
+ EventNames["ResponseStartedEvent"] = "network.responseStarted";
+ EventNames["ResponseCompletedEvent"] = "network.responseCompleted";
+ })(Network.EventNames || (Network.EventNames = {}));
+ })(exports.Network || (exports.Network = {}));
+ (function (CDP) {
+ CDP.AllEvents = 'cdp';
+ (function (EventNames) {
+ EventNames["EventReceivedEvent"] = "cdp.eventReceived";
+ })(CDP.EventNames || (CDP.EventNames = {}));
+ })(exports.CDP || (exports.CDP = {}));
+ (function (Input) {
+ (function (SourceActionsType) {
+ SourceActionsType["None"] = "none";
+ SourceActionsType["Key"] = "key";
+ SourceActionsType["Pointer"] = "pointer";
+ SourceActionsType["Wheel"] = "wheel";
+ })(Input.SourceActionsType || (Input.SourceActionsType = {}));
+ (function (PointerType) {
+ PointerType["Mouse"] = "mouse";
+ PointerType["Pen"] = "pen";
+ PointerType["Touch"] = "touch";
+ })(Input.PointerType || (Input.PointerType = {}));
+ (function (ActionType) {
+ ActionType["Pause"] = "pause";
+ ActionType["KeyDown"] = "keyDown";
+ ActionType["KeyUp"] = "keyUp";
+ ActionType["PointerUp"] = "pointerUp";
+ ActionType["PointerDown"] = "pointerDown";
+ ActionType["PointerMove"] = "pointerMove";
+ ActionType["Scroll"] = "scroll";
+ })(Input.ActionType || (Input.ActionType = {}));
+ })(exports.Input || (exports.Input = {}));
+
+} (protocol));
+
+var browsingContextProcessor = {};
+
+var InputStateManager$1 = {};
+
+var assert$1 = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(assert$1, "__esModule", { value: true });
+assert$1.assert = void 0;
+function assert(predicate) {
+ if (!predicate) {
+ throw new Error('Internal assertion failed.');
+ }
+}
+assert$1.assert = assert;
+
+var InputState$1 = {};
+
+var Mutex$1 = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * Copyright (c) Microsoft Corporation.
+ * Copyright 2022 The Chromium Authors.
+ *
+ * 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.
+ */
+Object.defineProperty(Mutex$1, "__esModule", { value: true });
+Mutex$1.Mutex = void 0;
+/**
+ * Use Mutex class to coordinate local concurrent operations.
+ * Once `acquire` promise resolves, you hold the lock and must
+ * call `release` function returned by `acquire` to release the
+ * lock. Failing to `release` the lock may lead to deadlocks.
+ */
+class Mutex {
+ #locked = false;
+ #acquirers = [];
+ // This is FIFO.
+ acquire() {
+ const state = { resolved: false };
+ if (this.#locked) {
+ return new Promise((resolve) => {
+ this.#acquirers.push(() => resolve(this.#release.bind(this, state)));
+ });
+ }
+ this.#locked = true;
+ return Promise.resolve(this.#release.bind(this, state));
+ }
+ #release(state) {
+ if (state.resolved) {
+ throw new Error('Cannot release more than once.');
+ }
+ state.resolved = true;
+ const resolve = this.#acquirers.shift();
+ if (!resolve) {
+ this.#locked = false;
+ return;
+ }
+ resolve();
+ }
+ async run(action) {
+ const release = await this.acquire();
+ try {
+ // Note we need to await here because we want the await to release AFTER
+ // that await happens. Returning action() will trigger the release
+ // immediately which is counter to what we want.
+ const result = await action();
+ return result;
+ }
+ finally {
+ release();
+ }
+ }
+}
+Mutex$1.Mutex = Mutex;
+
+var InputSource = {};
+
+(function (exports) {
+ /**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.WheelSource = exports.PointerSource = exports.KeySource = exports.NoneSource = exports.SourceType = void 0;
+ const protocol_js_1 = protocol;
+ exports.SourceType = protocol_js_1.Input.SourceActionsType;
+ class NoneSource {
+ type = exports.SourceType.None;
+ }
+ exports.NoneSource = NoneSource;
+ class KeySource {
+ type = exports.SourceType.Key;
+ pressed = new Set();
+ // This is a bitfield that matches the modifiers parameter of
+ // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent
+ #modifiers = 0;
+ get modifiers() {
+ return this.#modifiers;
+ }
+ get alt() {
+ return (this.#modifiers & 1) === 1;
+ }
+ set alt(value) {
+ this.#setModifier(value, 1);
+ }
+ get ctrl() {
+ return (this.#modifiers & 2) === 2;
+ }
+ set ctrl(value) {
+ this.#setModifier(value, 2);
+ }
+ get meta() {
+ return (this.#modifiers & 4) === 4;
+ }
+ set meta(value) {
+ this.#setModifier(value, 4);
+ }
+ get shift() {
+ return (this.#modifiers & 8) === 8;
+ }
+ set shift(value) {
+ this.#setModifier(value, 8);
+ }
+ #setModifier(value, bit) {
+ if (value) {
+ this.#modifiers |= bit;
+ }
+ else {
+ this.#modifiers ^= bit;
+ }
+ }
+ }
+ exports.KeySource = KeySource;
+ class PointerSource {
+ type = exports.SourceType.Pointer;
+ subtype;
+ pointerId;
+ pressed = new Set();
+ x = 0;
+ y = 0;
+ constructor(id, subtype) {
+ this.pointerId = id;
+ this.subtype = subtype;
+ }
+ // This is a bitfield that matches the buttons parameter of
+ // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchMouseEvent
+ get buttons() {
+ let buttons = 0;
+ for (const button of this.pressed) {
+ switch (button) {
+ case 0:
+ buttons |= 1;
+ break;
+ case 1:
+ buttons |= 4;
+ break;
+ case 2:
+ buttons |= 2;
+ break;
+ case 3:
+ buttons |= 8;
+ break;
+ case 4:
+ buttons |= 16;
+ break;
+ }
+ }
+ return buttons;
+ }
+ // --- Platform-specific state starts here ---
+ // Input.dispatchMouseEvent doesn't know the concept of double click, so we
+ // need to create it like for OSes:
+ // https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/events/event.cc;l=479
+ static #DOUBLE_CLICK_TIME_MS = 500;
+ static #MAX_DOUBLE_CLICK_RADIUS = 2;
+ #clickCount = 0;
+ #lastClick;
+ setClickCount(context) {
+ if (!this.#lastClick ||
+ // The click needs to be within a certain amount of ms.
+ context.timeStamp - this.#lastClick.timeStamp >
+ PointerSource.#DOUBLE_CLICK_TIME_MS ||
+ // The click needs to be within a square radius.
+ Math.abs(this.#lastClick.x - context.x) >
+ PointerSource.#MAX_DOUBLE_CLICK_RADIUS ||
+ Math.abs(this.#lastClick.y - context.y) >
+ PointerSource.#MAX_DOUBLE_CLICK_RADIUS) {
+ this.#clickCount = 0;
+ }
+ ++this.#clickCount;
+ this.#lastClick = context;
+ }
+ get clickCount() {
+ return this.#clickCount;
+ }
+ }
+ exports.PointerSource = PointerSource;
+ class WheelSource {
+ type = exports.SourceType.Wheel;
+ }
+ exports.WheelSource = WheelSource;
+
+} (InputSource));
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(InputState$1, "__esModule", { value: true });
+InputState$1.InputState = void 0;
+const protocol_js_1$b = protocol;
+const Mutex_js_1 = Mutex$1;
+const InputSource_js_1 = InputSource;
+class InputState {
+ cancelList = [];
+ #sources = new Map();
+ #mutex = new Mutex_js_1.Mutex();
+ getOrCreate(id, type, subtype) {
+ let source = this.#sources.get(id);
+ if (!source) {
+ switch (type) {
+ case InputSource_js_1.SourceType.None:
+ source = new InputSource_js_1.NoneSource();
+ break;
+ case InputSource_js_1.SourceType.Key:
+ source = new InputSource_js_1.KeySource();
+ break;
+ case InputSource_js_1.SourceType.Pointer: {
+ let pointerId = subtype === protocol_js_1$b.Input.PointerType.Mouse ? 0 : 2;
+ const pointerIds = new Set();
+ for (const [, source] of this.#sources) {
+ if (source.type === InputSource_js_1.SourceType.Pointer) {
+ pointerIds.add(source.pointerId);
+ }
+ }
+ while (pointerIds.has(pointerId)) {
+ ++pointerId;
+ }
+ source = new InputSource_js_1.PointerSource(pointerId, subtype);
+ break;
+ }
+ case InputSource_js_1.SourceType.Wheel:
+ source = new InputSource_js_1.WheelSource();
+ break;
+ default:
+ throw new protocol_js_1$b.Message.InvalidArgumentException(`Expected "${InputSource_js_1.SourceType.None}", "${InputSource_js_1.SourceType.Key}", "${InputSource_js_1.SourceType.Pointer}", or "${InputSource_js_1.SourceType.Wheel}". Found unknown source type ${type}.`);
+ }
+ this.#sources.set(id, source);
+ return source;
+ }
+ if (source.type !== type) {
+ throw new protocol_js_1$b.Message.InvalidArgumentException(`Input source type of ${id} is ${source.type}, but received ${type}.`);
+ }
+ return source;
+ }
+ get(id) {
+ const source = this.#sources.get(id);
+ if (!source) {
+ throw new protocol_js_1$b.Message.UnknownErrorException(`Internal error.`);
+ }
+ return source;
+ }
+ getGlobalKeyState() {
+ const state = new InputSource_js_1.KeySource();
+ for (const [, source] of this.#sources) {
+ if (source.type !== InputSource_js_1.SourceType.Key) {
+ continue;
+ }
+ for (const pressed of source.pressed) {
+ state.pressed.add(pressed);
+ }
+ state.alt ||= source.alt;
+ state.ctrl ||= source.ctrl;
+ state.meta ||= source.meta;
+ state.shift ||= source.shift;
+ }
+ return state;
+ }
+ get queue() {
+ return this.#mutex;
+ }
+}
+InputState$1.InputState = InputState;
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(InputStateManager$1, "__esModule", { value: true });
+InputStateManager$1.InputStateManager = void 0;
+const assert_js_1$1 = assert$1;
+const InputState_js_1 = InputState$1;
+class InputStateManager {
+ // We use a weak map here as specified here:
+ // https://www.w3.org/TR/webdriver/#dfn-browsing-context-input-state-map
+ #states = new WeakMap();
+ get(context) {
+ (0, assert_js_1$1.assert)(context.isTopLevelContext());
+ let state = this.#states.get(context);
+ if (!state) {
+ state = new InputState_js_1.InputState();
+ this.#states.set(context, state);
+ }
+ return state;
+ }
+ delete(context) {
+ this.#states.delete(context);
+ }
+}
+InputStateManager$1.InputStateManager = InputStateManager;
+
+var ActionDispatcher$1 = {};
+
+var USKeyboardLayout = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(USKeyboardLayout, "__esModule", { value: true });
+USKeyboardLayout.KeyToKeyCode = void 0;
+// TODO: Remove this once https://crrev.com/c/4548290 is stably in Chromium.
+// `Input.dispatchKeyboardEvent` will automatically handle these conversions.
+USKeyboardLayout.KeyToKeyCode = {
+ '0': 48,
+ '1': 49,
+ '2': 50,
+ '3': 51,
+ '4': 52,
+ '5': 53,
+ '6': 54,
+ '7': 55,
+ '8': 56,
+ '9': 57,
+ Abort: 3,
+ Help: 6,
+ Backspace: 8,
+ Tab: 9,
+ Numpad5: 12,
+ NumpadEnter: 13,
+ Enter: 13,
+ '\\r': 13,
+ '\\n': 13,
+ ShiftLeft: 16,
+ ShiftRight: 16,
+ ControlLeft: 17,
+ ControlRight: 17,
+ AltLeft: 18,
+ AltRight: 18,
+ Pause: 19,
+ CapsLock: 20,
+ Escape: 27,
+ Convert: 28,
+ NonConvert: 29,
+ Space: 32,
+ Numpad9: 33,
+ PageUp: 33,
+ Numpad3: 34,
+ PageDown: 34,
+ End: 35,
+ Numpad1: 35,
+ Home: 36,
+ Numpad7: 36,
+ ArrowLeft: 37,
+ Numpad4: 37,
+ Numpad8: 38,
+ ArrowUp: 38,
+ ArrowRight: 39,
+ Numpad6: 39,
+ Numpad2: 40,
+ ArrowDown: 40,
+ Select: 41,
+ Open: 43,
+ PrintScreen: 44,
+ Insert: 45,
+ Numpad0: 45,
+ Delete: 46,
+ NumpadDecimal: 46,
+ Digit0: 48,
+ Digit1: 49,
+ Digit2: 50,
+ Digit3: 51,
+ Digit4: 52,
+ Digit5: 53,
+ Digit6: 54,
+ Digit7: 55,
+ Digit8: 56,
+ Digit9: 57,
+ KeyA: 65,
+ KeyB: 66,
+ KeyC: 67,
+ KeyD: 68,
+ KeyE: 69,
+ KeyF: 70,
+ KeyG: 71,
+ KeyH: 72,
+ KeyI: 73,
+ KeyJ: 74,
+ KeyK: 75,
+ KeyL: 76,
+ KeyM: 77,
+ KeyN: 78,
+ KeyO: 79,
+ KeyP: 80,
+ KeyQ: 81,
+ KeyR: 82,
+ KeyS: 83,
+ KeyT: 84,
+ KeyU: 85,
+ KeyV: 86,
+ KeyW: 87,
+ KeyX: 88,
+ KeyY: 89,
+ KeyZ: 90,
+ MetaLeft: 91,
+ MetaRight: 92,
+ ContextMenu: 93,
+ NumpadMultiply: 106,
+ NumpadAdd: 107,
+ NumpadSubtract: 109,
+ NumpadDivide: 111,
+ F1: 112,
+ F2: 113,
+ F3: 114,
+ F4: 115,
+ F5: 116,
+ F6: 117,
+ F7: 118,
+ F8: 119,
+ F9: 120,
+ F10: 121,
+ F11: 122,
+ F12: 123,
+ F13: 124,
+ F14: 125,
+ F15: 126,
+ F16: 127,
+ F17: 128,
+ F18: 129,
+ F19: 130,
+ F20: 131,
+ F21: 132,
+ F22: 133,
+ F23: 134,
+ F24: 135,
+ NumLock: 144,
+ ScrollLock: 145,
+ AudioVolumeMute: 173,
+ AudioVolumeDown: 174,
+ AudioVolumeUp: 175,
+ MediaTrackNext: 176,
+ MediaTrackPrevious: 177,
+ MediaStop: 178,
+ MediaPlayPause: 179,
+ Semicolon: 186,
+ Equal: 187,
+ NumpadEqual: 187,
+ Comma: 188,
+ Minus: 189,
+ Period: 190,
+ Slash: 191,
+ Backquote: 192,
+ BracketLeft: 219,
+ Backslash: 220,
+ BracketRight: 221,
+ Quote: 222,
+ AltGraph: 225,
+ Props: 247,
+ Cancel: 3,
+ Clear: 12,
+ Shift: 16,
+ Control: 17,
+ Alt: 18,
+ Accept: 30,
+ ModeChange: 31,
+ ' ': 32,
+ Print: 42,
+ Execute: 43,
+ '\\u0000': 46,
+ a: 65,
+ b: 66,
+ c: 67,
+ d: 68,
+ e: 69,
+ f: 70,
+ g: 71,
+ h: 72,
+ i: 73,
+ j: 74,
+ k: 75,
+ l: 76,
+ m: 77,
+ n: 78,
+ o: 79,
+ p: 80,
+ q: 81,
+ r: 82,
+ s: 83,
+ t: 84,
+ u: 85,
+ v: 86,
+ w: 87,
+ x: 88,
+ y: 89,
+ z: 90,
+ Meta: 91,
+ '*': 106,
+ '+': 107,
+ '-': 109,
+ '/': 111,
+ ';': 186,
+ '=': 187,
+ ',': 188,
+ '.': 190,
+ '`': 192,
+ '[': 219,
+ '\\\\': 220,
+ ']': 221,
+ "'": 222,
+ Attn: 246,
+ CrSel: 247,
+ ExSel: 248,
+ EraseEof: 249,
+ Play: 250,
+ ZoomOut: 251,
+ ')': 48,
+ '!': 49,
+ '@': 50,
+ '#': 51,
+ $: 52,
+ '%': 53,
+ '^': 54,
+ '&': 55,
+ '(': 57,
+ A: 65,
+ B: 66,
+ C: 67,
+ D: 68,
+ E: 69,
+ F: 70,
+ G: 71,
+ H: 72,
+ I: 73,
+ J: 74,
+ K: 75,
+ L: 76,
+ M: 77,
+ N: 78,
+ O: 79,
+ P: 80,
+ Q: 81,
+ R: 82,
+ S: 83,
+ T: 84,
+ U: 85,
+ V: 86,
+ W: 87,
+ X: 88,
+ Y: 89,
+ Z: 90,
+ ':': 186,
+ '<': 188,
+ _: 189,
+ '>': 190,
+ '?': 191,
+ '~': 192,
+ '{': 219,
+ '|': 220,
+ '}': 221,
+ '"': 222,
+ Camera: 44,
+ EndCall: 95,
+ VolumeDown: 182,
+ VolumeUp: 183,
+};
+
+var keyUtils = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(keyUtils, "__esModule", { value: true });
+keyUtils.getKeyLocation = keyUtils.getKeyCode = keyUtils.getNormalizedKey = void 0;
+function getNormalizedKey(value) {
+ switch (value) {
+ case '\uE000':
+ return 'Unidentified';
+ case '\uE001':
+ return 'Cancel';
+ case '\uE002':
+ return 'Help';
+ case '\uE003':
+ return 'Backspace';
+ case '\uE004':
+ return 'Tab';
+ case '\uE005':
+ return 'Clear';
+ case '\uE006':
+ return 'Return';
+ case '\uE007':
+ return 'Enter';
+ case '\uE008':
+ return 'Shift';
+ case '\uE009':
+ return 'Control';
+ case '\uE00A':
+ return 'Alt';
+ case '\uE00B':
+ return 'Pause';
+ case '\uE00C':
+ return 'Escape';
+ case '\uE00D':
+ return ' ';
+ case '\uE00E':
+ return 'PageUp';
+ case '\uE00F':
+ return 'PageDown';
+ case '\uE010':
+ return 'End';
+ case '\uE011':
+ return 'Home';
+ case '\uE012':
+ return 'ArrowLeft';
+ case '\uE013':
+ return 'ArrowUp';
+ case '\uE014':
+ return 'ArrowRight';
+ case '\uE015':
+ return 'ArrowDown';
+ case '\uE016':
+ return 'Insert';
+ case '\uE017':
+ return 'Delete';
+ case '\uE018':
+ return ';';
+ case '\uE019':
+ return '=';
+ case '\uE01A':
+ return '0';
+ case '\uE01B':
+ return '1';
+ case '\uE01C':
+ return '2';
+ case '\uE01D':
+ return '3';
+ case '\uE01E':
+ return '4';
+ case '\uE01F':
+ return '5';
+ case '\uE020':
+ return '6';
+ case '\uE021':
+ return '7';
+ case '\uE022':
+ return '8';
+ case '\uE023':
+ return '9';
+ case '\uE024':
+ return '*';
+ case '\uE025':
+ return '+';
+ case '\uE026':
+ return ',';
+ case '\uE027':
+ return '-';
+ case '\uE028':
+ return '.';
+ case '\uE029':
+ return '/';
+ case '\uE031':
+ return 'F1';
+ case '\uE032':
+ return 'F2';
+ case '\uE033':
+ return 'F3';
+ case '\uE034':
+ return 'F4';
+ case '\uE035':
+ return 'F5';
+ case '\uE036':
+ return 'F6';
+ case '\uE037':
+ return 'F7';
+ case '\uE038':
+ return 'F8';
+ case '\uE039':
+ return 'F9';
+ case '\uE03A':
+ return 'F10';
+ case '\uE03B':
+ return 'F11';
+ case '\uE03C':
+ return 'F12';
+ case '\uE03D':
+ return 'Meta';
+ case '\uE040':
+ return 'ZenkakuHankaku';
+ case '\uE050':
+ return 'Shift';
+ case '\uE051':
+ return 'Control';
+ case '\uE052':
+ return 'Alt';
+ case '\uE053':
+ return 'Meta';
+ case '\uE054':
+ return 'PageUp';
+ case '\uE055':
+ return 'PageDown';
+ case '\uE056':
+ return 'End';
+ case '\uE057':
+ return 'Home';
+ case '\uE058':
+ return 'ArrowLeft';
+ case '\uE059':
+ return 'ArrowUp';
+ case '\uE05A':
+ return 'ArrowRight';
+ case '\uE05B':
+ return 'ArrowDown';
+ case '\uE05C':
+ return 'Insert';
+ case '\uE05D':
+ return 'Delete';
+ default:
+ return value;
+ }
+}
+keyUtils.getNormalizedKey = getNormalizedKey;
+function getKeyCode(key) {
+ switch (key) {
+ case '`':
+ case '~':
+ return 'Backquote';
+ case '\\':
+ case '|':
+ return 'Backslash';
+ case '\uE003':
+ return 'Backspace';
+ case '[':
+ case '{':
+ return 'BracketLeft';
+ case ']':
+ case '}':
+ return 'BracketRight';
+ case ',':
+ case '<':
+ return 'Comma';
+ case '0':
+ case ')':
+ return 'Digit0';
+ case '1':
+ case '!':
+ return 'Digit1';
+ case '2':
+ case '@':
+ return 'Digit2';
+ case '3':
+ case '#':
+ return 'Digit3';
+ case '4':
+ case '$':
+ return 'Digit4';
+ case '5':
+ case '%':
+ return 'Digit5';
+ case '6':
+ case '^':
+ return 'Digit6';
+ case '7':
+ case '&':
+ return 'Digit7';
+ case '8':
+ case '*':
+ return 'Digit8';
+ case '9':
+ case '(':
+ return 'Digit9';
+ case '=':
+ case '+':
+ return 'Equal';
+ case 'a':
+ case 'A':
+ return 'KeyA';
+ case 'b':
+ case 'B':
+ return 'KeyB';
+ case 'c':
+ case 'C':
+ return 'KeyC';
+ case 'd':
+ case 'D':
+ return 'KeyD';
+ case 'e':
+ case 'E':
+ return 'KeyE';
+ case 'f':
+ case 'F':
+ return 'KeyF';
+ case 'g':
+ case 'G':
+ return 'KeyG';
+ case 'h':
+ case 'H':
+ return 'KeyH';
+ case 'i':
+ case 'I':
+ return 'KeyI';
+ case 'j':
+ case 'J':
+ return 'KeyJ';
+ case 'k':
+ case 'K':
+ return 'KeyK';
+ case 'l':
+ case 'L':
+ return 'KeyL';
+ case 'm':
+ case 'M':
+ return 'KeyM';
+ case 'n':
+ case 'N':
+ return 'KeyN';
+ case 'o':
+ case 'O':
+ return 'KeyO';
+ case 'p':
+ case 'P':
+ return 'KeyP';
+ case 'q':
+ case 'Q':
+ return 'KeyQ';
+ case 'r':
+ case 'R':
+ return 'KeyR';
+ case 's':
+ case 'S':
+ return 'KeyS';
+ case 't':
+ case 'T':
+ return 'KeyT';
+ case 'u':
+ case 'U':
+ return 'KeyU';
+ case 'v':
+ case 'V':
+ return 'KeyV';
+ case 'w':
+ case 'W':
+ return 'KeyW';
+ case 'x':
+ case 'X':
+ return 'KeyX';
+ case 'y':
+ case 'Y':
+ return 'KeyY';
+ case 'z':
+ case 'Z':
+ return 'KeyZ';
+ case '-':
+ case '_':
+ return 'Minus';
+ case '.':
+ return 'Period';
+ case "'":
+ case '"':
+ return 'Quote';
+ case ';':
+ case ':':
+ return 'Semicolon';
+ case '/':
+ case '?':
+ return 'Slash';
+ case '\uE00A':
+ return 'AltLeft';
+ case '\uE052':
+ return 'AltRight';
+ case '\uE009':
+ return 'ControlLeft';
+ case '\uE051':
+ return 'ControlRight';
+ case '\uE006':
+ return 'Enter';
+ case '\uE03D':
+ return 'MetaLeft';
+ case '\uE053':
+ return 'MetaRight';
+ case '\uE008':
+ return 'ShiftLeft';
+ case '\uE050':
+ return 'ShiftRight';
+ case ' ':
+ case '\uE00D':
+ return 'Space';
+ case '\uE004':
+ return 'Tab';
+ case '\uE017':
+ return 'Delete';
+ case '\uE010':
+ return 'End';
+ case '\uE002':
+ return 'Help';
+ case '\uE011':
+ return 'Home';
+ case '\uE016':
+ return 'Insert';
+ case '\uE00F':
+ return 'PageDown';
+ case '\uE00E':
+ return 'PageUp';
+ case '\uE015':
+ return 'ArrowDown';
+ case '\uE012':
+ return 'ArrowLeft';
+ case '\uE014':
+ return 'ArrowRight';
+ case '\uE013':
+ return 'ArrowUp';
+ case '\uE00C':
+ return 'Escape';
+ case '\uE031':
+ return 'F1';
+ case '\uE032':
+ return 'F2';
+ case '\uE033':
+ return 'F3';
+ case '\uE034':
+ return 'F4';
+ case '\uE035':
+ return 'F5';
+ case '\uE036':
+ return 'F6';
+ case '\uE037':
+ return 'F7';
+ case '\uE038':
+ return 'F8';
+ case '\uE039':
+ return 'F9';
+ case '\uE03A':
+ return 'F10';
+ case '\uE03B':
+ return 'F11';
+ case '\uE03C':
+ return 'F12';
+ case '\uE01A':
+ case '\uE05C':
+ return 'Numpad0';
+ case '\uE01B':
+ case '\uE056':
+ return 'Numpad1';
+ case '\uE01C':
+ case '\uE05B':
+ return 'Numpad2';
+ case '\uE01D':
+ case '\uE055':
+ return 'Numpad3';
+ case '\uE01E':
+ case '\uE058':
+ return 'Numpad4';
+ case '\uE01F':
+ return 'Numpad5';
+ case '\uE020':
+ case '\uE05A':
+ return 'Numpad6';
+ case '\uE021':
+ case '\uE057':
+ return 'Numpad7';
+ case '\uE022':
+ case '\uE059':
+ return 'Numpad8';
+ case '\uE023':
+ case '\uE054':
+ return 'Numpad9';
+ case '\uE025':
+ return 'NumpadAdd';
+ case '\uE026':
+ return 'NumpadComma';
+ case '\uE028':
+ case '\uE05D':
+ return 'NumpadDecimal';
+ case '\uE029':
+ return 'NumpadDivide';
+ case '\uE007':
+ return 'NumpadEnter';
+ case '\uE024':
+ return 'NumpadMultiply';
+ case '\uE027':
+ return 'NumpadSubtract';
+ default:
+ return;
+ }
+}
+keyUtils.getKeyCode = getKeyCode;
+function getKeyLocation(key) {
+ switch (key) {
+ case '\uE007':
+ case '\uE008':
+ case '\uE009':
+ case '\uE00A':
+ case '\uE03D':
+ return 1;
+ case '\uE01A':
+ case '\uE01B':
+ case '\uE01C':
+ case '\uE01D':
+ case '\uE01E':
+ case '\uE01F':
+ case '\uE020':
+ case '\uE021':
+ case '\uE022':
+ case '\uE023':
+ case '\uE024':
+ case '\uE025':
+ case '\uE026':
+ case '\uE027':
+ case '\uE028':
+ case '\uE029':
+ case '\uE054':
+ case '\uE055':
+ case '\uE056':
+ case '\uE057':
+ case '\uE058':
+ case '\uE059':
+ case '\uE05A':
+ case '\uE05B':
+ case '\uE05C':
+ case '\uE05D':
+ return 3;
+ case '\uE050':
+ case '\uE051':
+ case '\uE052':
+ case '\uE053':
+ return 2;
+ default:
+ return 0;
+ }
+}
+keyUtils.getKeyLocation = getKeyLocation;
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(ActionDispatcher$1, "__esModule", { value: true });
+ActionDispatcher$1.ActionDispatcher = void 0;
+const protocol_js_1$a = protocol;
+const assert_js_1 = assert$1;
+const USKeyboardLayout_js_1 = USKeyboardLayout;
+const keyUtils_js_1 = keyUtils;
+/** https://w3c.github.io/webdriver/#dfn-center-point */
+const CALCULATE_IN_VIEW_CENTER_PT_DECL = ((i) => {
+ const t = i.getClientRects()[0], e = Math.max(0, Math.min(t.x, t.x + t.width)), n = Math.min(window.innerWidth, Math.max(t.x, t.x + t.width)), h = Math.max(0, Math.min(t.y, t.y + t.height)), m = Math.min(window.innerHeight, Math.max(t.y, t.y + t.height));
+ return [e + ((n - e) >> 1), h + ((m - h) >> 1)];
+}).toString();
+async function getElementCenter(context, element) {
+ const { result } = await (await context.getOrCreateSandbox(undefined)).callFunction(CALCULATE_IN_VIEW_CENTER_PT_DECL, { type: 'undefined' }, [element], false, 'none', {});
+ if (result.type === 'exception') {
+ throw new protocol_js_1$a.Message.NoSuchNodeException(`Origin element ${element.sharedId} was not found`);
+ }
+ (0, assert_js_1.assert)(result.result.type === 'array');
+ (0, assert_js_1.assert)(result.result.value?.[0]?.type === 'number');
+ (0, assert_js_1.assert)(result.result.value?.[1]?.type === 'number');
+ const { result: { value: [{ value: x }, { value: y }], }, } = result;
+ return { x: x, y: y };
+}
+class ActionDispatcher {
+ #tickStart = 0;
+ #tickDuration = 0;
+ #inputState;
+ #context;
+ constructor(inputState, context) {
+ this.#inputState = inputState;
+ this.#context = context;
+ }
+ async dispatchActions(optionsByTick) {
+ await this.#inputState.queue.run(async () => {
+ for (const options of optionsByTick) {
+ await this.dispatchTickActions(options);
+ }
+ });
+ }
+ async dispatchTickActions(options) {
+ this.#tickStart = performance.now();
+ this.#tickDuration = 0;
+ for (const { action } of options) {
+ if ('duration' in action && action.duration !== undefined) {
+ this.#tickDuration = Math.max(this.#tickDuration, action.duration);
+ }
+ }
+ const promises = [
+ new Promise((resolve) => setTimeout(resolve, this.#tickDuration)),
+ ];
+ for (const option of options) {
+ promises.push(this.#dispatchAction(option));
+ }
+ await Promise.all(promises);
+ }
+ async #dispatchAction({ id, action }) {
+ const source = this.#inputState.get(id);
+ const keyState = this.#inputState.getGlobalKeyState();
+ switch (action.type) {
+ case protocol_js_1$a.Input.ActionType.KeyDown: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchKeyDownAction(source, action);
+ this.#inputState.cancelList.push({
+ id,
+ action: {
+ ...action,
+ type: protocol_js_1$a.Input.ActionType.KeyUp,
+ },
+ });
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.KeyUp: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchKeyUpAction(source, action);
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.Pause: {
+ // TODO: Implement waiting on the input source.
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.PointerDown: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchPointerDownAction(source, keyState, action);
+ this.#inputState.cancelList.push({
+ id,
+ action: {
+ ...action,
+ type: protocol_js_1$a.Input.ActionType.PointerUp,
+ },
+ });
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.PointerMove: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchPointerMoveAction(source, keyState, action);
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.PointerUp: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchPointerUpAction(source, keyState, action);
+ break;
+ }
+ case protocol_js_1$a.Input.ActionType.Scroll: {
+ // SAFETY: The source is validated before.
+ await this.#dispatchScrollAction(source, keyState, action);
+ break;
+ }
+ }
+ }
+ #dispatchPointerDownAction(source, keyState, action) {
+ const { button } = action;
+ if (source.pressed.has(button)) {
+ return;
+ }
+ source.pressed.add(button);
+ const { x, y, subtype: pointerType } = source;
+ const { width, height, pressure, twist, tangentialPressure } = action;
+ const { tiltX, tiltY } = 'tiltX' in action ? action : {};
+ // TODO: Implement azimuth/altitude angle.
+ // --- Platform-specific code begins here ---
+ const { modifiers } = keyState;
+ switch (pointerType) {
+ case protocol_js_1$a.Input.PointerType.Mouse:
+ case protocol_js_1$a.Input.PointerType.Pen:
+ source.setClickCount({ x, y, timeStamp: performance.now() });
+ // TODO: Implement width and height when available.
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
+ type: 'mousePressed',
+ x,
+ y,
+ modifiers,
+ button: (() => {
+ switch (button) {
+ case 0:
+ return 'left';
+ case 1:
+ return 'middle';
+ case 2:
+ return 'right';
+ case 3:
+ return 'back';
+ case 4:
+ return 'forward';
+ default:
+ return 'none';
+ }
+ })(),
+ buttons: source.buttons,
+ clickCount: source.clickCount,
+ pointerType,
+ tangentialPressure,
+ tiltX,
+ tiltY,
+ twist,
+ force: pressure,
+ });
+ case protocol_js_1$a.Input.PointerType.Touch:
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
+ type: 'touchStart',
+ touchPoints: [
+ {
+ x,
+ y,
+ radiusX: width,
+ radiusY: height,
+ tangentialPressure,
+ tiltX,
+ tiltY,
+ twist,
+ force: pressure,
+ id: source.pointerId,
+ },
+ ],
+ modifiers,
+ });
+ }
+ // --- Platform-specific code ends here ---
+ }
+ #dispatchPointerUpAction(source, keyState, action) {
+ const { button } = action;
+ if (!source.pressed.has(button)) {
+ return;
+ }
+ source.pressed.delete(button);
+ const { x, y, subtype: pointerType } = source;
+ // --- Platform-specific code begins here ---
+ const { modifiers } = keyState;
+ switch (pointerType) {
+ case protocol_js_1$a.Input.PointerType.Mouse:
+ case protocol_js_1$a.Input.PointerType.Pen:
+ // TODO: Implement width and height when available.
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
+ type: 'mouseReleased',
+ x,
+ y,
+ modifiers,
+ button: (() => {
+ switch (button) {
+ case 0:
+ return 'left';
+ case 1:
+ return 'middle';
+ case 2:
+ return 'right';
+ case 3:
+ return 'back';
+ case 4:
+ return 'forward';
+ default:
+ return 'none';
+ }
+ })(),
+ buttons: source.buttons,
+ clickCount: source.clickCount,
+ pointerType,
+ });
+ case protocol_js_1$a.Input.PointerType.Touch:
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
+ type: 'touchEnd',
+ touchPoints: [
+ {
+ x,
+ y,
+ id: source.pointerId,
+ },
+ ],
+ modifiers,
+ });
+ }
+ // --- Platform-specific code ends here ---
+ }
+ async #dispatchPointerMoveAction(source, keyState, action) {
+ const { x: startX, y: startY, subtype: pointerType } = source;
+ const { width, height, pressure, twist, tangentialPressure, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
+ const { tiltX, tiltY } = 'tiltX' in action ? action : {};
+ // TODO: Implement azimuth/altitude angle.
+ const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY);
+ if (targetX < 0 || targetY < 0) {
+ throw new protocol_js_1$a.Message.MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
+ }
+ let last;
+ do {
+ const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
+ last = ratio >= 1;
+ let x;
+ let y;
+ if (last) {
+ x = targetX;
+ y = targetY;
+ }
+ else {
+ x = Math.round(ratio * (targetX - startX) + startX);
+ y = Math.round(ratio * (targetY - startY) + startY);
+ }
+ if (source.x !== x || source.y !== y) {
+ // --- Platform-specific code begins here ---
+ const { modifiers } = keyState;
+ switch (pointerType) {
+ case protocol_js_1$a.Input.PointerType.Mouse:
+ case protocol_js_1$a.Input.PointerType.Pen:
+ // TODO: Implement width and height when available.
+ await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
+ type: 'mouseMoved',
+ x,
+ y,
+ modifiers,
+ clickCount: 0,
+ buttons: source.buttons,
+ pointerType,
+ tangentialPressure,
+ tiltX,
+ tiltY,
+ twist,
+ force: pressure,
+ });
+ break;
+ case protocol_js_1$a.Input.PointerType.Touch:
+ await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
+ type: 'touchMove',
+ touchPoints: [
+ {
+ x,
+ y,
+ radiusX: width,
+ radiusY: height,
+ tangentialPressure,
+ tiltX,
+ tiltY,
+ twist,
+ force: pressure,
+ id: source.pointerId,
+ },
+ ],
+ modifiers,
+ });
+ break;
+ }
+ // --- Platform-specific code ends here ---
+ source.x = x;
+ source.y = y;
+ }
+ } while (!last);
+ }
+ async #getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY) {
+ let targetX;
+ let targetY;
+ switch (origin) {
+ case 'viewport':
+ targetX = offsetX;
+ targetY = offsetY;
+ break;
+ case 'pointer':
+ targetX = startX + offsetX;
+ targetY = startY + offsetY;
+ break;
+ default: {
+ const { x: posX, y: posY } = await getElementCenter(this.#context, origin.element);
+ // SAFETY: These can never be special numbers.
+ targetX = posX + offsetX;
+ targetY = posY + offsetY;
+ break;
+ }
+ }
+ return { targetX, targetY };
+ }
+ async #dispatchScrollAction(_source, keyState, action) {
+ const { deltaX: targetDeltaX, deltaY: targetDeltaY, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
+ if (origin === 'pointer') {
+ throw new protocol_js_1$a.Message.InvalidArgumentException('"pointer" origin is invalid for scrolling.');
+ }
+ const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, 0, 0);
+ if (targetX < 0 || targetY < 0) {
+ throw new protocol_js_1$a.Message.MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
+ }
+ let currentDeltaX = 0;
+ let currentDeltaY = 0;
+ let last;
+ do {
+ const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
+ last = ratio >= 1;
+ let deltaX;
+ let deltaY;
+ if (last) {
+ deltaX = targetDeltaX - currentDeltaX;
+ deltaY = targetDeltaY - currentDeltaY;
+ }
+ else {
+ deltaX = Math.round(ratio * targetDeltaX - currentDeltaX);
+ deltaY = Math.round(ratio * targetDeltaY - currentDeltaY);
+ }
+ if (deltaX !== 0 || deltaY !== 0) {
+ // --- Platform-specific code begins here ---
+ const { modifiers } = keyState;
+ await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
+ type: 'mouseWheel',
+ deltaX,
+ deltaY,
+ x: targetX,
+ y: targetY,
+ modifiers,
+ });
+ // --- Platform-specific code ends here ---
+ currentDeltaX += deltaX;
+ currentDeltaY += deltaY;
+ }
+ } while (!last);
+ }
+ #dispatchKeyDownAction(source, action) {
+ const rawKey = action.value;
+ const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);
+ const repeat = source.pressed.has(key);
+ const code = (0, keyUtils_js_1.getKeyCode)(rawKey);
+ const location = (0, keyUtils_js_1.getKeyLocation)(rawKey);
+ switch (key) {
+ case 'Alt':
+ source.alt = true;
+ break;
+ case 'Shift':
+ source.shift = true;
+ break;
+ case 'Control':
+ source.ctrl = true;
+ break;
+ case 'Meta':
+ source.meta = true;
+ break;
+ }
+ source.pressed.add(key);
+ const { modifiers } = source;
+ // --- Platform-specific code begins here ---
+ // The spread is a little hack so JS gives us an array of unicode characters
+ // to measure.
+ const text = [...key].length === 1 ? key : undefined;
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
+ type: text ? 'keyDown' : 'rawKeyDown',
+ windowsVirtualKeyCode: USKeyboardLayout_js_1.KeyToKeyCode[key],
+ key,
+ code,
+ text,
+ unmodifiedText: text,
+ autoRepeat: repeat,
+ isSystemKey: source.alt || undefined,
+ location: location < 2 ? location : undefined,
+ isKeypad: location === 3,
+ modifiers,
+ });
+ // --- Platform-specific code ends here ---
+ }
+ #dispatchKeyUpAction(source, action) {
+ const rawKey = action.value;
+ const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);
+ if (!source.pressed.has(key)) {
+ return;
+ }
+ const code = (0, keyUtils_js_1.getKeyCode)(rawKey);
+ const location = (0, keyUtils_js_1.getKeyLocation)(rawKey);
+ switch (key) {
+ case 'Alt':
+ source.alt = false;
+ break;
+ case 'Shift':
+ source.shift = false;
+ break;
+ case 'Control':
+ source.ctrl = false;
+ break;
+ case 'Meta':
+ source.meta = false;
+ break;
+ }
+ source.pressed.delete(key);
+ const { modifiers } = source;
+ // --- Platform-specific code begins here ---
+ // The spread is a little hack so JS gives us an array of unicode characters
+ // to measure.
+ const text = [...key].length === 1 ? key : undefined;
+ return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
+ type: 'keyUp',
+ windowsVirtualKeyCode: USKeyboardLayout_js_1.KeyToKeyCode[key],
+ key,
+ code,
+ text,
+ unmodifiedText: text,
+ location: location < 2 ? location : undefined,
+ isSystemKey: source.alt || undefined,
+ isKeypad: location === 3,
+ modifiers,
+ });
+ // --- Platform-specific code ends here ---
+ }
+}
+ActionDispatcher$1.ActionDispatcher = ActionDispatcher;
+
+var PreloadScriptStorage$1 = {};
+
+var uuid = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(uuid, "__esModule", { value: true });
+uuid.uuidv4 = void 0;
+/**
+ * Generates a random v4 UUID, as specified in RFC4122.
+ *
+ * Uses the native Web Crypto API if available, otherwise falls back to a
+ * polyfill.
+ *
+ * Example: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
+ */
+function uuidv4() {
+ // Available only in secure contexts
+ // https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
+ if ('crypto' in globalThis && 'randomUUID' in globalThis.crypto) {
+ // Node with
+ // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1 or
+ // secure browser context.
+ return globalThis.crypto.randomUUID();
+ }
+ const randomValues = new Uint8Array(16);
+ if ('crypto' in globalThis && 'getRandomValues' in globalThis.crypto) {
+ // Node with
+ // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1 or
+ // browser.
+ globalThis.crypto.getRandomValues(randomValues);
+ }
+ else {
+ // Node without
+ // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1.
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
+ require$$5.webcrypto.getRandomValues(randomValues);
+ }
+ // Set version (4) and variant (RFC4122) bits.
+ randomValues[6] = (randomValues[6] & 0x0f) | 0x40;
+ randomValues[8] = (randomValues[8] & 0x3f) | 0x80;
+ const bytesToHex = (bytes) => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
+ return [
+ bytesToHex(randomValues.subarray(0, 4)),
+ bytesToHex(randomValues.subarray(4, 6)),
+ bytesToHex(randomValues.subarray(6, 8)),
+ bytesToHex(randomValues.subarray(8, 10)),
+ bytesToHex(randomValues.subarray(10, 16)),
+ ].join('-');
+}
+uuid.uuidv4 = uuidv4;
+
+Object.defineProperty(PreloadScriptStorage$1, "__esModule", { value: true });
+PreloadScriptStorage$1.PreloadScriptStorage = void 0;
+/*
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+const uuid_js_1 = uuid;
+/**
+ * Container class for preload scripts.
+ *
+ * BiDi IDs are generated by the server and are unique within the context.
+ *
+ * CDP preload script IDs are generated by the client and are unique
+ * within the session.
+ *
+ * The mapping between BiDi and CDP preload script IDs is 1:many.
+ * BiDi IDs are needed by the mapper to keep track of potential multiple CDP IDs
+ * in the client.
+ *
+ * This class does not concern itself with the validity of the IDs.
+ */
+class PreloadScriptStorage {
+ /** Tracks all BiDi preload scripts. */
+ #scripts = new Set();
+ /** Finds all entries that match the given filter. */
+ findPreloadScripts(filter) {
+ if (!filter) {
+ return [...this.#scripts];
+ }
+ return [...this.#scripts].filter((script) => {
+ if (filter.id !== undefined && filter.id !== script.id) {
+ return false;
+ }
+ if (filter.contextId !== undefined &&
+ filter.contextId !== script.contextId) {
+ return false;
+ }
+ if (filter.contextIds !== undefined &&
+ !filter.contextIds.includes(script.contextId)) {
+ return false;
+ }
+ return true;
+ });
+ }
+ /**
+ * Keeps track of the given CDP preload scripts associated with the given
+ * browsing context ID.
+ *
+ * @param contextId Browsing context ID, or null for global context.
+ * @param cdpPreloadScripts CDP preload scripts.
+ * @param functionDeclaration The script itself, in a format expected by the spec
+ * i.e. a function.
+ */
+ addPreloadScripts(contextId, cdpPreloadScripts, functionDeclaration, sandbox) {
+ // Generate a random ID.
+ const bidiId = (0, uuid_js_1.uuidv4)();
+ const preloadScript = {
+ id: bidiId,
+ contextId,
+ cdpPreloadScripts,
+ functionDeclaration,
+ sandbox,
+ };
+ this.#scripts.add(preloadScript);
+ return preloadScript;
+ }
+ /**
+ * Keeps track of the given CDP preload script in the given BiDi preload
+ * script.
+ */
+ appendCdpPreloadScript(script, cdpPreloadScript) {
+ script.cdpPreloadScripts.push(cdpPreloadScript);
+ }
+ /** Deletes all BiDi preload script entries that match the given filter. */
+ removeBiDiPreloadScripts(filter) {
+ for (const preloadScript of this.findPreloadScripts(filter)) {
+ this.#scripts.delete(preloadScript);
+ }
+ }
+ /** Deletes all CDP preload script entries that match the given filter. */
+ removeCdpPreloadScripts(filter) {
+ for (const preloadScript of this.#scripts) {
+ preloadScript.cdpPreloadScripts = preloadScript.cdpPreloadScripts.filter((cdpPreloadScript) => {
+ if (filter?.targetId !== undefined &&
+ filter.targetId !== cdpPreloadScript.target.targetId) {
+ return true;
+ }
+ if (filter?.sessionId !== undefined &&
+ filter.sessionId !== cdpPreloadScript.target.cdpSessionId) {
+ return true;
+ }
+ return false;
+ });
+ }
+ }
+}
+PreloadScriptStorage$1.PreloadScriptStorage = PreloadScriptStorage;
+
+var browsingContextImpl = {};
+
+var unitConversions = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(unitConversions, "__esModule", { value: true });
+unitConversions.inchesFromCm = void 0;
+/** @return Given an input in cm, convert it to inches. */
+function inchesFromCm(cm) {
+ return cm / 2.54;
+}
+unitConversions.inchesFromCm = inchesFromCm;
+
+var deferred = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(deferred, "__esModule", { value: true });
+deferred.Deferred = void 0;
+class Deferred {
+ #isFinished = false;
+ #promise;
+ #resolve;
+ #reject;
+ get isFinished() {
+ return this.#isFinished;
+ }
+ constructor() {
+ this.#promise = new Promise((resolve, reject) => {
+ this.#resolve = resolve;
+ this.#reject = reject;
+ });
+ // Needed to avoid `Uncaught (in promise)`. The promises returned by `then`
+ // and `catch` will be rejected anyway.
+ this.#promise.catch((_error) => {
+ // Intentionally empty.
+ });
+ }
+ then(onFulfilled, onRejected) {
+ return this.#promise.then(onFulfilled, onRejected);
+ }
+ catch(onRejected) {
+ return this.#promise.catch(onRejected);
+ }
+ resolve(value) {
+ this.#isFinished = true;
+ this.#resolve?.(value);
+ }
+ reject(reason) {
+ this.#isFinished = true;
+ this.#reject?.(reason);
+ }
+ finally(onFinally) {
+ return this.#promise.finally(onFinally);
+ }
+ [Symbol.toStringTag] = 'Promise';
+}
+deferred.Deferred = Deferred;
+
+var realm = {};
+
+var scriptEvaluator = {};
+
+(function (exports) {
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.ScriptEvaluator = exports.SHARED_ID_DIVIDER = void 0;
+ const protocol_js_1 = protocol;
+ // As `script.evaluate` wraps call into serialization script, `lineNumber`
+ // should be adjusted.
+ const CALL_FUNCTION_STACKTRACE_LINE_OFFSET = 1;
+ const EVALUATE_STACKTRACE_LINE_OFFSET = 0;
+ exports.SHARED_ID_DIVIDER = '_element_';
+ class ScriptEvaluator {
+ #eventManager;
+ constructor(eventManager) {
+ this.#eventManager = eventManager;
+ }
+ /**
+ * Gets the string representation of an object. This is equivalent to
+ * calling toString() on the object value.
+ * @param cdpObject CDP remote object representing an object.
+ * @param realm
+ * @return string The stringified object.
+ */
+ static async stringifyObject(cdpObject, realm) {
+ const stringifyResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((obj) => {
+ return String(obj);
+ }),
+ awaitPromise: false,
+ arguments: [cdpObject],
+ returnByValue: true,
+ executionContextId: realm.executionContextId,
+ });
+ return stringifyResult.result.value;
+ }
+ /**
+ * Serializes a given CDP object into BiDi, keeping references in the
+ * target's `globalThis`.
+ * @param cdpRemoteObject CDP remote object to be serialized.
+ * @param resultOwnership Indicates desired ResultOwnership.
+ * @param realm
+ */
+ async serializeCdpObject(cdpRemoteObject, resultOwnership, realm) {
+ const arg = ScriptEvaluator.#cdpRemoteObjectToCallArgument(cdpRemoteObject);
+ const cdpWebDriverValue = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((obj) => obj),
+ awaitPromise: false,
+ arguments: [arg],
+ serializationOptions: {
+ serialization: 'deep',
+ },
+ executionContextId: realm.executionContextId,
+ });
+ return realm.cdpToBidiValue(cdpWebDriverValue, resultOwnership);
+ }
+ async scriptEvaluate(realm, expression, awaitPromise, resultOwnership, serializationOptions) {
+ if (![0, null, undefined].includes(serializationOptions.maxDomDepth))
+ throw new Error('serializationOptions.maxDomDepth other than 0 or null is not supported');
+ const cdpEvaluateResult = await realm.cdpClient.sendCommand('Runtime.evaluate', {
+ contextId: realm.executionContextId,
+ expression,
+ awaitPromise,
+ serializationOptions: {
+ serialization: 'deep',
+ ...(serializationOptions.maxObjectDepth === undefined ||
+ serializationOptions.maxObjectDepth === null
+ ? {}
+ : { maxDepth: serializationOptions.maxObjectDepth }),
+ },
+ });
+ if (cdpEvaluateResult.exceptionDetails) {
+ // Serialize exception details.
+ return {
+ exceptionDetails: await this.#serializeCdpExceptionDetails(cdpEvaluateResult.exceptionDetails, EVALUATE_STACKTRACE_LINE_OFFSET, resultOwnership, realm),
+ type: 'exception',
+ realm: realm.realmId,
+ };
+ }
+ return {
+ type: 'success',
+ result: realm.cdpToBidiValue(cdpEvaluateResult, resultOwnership),
+ realm: realm.realmId,
+ };
+ }
+ async callFunction(realm, functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions) {
+ if (![0, null, undefined].includes(serializationOptions.maxDomDepth))
+ throw new Error('serializationOptions.maxDomDepth other than 0 or null is not supported');
+ const callFunctionAndSerializeScript = `(...args)=>{ return _callFunction((\n${functionDeclaration}\n), args);
+ function _callFunction(f, args) {
+ const deserializedThis = args.shift();
+ const deserializedArgs = args;
+ return f.apply(deserializedThis, deserializedArgs);
+ }}`;
+ const thisAndArgumentsList = [
+ await this.#deserializeToCdpArg(_this, realm),
+ ];
+ thisAndArgumentsList.push(...(await Promise.all(_arguments.map(async (a) => {
+ return this.#deserializeToCdpArg(a, realm);
+ }))));
+ let cdpCallFunctionResult;
+ try {
+ cdpCallFunctionResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: callFunctionAndSerializeScript,
+ awaitPromise,
+ arguments: thisAndArgumentsList,
+ serializationOptions: {
+ serialization: 'deep',
+ ...(serializationOptions.maxObjectDepth === undefined ||
+ serializationOptions.maxObjectDepth === null
+ ? {}
+ : { maxDepth: serializationOptions.maxObjectDepth }),
+ },
+ executionContextId: realm.executionContextId,
+ });
+ }
+ catch (e) {
+ // Heuristic to determine if the problem is in the argument.
+ // The check can be done on the `deserialization` step, but this approach
+ // helps to save round-trips.
+ if (e.code === -32000 &&
+ [
+ 'Could not find object with given id',
+ 'Argument should belong to the same JavaScript world as target object',
+ 'Invalid remote object id',
+ ].includes(e.message)) {
+ throw new protocol_js_1.Message.NoSuchHandleException('Handle was not found.');
+ }
+ throw e;
+ }
+ if (cdpCallFunctionResult.exceptionDetails) {
+ // Serialize exception details.
+ return {
+ exceptionDetails: await this.#serializeCdpExceptionDetails(cdpCallFunctionResult.exceptionDetails, CALL_FUNCTION_STACKTRACE_LINE_OFFSET, resultOwnership, realm),
+ type: 'exception',
+ realm: realm.realmId,
+ };
+ }
+ return {
+ type: 'success',
+ result: realm.cdpToBidiValue(cdpCallFunctionResult, resultOwnership),
+ realm: realm.realmId,
+ };
+ }
+ static #cdpRemoteObjectToCallArgument(cdpRemoteObject) {
+ if (cdpRemoteObject.objectId !== undefined) {
+ return { objectId: cdpRemoteObject.objectId };
+ }
+ if (cdpRemoteObject.unserializableValue !== undefined) {
+ return { unserializableValue: cdpRemoteObject.unserializableValue };
+ }
+ return { value: cdpRemoteObject.value };
+ }
+ async #deserializeToCdpArg(argumentValue, realm) {
+ if ('sharedId' in argumentValue) {
+ const [navigableId, rawBackendNodeId] = argumentValue.sharedId.split(exports.SHARED_ID_DIVIDER);
+ const backendNodeId = parseInt(rawBackendNodeId ?? '');
+ if (isNaN(backendNodeId) ||
+ backendNodeId === undefined ||
+ navigableId === undefined) {
+ throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" was not found.`);
+ }
+ if (realm.navigableId !== navigableId) {
+ throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" belongs to different document. Current document is ${realm.navigableId}.`);
+ }
+ try {
+ const obj = await realm.cdpClient.sendCommand('DOM.resolveNode', {
+ backendNodeId,
+ executionContextId: realm.executionContextId,
+ });
+ // TODO(#375): Release `obj.object.objectId` after using.
+ return { objectId: obj.object.objectId };
+ }
+ catch (e) {
+ // Heuristic to detect "no such node" exception. Based on the specific
+ // CDP implementation.
+ if (e.code === -32000 && e.message === 'No node with given id found') {
+ throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" was not found.`);
+ }
+ throw e;
+ }
+ }
+ if ('handle' in argumentValue) {
+ return { objectId: argumentValue.handle };
+ }
+ switch (argumentValue.type) {
+ // Primitive Protocol Value
+ // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue
+ case 'undefined':
+ return { unserializableValue: 'undefined' };
+ case 'null':
+ return { unserializableValue: 'null' };
+ case 'string':
+ return { value: argumentValue.value };
+ case 'number':
+ if (argumentValue.value === 'NaN') {
+ return { unserializableValue: 'NaN' };
+ }
+ else if (argumentValue.value === '-0') {
+ return { unserializableValue: '-0' };
+ }
+ else if (argumentValue.value === 'Infinity') {
+ return { unserializableValue: 'Infinity' };
+ }
+ else if (argumentValue.value === '-Infinity') {
+ return { unserializableValue: '-Infinity' };
+ }
+ return {
+ value: argumentValue.value,
+ };
+ case 'boolean':
+ return { value: Boolean(argumentValue.value) };
+ case 'bigint':
+ return {
+ unserializableValue: `BigInt(${JSON.stringify(argumentValue.value)})`,
+ };
+ case 'date':
+ return {
+ unserializableValue: `new Date(Date.parse(${JSON.stringify(argumentValue.value)}))`,
+ };
+ case 'regexp':
+ return {
+ unserializableValue: `new RegExp(${JSON.stringify(argumentValue.value.pattern)}, ${JSON.stringify(argumentValue.value.flags)})`,
+ };
+ case 'map': {
+ // TODO: If none of the nested keys and values has a remote
+ // reference, serialize to `unserializableValue` without CDP roundtrip.
+ const keyValueArray = await this.#flattenKeyValuePairs(argumentValue.value, realm);
+ const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((...args) => {
+ const result = new Map();
+ for (let i = 0; i < args.length; i += 2) {
+ result.set(args[i], args[i + 1]);
+ }
+ return result;
+ }),
+ awaitPromise: false,
+ arguments: keyValueArray,
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ });
+ // TODO(#375): Release `argEvalResult.result.objectId` after using.
+ return { objectId: argEvalResult.result.objectId };
+ }
+ case 'object': {
+ // TODO: If none of the nested keys and values has a remote
+ // reference, serialize to `unserializableValue` without CDP roundtrip.
+ const keyValueArray = await this.#flattenKeyValuePairs(argumentValue.value, realm);
+ const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((...args) => {
+ const result = {};
+ for (let i = 0; i < args.length; i += 2) {
+ // Key should be either `string`, `number`, or `symbol`.
+ const key = args[i];
+ result[key] = args[i + 1];
+ }
+ return result;
+ }),
+ awaitPromise: false,
+ arguments: keyValueArray,
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ });
+ // TODO(#375): Release `argEvalResult.result.objectId` after using.
+ return { objectId: argEvalResult.result.objectId };
+ }
+ case 'array': {
+ // TODO: If none of the nested items has a remote reference,
+ // serialize to `unserializableValue` without CDP roundtrip.
+ const args = await this.#flattenValueList(argumentValue.value, realm);
+ const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((...args) => {
+ return args;
+ }),
+ awaitPromise: false,
+ arguments: args,
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ });
+ // TODO(#375): Release `argEvalResult.result.objectId` after using.
+ return { objectId: argEvalResult.result.objectId };
+ }
+ case 'set': {
+ // TODO: if none of the nested items has a remote reference,
+ // serialize to `unserializableValue` without CDP roundtrip.
+ const args = await this.#flattenValueList(argumentValue.value, realm);
+ const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((...args) => {
+ return new Set(args);
+ }),
+ awaitPromise: false,
+ arguments: args,
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ });
+ // TODO(#375): Release `argEvalResult.result.objectId` after using.
+ return { objectId: argEvalResult.result.objectId };
+ }
+ case 'channel': {
+ const createChannelHandleResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String(() => {
+ const queue = [];
+ let queueNonEmptyResolver = null;
+ return {
+ /**
+ * Gets a promise, which is resolved as soon as a message occurs
+ * in the queue.
+ */
+ async getMessage() {
+ const onMessage = queue.length > 0
+ ? Promise.resolve()
+ : new Promise((resolve) => {
+ queueNonEmptyResolver = resolve;
+ });
+ await onMessage;
+ return queue.shift();
+ },
+ /**
+ * Adds a message to the queue.
+ * Resolves the pending promise if needed.
+ */
+ sendMessage(message) {
+ queue.push(message);
+ if (queueNonEmptyResolver !== null) {
+ queueNonEmptyResolver();
+ queueNonEmptyResolver = null;
+ }
+ },
+ };
+ }),
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ serializationOptions: {
+ serialization: 'deep',
+ },
+ });
+ const channelHandle = createChannelHandleResult.result.objectId;
+ // Long-poll the message queue asynchronously.
+ void this.#initChannelListener(argumentValue, channelHandle, realm);
+ const sendMessageArgResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String((channelHandle) => {
+ return channelHandle.sendMessage;
+ }),
+ arguments: [
+ {
+ objectId: channelHandle,
+ },
+ ],
+ returnByValue: false,
+ executionContextId: realm.executionContextId,
+ serializationOptions: {
+ serialization: 'deep',
+ },
+ });
+ return { objectId: sendMessageArgResult.result.objectId };
+ }
+ // TODO(#375): Dispose of nested objects.
+ default:
+ throw new Error(`Value ${JSON.stringify(argumentValue)} is not deserializable.`);
+ }
+ }
+ async #flattenKeyValuePairs(mapping, realm) {
+ const keyValueArray = [];
+ for (const [key, value] of mapping) {
+ let keyArg;
+ if (typeof key === 'string') {
+ // Key is a string.
+ keyArg = { value: key };
+ }
+ else {
+ // Key is a serialized value.
+ keyArg = await this.#deserializeToCdpArg(key, realm);
+ }
+ const valueArg = await this.#deserializeToCdpArg(value, realm);
+ keyValueArray.push(keyArg);
+ keyValueArray.push(valueArg);
+ }
+ return keyValueArray;
+ }
+ async #flattenValueList(list, realm) {
+ return Promise.all(list.map((value) => this.#deserializeToCdpArg(value, realm)));
+ }
+ async #initChannelListener(channel, channelHandle, realm) {
+ const channelId = channel.value.channel;
+ // TODO(#294): Remove this loop after the realm is destroyed.
+ // Rely on the CDP throwing exception in such a case.
+ for (;;) {
+ const message = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
+ functionDeclaration: String(async (channelHandle) => channelHandle.getMessage()),
+ arguments: [
+ {
+ objectId: channelHandle,
+ },
+ ],
+ awaitPromise: true,
+ executionContextId: realm.executionContextId,
+ serializationOptions: {
+ serialization: 'deep',
+ },
+ });
+ this.#eventManager.registerEvent({
+ method: protocol_js_1.Script.EventNames.MessageEvent,
+ params: {
+ channel: channelId,
+ data: realm.cdpToBidiValue(message, channel.value.ownership ?? 'none'),
+ source: {
+ realm: realm.realmId,
+ context: realm.browsingContextId,
+ },
+ },
+ }, realm.browsingContextId);
+ }
+ }
+ async #serializeCdpExceptionDetails(cdpExceptionDetails, lineOffset, resultOwnership, realm) {
+ const callFrames = cdpExceptionDetails.stackTrace?.callFrames.map((frame) => ({
+ url: frame.url,
+ functionName: frame.functionName,
+ // As `script.evaluate` wraps call into serialization script, so
+ // `lineNumber` should be adjusted.
+ lineNumber: frame.lineNumber - lineOffset,
+ columnNumber: frame.columnNumber,
+ }));
+ const exception = await this.serializeCdpObject(
+ // Exception should always be there.
+ cdpExceptionDetails.exception, resultOwnership, realm);
+ const text = await ScriptEvaluator.stringifyObject(cdpExceptionDetails.exception, realm);
+ return {
+ exception,
+ columnNumber: cdpExceptionDetails.columnNumber,
+ // As `script.evaluate` wraps call into serialization script, so
+ // `lineNumber` should be adjusted.
+ lineNumber: cdpExceptionDetails.lineNumber - lineOffset,
+ stackTrace: {
+ callFrames: callFrames || [],
+ },
+ text: text || cdpExceptionDetails.text,
+ };
+ }
+ }
+ exports.ScriptEvaluator = ScriptEvaluator;
+
+} (scriptEvaluator));
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(realm, "__esModule", { value: true });
+realm.Realm = void 0;
+const log_js_1$5 = log;
+const scriptEvaluator_js_1 = scriptEvaluator;
+class Realm {
+ #realmStorage;
+ #browsingContextStorage;
+ #realmId;
+ #browsingContextId;
+ #executionContextId;
+ #origin;
+ #type;
+ #cdpClient;
+ #eventManager;
+ #scriptEvaluator;
+ sandbox;
+ cdpSessionId;
+ #logger;
+ constructor(realmStorage, browsingContextStorage, realmId, browsingContextId, executionContextId, origin, type, sandbox, cdpSessionId, cdpClient, eventManager, logger) {
+ this.#realmId = realmId;
+ this.#browsingContextId = browsingContextId;
+ this.#executionContextId = executionContextId;
+ this.sandbox = sandbox;
+ this.#origin = origin;
+ this.#type = type;
+ this.cdpSessionId = cdpSessionId;
+ this.#cdpClient = cdpClient;
+ this.#realmStorage = realmStorage;
+ this.#browsingContextStorage = browsingContextStorage;
+ this.#eventManager = eventManager;
+ this.#scriptEvaluator = new scriptEvaluator_js_1.ScriptEvaluator(this.#eventManager);
+ this.#realmStorage.realmMap.set(this.#realmId, this);
+ this.#logger = logger;
+ }
+ async #releaseObject(handle) {
+ try {
+ await this.cdpClient.sendCommand('Runtime.releaseObject', {
+ objectId: handle,
+ });
+ }
+ catch (e) {
+ // Heuristic to determine if the problem is in the unknown handler.
+ // Ignore the error if so.
+ if (!(e.code === -32000 && e.message === 'Invalid remote object id')) {
+ throw e;
+ }
+ }
+ }
+ async disown(handle) {
+ // Disowning an object from different realm does nothing.
+ if (this.#realmStorage.knownHandlesToRealm.get(handle) !== this.realmId) {
+ return;
+ }
+ await this.#releaseObject(handle);
+ this.#realmStorage.knownHandlesToRealm.delete(handle);
+ }
+ cdpToBidiValue(cdpValue, resultOwnership) {
+ const deepSerializedValue = cdpValue.result.deepSerializedValue;
+ const bidiValue = this.deepSerializedToBiDi(deepSerializedValue);
+ if (cdpValue.result.objectId) {
+ const objectId = cdpValue.result.objectId;
+ if (resultOwnership === 'root') {
+ // Extend BiDi value with `handle` based on required `resultOwnership`
+ // and CDP response but not on the actual BiDi type.
+ bidiValue.handle = objectId;
+ // Remember all the handles sent to client.
+ this.#realmStorage.knownHandlesToRealm.set(objectId, this.realmId);
+ }
+ else {
+ // No need in awaiting for the object to be released.
+ void this.#releaseObject(objectId).catch((error) => this.#logger?.(log_js_1$5.LogType.system, error));
+ }
+ }
+ return bidiValue;
+ }
+ deepSerializedToBiDi(webDriverValue) {
+ // This relies on the CDP to implement proper BiDi serialization, except
+ // backendNodeId/sharedId and `platformobject`.
+ const result = webDriverValue;
+ if (Object.hasOwn(result, 'weakLocalObjectReference')) {
+ result.internalId = `${result.weakLocalObjectReference}`;
+ delete result['weakLocalObjectReference'];
+ }
+ // Platform object is a special case. It should have only `{type: object}`
+ // without `value` field.
+ if (result.type === 'platformobject') {
+ return { type: 'object' };
+ }
+ const bidiValue = result.value;
+ if (bidiValue === undefined) {
+ return result;
+ }
+ if (result.type === 'node') {
+ if (Object.hasOwn(bidiValue, 'backendNodeId')) {
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ result.sharedId = `${this.navigableId}${scriptEvaluator_js_1.SHARED_ID_DIVIDER}${bidiValue.backendNodeId}`;
+ delete bidiValue['backendNodeId'];
+ }
+ if (Object.hasOwn(bidiValue, 'children')) {
+ for (const i in bidiValue.children) {
+ bidiValue.children[i] = this.deepSerializedToBiDi(bidiValue.children[i]);
+ }
+ }
+ }
+ // Recursively update the nested values.
+ if (['array', 'set'].includes(webDriverValue.type)) {
+ for (const i in bidiValue) {
+ bidiValue[i] = this.deepSerializedToBiDi(bidiValue[i]);
+ }
+ }
+ if (['object', 'map'].includes(webDriverValue.type)) {
+ for (const i in bidiValue) {
+ bidiValue[i] = [
+ this.deepSerializedToBiDi(bidiValue[i][0]),
+ this.deepSerializedToBiDi(bidiValue[i][1]),
+ ];
+ }
+ }
+ return result;
+ }
+ toBiDi() {
+ return {
+ realm: this.realmId,
+ origin: this.origin,
+ type: this.type,
+ context: this.browsingContextId,
+ ...(this.sandbox === undefined ? {} : { sandbox: this.sandbox }),
+ };
+ }
+ get realmId() {
+ return this.#realmId;
+ }
+ get navigableId() {
+ return (this.#browsingContextStorage.findContext(this.#browsingContextId)
+ ?.navigableId ?? 'UNKNOWN');
+ }
+ get browsingContextId() {
+ return this.#browsingContextId;
+ }
+ get executionContextId() {
+ return this.#executionContextId;
+ }
+ get origin() {
+ return this.#origin;
+ }
+ get type() {
+ return this.#type;
+ }
+ get cdpClient() {
+ return this.#cdpClient;
+ }
+ async callFunction(functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions) {
+ const context = this.#browsingContextStorage.getContext(this.browsingContextId);
+ await context.awaitUnblocked();
+ return {
+ result: await this.#scriptEvaluator.callFunction(this, functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions),
+ };
+ }
+ async scriptEvaluate(expression, awaitPromise, resultOwnership, serializationOptions) {
+ const context = this.#browsingContextStorage.getContext(this.browsingContextId);
+ await context.awaitUnblocked();
+ return {
+ result: await this.#scriptEvaluator.scriptEvaluate(this, expression, awaitPromise, resultOwnership, serializationOptions),
+ };
+ }
+ /**
+ * Serializes a given CDP object into BiDi, keeping references in the
+ * target's `globalThis`.
+ * @param cdpObject CDP remote object to be serialized.
+ * @param resultOwnership Indicates desired ResultOwnership.
+ */
+ async serializeCdpObject(cdpObject, resultOwnership) {
+ return this.#scriptEvaluator.serializeCdpObject(cdpObject, resultOwnership, this);
+ }
+ /**
+ * Gets the string representation of an object. This is equivalent to
+ * calling toString() on the object value.
+ * @param cdpObject CDP remote object representing an object.
+ * @return string The stringified object.
+ */
+ async stringifyObject(cdpObject) {
+ return scriptEvaluator_js_1.ScriptEvaluator.stringifyObject(cdpObject, this);
+ }
+}
+realm.Realm = Realm;
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(browsingContextImpl, "__esModule", { value: true });
+browsingContextImpl.BrowsingContextImpl = void 0;
+const unitConversions_js_1 = unitConversions;
+const protocol_js_1$9 = protocol;
+const log_js_1$4 = log;
+const deferred_js_1$2 = deferred;
+const realm_js_1 = realm;
+class BrowsingContextImpl {
+ /** The ID of this browsing context. */
+ #id;
+ /**
+ * The ID of the parent browsing context.
+ * If null, this is a top-level context.
+ */
+ #parentId;
+ /** Direct children browsing contexts. */
+ #children = new Set();
+ #browsingContextStorage;
+ #deferreds = {
+ documentInitialized: new deferred_js_1$2.Deferred(),
+ Page: {
+ navigatedWithinDocument: new deferred_js_1$2.Deferred(),
+ lifecycleEvent: {
+ DOMContentLoaded: new deferred_js_1$2.Deferred(),
+ load: new deferred_js_1$2.Deferred(),
+ },
+ },
+ };
+ #url = 'about:blank';
+ #eventManager;
+ #realmStorage;
+ #loaderId;
+ #cdpTarget;
+ #maybeDefaultRealm;
+ #logger;
+ constructor(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger) {
+ this.#cdpTarget = cdpTarget;
+ this.#realmStorage = realmStorage;
+ this.#id = id;
+ this.#parentId = parentId;
+ this.#eventManager = eventManager;
+ this.#browsingContextStorage = browsingContextStorage;
+ this.#logger = logger;
+ }
+ static create(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger) {
+ const context = new BrowsingContextImpl(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger);
+ context.#initListeners();
+ browsingContextStorage.addContext(context);
+ if (!context.isTopLevelContext()) {
+ context.parent.addChild(context.id);
+ }
+ eventManager.registerEvent({
+ method: protocol_js_1$9.BrowsingContext.EventNames.ContextCreatedEvent,
+ params: context.serializeToBidiValue(),
+ }, context.id);
+ return context;
+ }
+ /**
+ * @see https://html.spec.whatwg.org/multipage/document-sequences.html#navigable
+ */
+ get navigableId() {
+ return this.#loaderId;
+ }
+ delete() {
+ this.#deleteAllChildren();
+ this.#realmStorage.deleteRealms({
+ browsingContextId: this.id,
+ });
+ // Remove context from the parent.
+ if (!this.isTopLevelContext()) {
+ this.parent.#children.delete(this.id);
+ }
+ this.#eventManager.registerEvent({
+ method: protocol_js_1$9.BrowsingContext.EventNames.ContextDestroyedEvent,
+ params: this.serializeToBidiValue(),
+ }, this.id);
+ this.#browsingContextStorage.deleteContextById(this.id);
+ }
+ /** Returns the ID of this context. */
+ get id() {
+ return this.#id;
+ }
+ /** Returns the parent context ID. */
+ get parentId() {
+ return this.#parentId;
+ }
+ /** Returns the parent context. */
+ get parent() {
+ if (this.parentId === null) {
+ return null;
+ }
+ return this.#browsingContextStorage.getContext(this.parentId);
+ }
+ /** Returns all direct children contexts. */
+ get directChildren() {
+ return [...this.#children].map((id) => this.#browsingContextStorage.getContext(id));
+ }
+ /** Returns all children contexts, flattened. */
+ get allChildren() {
+ const children = this.directChildren;
+ return children.concat(...children.map((child) => child.allChildren));
+ }
+ /**
+ * Returns true if this is a top-level context.
+ * This is the case whenever the parent context ID is null.
+ */
+ isTopLevelContext() {
+ return this.#parentId === null;
+ }
+ get top() {
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ let topContext = this;
+ let parent = topContext.parent;
+ while (parent) {
+ topContext = parent;
+ parent = topContext.parent;
+ }
+ return topContext;
+ }
+ addChild(childId) {
+ this.#children.add(childId);
+ }
+ #deleteAllChildren() {
+ this.directChildren.map((child) => child.delete());
+ }
+ get #defaultRealm() {
+ if (this.#maybeDefaultRealm === undefined) {
+ throw new Error(`No default realm for browsing context ${this.#id}`);
+ }
+ return this.#maybeDefaultRealm;
+ }
+ get cdpTarget() {
+ return this.#cdpTarget;
+ }
+ updateCdpTarget(cdpTarget) {
+ this.#cdpTarget = cdpTarget;
+ this.#initListeners();
+ }
+ get url() {
+ return this.#url;
+ }
+ async awaitLoaded() {
+ await this.#deferreds.Page.lifecycleEvent.load;
+ }
+ awaitUnblocked() {
+ return this.#cdpTarget.targetUnblocked;
+ }
+ async getOrCreateSandbox(sandbox) {
+ if (sandbox === undefined || sandbox === '') {
+ return this.#defaultRealm;
+ }
+ let maybeSandboxes = this.#realmStorage.findRealms({
+ browsingContextId: this.id,
+ sandbox,
+ });
+ if (maybeSandboxes.length === 0) {
+ await this.#cdpTarget.cdpClient.sendCommand('Page.createIsolatedWorld', {
+ frameId: this.id,
+ worldName: sandbox,
+ });
+ // `Runtime.executionContextCreated` should be emitted by the time the
+ // previous command is done.
+ maybeSandboxes = this.#realmStorage.findRealms({
+ browsingContextId: this.id,
+ sandbox,
+ });
+ }
+ if (maybeSandboxes.length !== 1) {
+ throw Error(`Sandbox ${sandbox} wasn't created.`);
+ }
+ return maybeSandboxes[0];
+ }
+ serializeToBidiValue(maxDepth = 0, addParentField = true) {
+ return {
+ context: this.#id,
+ url: this.url,
+ children: maxDepth > 0
+ ? this.directChildren.map((c) => c.serializeToBidiValue(maxDepth - 1, false))
+ : null,
+ ...(addParentField ? { parent: this.#parentId } : {}),
+ };
+ }
+ #initListeners() {
+ this.#cdpTarget.cdpClient.on('Target.targetInfoChanged', (params) => {
+ if (this.id !== params.targetInfo.targetId) {
+ return;
+ }
+ this.#url = params.targetInfo.url;
+ });
+ this.#cdpTarget.cdpClient.on('Page.frameNavigated', (params) => {
+ if (this.id !== params.frame.id) {
+ return;
+ }
+ this.#url = params.frame.url + (params.frame.urlFragment ?? '');
+ // At the point the page is initialized, all the nested iframes from the
+ // previous page are detached and realms are destroyed.
+ // Remove children from context.
+ this.#deleteAllChildren();
+ });
+ this.#cdpTarget.cdpClient.on('Page.navigatedWithinDocument', (params) => {
+ if (this.id !== params.frameId) {
+ return;
+ }
+ this.#url = params.url;
+ this.#deferreds.Page.navigatedWithinDocument.resolve(params);
+ });
+ this.#cdpTarget.cdpClient.on('Page.lifecycleEvent', (params) => {
+ if (this.id !== params.frameId) {
+ return;
+ }
+ // `timestamp` from the event is MonotonicTime, not real time, so
+ // the best Mapper can do is to set the timestamp to the epoch time
+ // of the event arrived.
+ // https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-MonotonicTime
+ const timestamp = new Date().getTime();
+ switch (params.name) {
+ case 'init':
+ this.#documentChanged(params.loaderId);
+ this.#deferreds.documentInitialized.resolve();
+ break;
+ case 'commit':
+ this.#loaderId = params.loaderId;
+ break;
+ case 'DOMContentLoaded':
+ this.#deferreds.Page.lifecycleEvent.DOMContentLoaded.resolve(params);
+ this.#eventManager.registerEvent({
+ method: protocol_js_1$9.BrowsingContext.EventNames.DomContentLoadedEvent,
+ params: {
+ context: this.id,
+ navigation: this.#loaderId ?? null,
+ timestamp,
+ url: this.#url,
+ },
+ }, this.id);
+ break;
+ case 'load':
+ this.#deferreds.Page.lifecycleEvent.load.resolve(params);
+ this.#eventManager.registerEvent({
+ method: protocol_js_1$9.BrowsingContext.EventNames.LoadEvent,
+ params: {
+ context: this.id,
+ navigation: this.#loaderId ?? null,
+ timestamp,
+ url: this.#url,
+ },
+ }, this.id);
+ break;
+ }
+ if (params.loaderId !== this.#loaderId) {
+ return;
+ }
+ });
+ this.#cdpTarget.cdpClient.on('Runtime.executionContextCreated', (params) => {
+ if (params.context.auxData.frameId !== this.id) {
+ return;
+ }
+ // Only this execution contexts are supported for now.
+ if (!['default', 'isolated'].includes(params.context.auxData.type)) {
+ return;
+ }
+ const realm = new realm_js_1.Realm(this.#realmStorage, this.#browsingContextStorage, params.context.uniqueId, this.id, params.context.id, this.#getOrigin(params),
+ // XXX: differentiate types.
+ 'window',
+ // Sandbox name for isolated world.
+ params.context.auxData.type === 'isolated'
+ ? params.context.name
+ : undefined, this.#cdpTarget.cdpSessionId, this.#cdpTarget.cdpClient, this.#eventManager, this.#logger);
+ if (params.context.auxData.isDefault) {
+ this.#maybeDefaultRealm = realm;
+ }
+ });
+ this.#cdpTarget.cdpClient.on('Runtime.executionContextDestroyed', (params) => {
+ this.#realmStorage.deleteRealms({
+ cdpSessionId: this.#cdpTarget.cdpSessionId,
+ executionContextId: params.executionContextId,
+ });
+ });
+ this.#cdpTarget.cdpClient.on('Runtime.executionContextsCleared', () => {
+ this.#realmStorage.deleteRealms({
+ cdpSessionId: this.#cdpTarget.cdpSessionId,
+ });
+ });
+ }
+ #getOrigin(params) {
+ if (params.context.auxData.type === 'isolated') {
+ // Sandbox should have the same origin as the context itself, but in CDP
+ // it has an empty one.
+ return this.#defaultRealm.origin;
+ }
+ // https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin
+ return ['://', ''].includes(params.context.origin)
+ ? 'null'
+ : params.context.origin;
+ }
+ #documentChanged(loaderId) {
+ // Same document navigation.
+ if (loaderId === undefined || this.#loaderId === loaderId) {
+ if (this.#deferreds.Page.navigatedWithinDocument.isFinished) {
+ this.#deferreds.Page.navigatedWithinDocument =
+ new deferred_js_1$2.Deferred();
+ }
+ else {
+ this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (navigatedWithinDocument)');
+ }
+ return;
+ }
+ this.#resetDeferredsIfFinished();
+ this.#loaderId = loaderId;
+ }
+ #resetDeferredsIfFinished() {
+ if (this.#deferreds.documentInitialized.isFinished) {
+ this.#deferreds.documentInitialized = new deferred_js_1$2.Deferred();
+ }
+ else {
+ this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (document initialized)');
+ }
+ if (this.#deferreds.Page.lifecycleEvent.DOMContentLoaded.isFinished) {
+ this.#deferreds.Page.lifecycleEvent.DOMContentLoaded =
+ new deferred_js_1$2.Deferred();
+ }
+ else {
+ this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (DOMContentLoaded)');
+ }
+ if (this.#deferreds.Page.lifecycleEvent.load.isFinished) {
+ this.#deferreds.Page.lifecycleEvent.load =
+ new deferred_js_1$2.Deferred();
+ }
+ else {
+ this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (load)');
+ }
+ }
+ async navigate(url, wait) {
+ await this.awaitUnblocked();
+ // TODO: handle loading errors.
+ const cdpNavigateResult = await this.#cdpTarget.cdpClient.sendCommand('Page.navigate', {
+ url,
+ frameId: this.id,
+ });
+ if (cdpNavigateResult.errorText) {
+ throw new protocol_js_1$9.Message.UnknownErrorException(cdpNavigateResult.errorText);
+ }
+ this.#documentChanged(cdpNavigateResult.loaderId);
+ switch (wait) {
+ case 'none':
+ break;
+ case 'interactive':
+ // No `loaderId` means same-document navigation.
+ if (cdpNavigateResult.loaderId === undefined) {
+ await this.#deferreds.Page.navigatedWithinDocument;
+ }
+ else {
+ await this.#deferreds.Page.lifecycleEvent.DOMContentLoaded;
+ }
+ break;
+ case 'complete':
+ // No `loaderId` means same-document navigation.
+ if (cdpNavigateResult.loaderId === undefined) {
+ await this.#deferreds.Page.navigatedWithinDocument;
+ }
+ else {
+ await this.awaitLoaded();
+ }
+ break;
+ }
+ return {
+ result: {
+ navigation: cdpNavigateResult.loaderId ?? null,
+ url,
+ },
+ };
+ }
+ async reload(ignoreCache, wait) {
+ await this.awaitUnblocked();
+ await this.#cdpTarget.cdpClient.sendCommand('Page.reload', {
+ ignoreCache,
+ });
+ this.#resetDeferredsIfFinished();
+ switch (wait) {
+ case 'none':
+ break;
+ case 'interactive':
+ await this.#deferreds.Page.lifecycleEvent.DOMContentLoaded;
+ break;
+ case 'complete':
+ await this.awaitLoaded();
+ break;
+ }
+ return { result: {} };
+ }
+ async captureScreenshot() {
+ const [, result] = await Promise.all([
+ // XXX: Either make this a proposal in the BiDi spec, or focus the
+ // original tab right after the screenshot is taken.
+ // The screenshot command gets blocked until we focus the active tab.
+ this.#cdpTarget.cdpClient.sendCommand('Page.bringToFront'),
+ this.#cdpTarget.cdpClient.sendCommand('Page.captureScreenshot', {}),
+ ]);
+ return {
+ result: {
+ data: result.data,
+ },
+ };
+ }
+ async print(params) {
+ const printToPdfCdpParams = {
+ printBackground: params.background,
+ landscape: params.orientation === 'landscape',
+ pageRanges: params.pageRanges?.join(',') ?? '',
+ scale: params.scale,
+ preferCSSPageSize: !params.shrinkToFit,
+ };
+ if (params.margin?.bottom) {
+ printToPdfCdpParams.marginBottom = (0, unitConversions_js_1.inchesFromCm)(params.margin.bottom);
+ }
+ if (params.margin?.left) {
+ printToPdfCdpParams.marginLeft = (0, unitConversions_js_1.inchesFromCm)(params.margin.left);
+ }
+ if (params.margin?.right) {
+ printToPdfCdpParams.marginRight = (0, unitConversions_js_1.inchesFromCm)(params.margin.right);
+ }
+ if (params.margin?.top) {
+ printToPdfCdpParams.marginTop = (0, unitConversions_js_1.inchesFromCm)(params.margin.top);
+ }
+ if (params.page?.height) {
+ printToPdfCdpParams.paperHeight = (0, unitConversions_js_1.inchesFromCm)(params.page.height);
+ }
+ if (params.page?.width) {
+ printToPdfCdpParams.paperWidth = (0, unitConversions_js_1.inchesFromCm)(params.page.width);
+ }
+ const result = await this.#cdpTarget.cdpClient.sendCommand('Page.printToPDF', printToPdfCdpParams);
+ return {
+ result: {
+ data: result.data,
+ },
+ };
+ }
+}
+browsingContextImpl.BrowsingContextImpl = BrowsingContextImpl;
+
+var cdpTarget = {};
+
+var logManager = {};
+
+var logHelper = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(logHelper, "__esModule", { value: true });
+logHelper.getRemoteValuesText = logHelper.logMessageFormatter = void 0;
+const specifiers = ['%s', '%d', '%i', '%f', '%o', '%O', '%c'];
+function isFormmatSpecifier(str) {
+ return specifiers.some((spec) => str.includes(spec));
+}
+/**
+ * @param args input remote values to be format printed
+ * @return parsed text of the remote values in specific format
+ */
+function logMessageFormatter(args) {
+ let output = '';
+ const argFormat = args[0].value.toString();
+ const argValues = args.slice(1, undefined);
+ const tokens = argFormat.split(new RegExp(specifiers.map((spec) => `(${spec})`).join('|'), 'g'));
+ for (const token of tokens) {
+ if (token === undefined || token === '') {
+ continue;
+ }
+ if (isFormmatSpecifier(token)) {
+ const arg = argValues.shift();
+ // raise an exception when less value is provided
+ if (arg === undefined) {
+ throw new Error(`Less value is provided: "${getRemoteValuesText(args, false)}"`);
+ }
+ if (token === '%s') {
+ output += stringFromArg(arg);
+ }
+ else if (token === '%d' || token === '%i') {
+ if (arg.type === 'bigint' ||
+ arg.type === 'number' ||
+ arg.type === 'string') {
+ output += parseInt(arg.value.toString(), 10);
+ }
+ else {
+ output += 'NaN';
+ }
+ }
+ else if (token === '%f') {
+ if (arg.type === 'bigint' ||
+ arg.type === 'number' ||
+ arg.type === 'string') {
+ output += parseFloat(arg.value.toString());
+ }
+ else {
+ output += 'NaN';
+ }
+ }
+ else {
+ // %o, %O, %c
+ output += toJson(arg);
+ }
+ }
+ else {
+ output += token;
+ }
+ }
+ // raise an exception when more value is provided
+ if (argValues.length > 0) {
+ throw new Error(`More value is provided: "${getRemoteValuesText(args, false)}"`);
+ }
+ return output;
+}
+logHelper.logMessageFormatter = logMessageFormatter;
+/**
+ * @param arg input remote value to be parsed
+ * @return parsed text of the remote value
+ *
+ * input: {"type": "number", "value": 1}
+ * output: 1
+ *
+ * input: {"type": "string", "value": "abc"}
+ * output: "abc"
+ *
+ * input: {"type": "object", "value": [["id", {"type": "number", "value": 1}]]}
+ * output: '{"id": 1}'
+ *
+ * input: {"type": "object", "value": [["font-size", {"type": "string", "value": "20px"}]]}
+ * output: '{"font-size": "20px"}'
+ */
+function toJson(arg) {
+ // arg type validation
+ if (arg.type !== 'array' &&
+ arg.type !== 'bigint' &&
+ arg.type !== 'date' &&
+ arg.type !== 'number' &&
+ arg.type !== 'object' &&
+ arg.type !== 'string') {
+ return stringFromArg(arg);
+ }
+ if (arg.type === 'bigint') {
+ return `${arg.value.toString()}n`;
+ }
+ if (arg.type === 'number') {
+ return arg.value.toString();
+ }
+ if (['date', 'string'].includes(arg.type)) {
+ return JSON.stringify(arg.value);
+ }
+ if (arg.type === 'object') {
+ return `{${arg.value
+ .map((pair) => {
+ return `${JSON.stringify(pair[0])}:${toJson(pair[1])}`;
+ })
+ .join(',')}}`;
+ }
+ if (arg.type === 'array') {
+ return `[${arg.value?.map((val) => toJson(val)).join(',') ?? ''}]`;
+ }
+ throw Error(`Invalid value type: ${arg.toString()}`);
+}
+function stringFromArg(arg) {
+ if (!Object.hasOwn(arg, 'value')) {
+ return arg.type;
+ }
+ switch (arg.type) {
+ case 'string':
+ case 'number':
+ case 'boolean':
+ case 'bigint':
+ return String(arg.value);
+ case 'regexp':
+ return `/${arg.value.pattern}/${arg.value.flags ?? ''}`;
+ case 'date':
+ return new Date(arg.value).toString();
+ case 'object':
+ return `Object(${arg.value?.length ?? ''})`;
+ case 'array':
+ return `Array(${arg.value?.length ?? ''})`;
+ case 'map':
+ return `Map(${arg.value.length})`;
+ case 'set':
+ return `Set(${arg.value.length})`;
+ case 'node':
+ return 'node';
+ default:
+ return arg.type;
+ }
+}
+function getRemoteValuesText(args, formatText) {
+ const arg = args[0];
+ if (!arg) {
+ return '';
+ }
+ // if args[0] is a format specifier, format the args as output
+ if (arg.type === 'string' &&
+ isFormmatSpecifier(arg.value.toString()) &&
+ formatText) {
+ return logMessageFormatter(args);
+ }
+ // if args[0] is not a format specifier, just join the args with \u0020 (unicode 'SPACE')
+ return args
+ .map((arg) => {
+ return stringFromArg(arg);
+ })
+ .join('\u0020');
+}
+logHelper.getRemoteValuesText = getRemoteValuesText;
+
+Object.defineProperty(logManager, "__esModule", { value: true });
+logManager.LogManager = void 0;
+const protocol_js_1$8 = protocol;
+const logHelper_js_1 = logHelper;
+/** Converts CDP StackTrace object to BiDi StackTrace object. */
+function getBidiStackTrace(cdpStackTrace) {
+ const stackFrames = cdpStackTrace?.callFrames.map((callFrame) => {
+ return {
+ columnNumber: callFrame.columnNumber,
+ functionName: callFrame.functionName,
+ lineNumber: callFrame.lineNumber,
+ url: callFrame.url,
+ };
+ });
+ return stackFrames ? { callFrames: stackFrames } : undefined;
+}
+function getLogLevel(consoleApiType) {
+ if (['assert', 'error'].includes(consoleApiType)) {
+ return 'error';
+ }
+ if (['debug', 'trace'].includes(consoleApiType)) {
+ return 'debug';
+ }
+ if (['warn', 'warning'].includes(consoleApiType)) {
+ return 'warn';
+ }
+ return 'info';
+}
+class LogManager {
+ #eventManager;
+ #realmStorage;
+ #cdpTarget;
+ constructor(cdpTarget, realmStorage, eventManager) {
+ this.#cdpTarget = cdpTarget;
+ this.#realmStorage = realmStorage;
+ this.#eventManager = eventManager;
+ }
+ static create(cdpTarget, realmStorage, eventManager) {
+ const logManager = new LogManager(cdpTarget, realmStorage, eventManager);
+ logManager.#initialize();
+ return logManager;
+ }
+ #initialize() {
+ this.#initializeLogEntryAddedEventListener();
+ }
+ #initializeLogEntryAddedEventListener() {
+ this.#cdpTarget.cdpClient.on('Runtime.consoleAPICalled', (params) => {
+ // Try to find realm by `cdpSessionId` and `executionContextId`,
+ // if provided.
+ const realm = this.#realmStorage.findRealm({
+ cdpSessionId: this.#cdpTarget.cdpSessionId,
+ executionContextId: params.executionContextId,
+ });
+ const argsPromise = realm === undefined
+ ? Promise.resolve(params.args)
+ : // Properly serialize arguments if possible.
+ Promise.all(params.args.map((arg) => {
+ return realm.serializeCdpObject(arg, 'none');
+ }));
+ this.#eventManager.registerPromiseEvent(argsPromise.then((args) => ({
+ method: protocol_js_1$8.Log.EventNames.LogEntryAddedEvent,
+ params: {
+ level: getLogLevel(params.type),
+ source: {
+ realm: realm?.realmId ?? 'UNKNOWN',
+ context: realm?.browsingContextId ?? 'UNKNOWN',
+ },
+ text: (0, logHelper_js_1.getRemoteValuesText)(args, true),
+ timestamp: Math.round(params.timestamp),
+ stackTrace: getBidiStackTrace(params.stackTrace),
+ type: 'console',
+ // Console method is `warn`, not `warning`.
+ method: params.type === 'warning' ? 'warn' : params.type,
+ args,
+ },
+ })), realm?.browsingContextId ?? 'UNKNOWN', protocol_js_1$8.Log.EventNames.LogEntryAddedEvent);
+ });
+ this.#cdpTarget.cdpClient.on('Runtime.exceptionThrown', (params) => {
+ // Try to find realm by `cdpSessionId` and `executionContextId`,
+ // if provided.
+ const realm = this.#realmStorage.findRealm({
+ cdpSessionId: this.#cdpTarget.cdpSessionId,
+ executionContextId: params.exceptionDetails.executionContextId,
+ });
+ // Try all the best to get the exception text.
+ const textPromise = (async () => {
+ if (!params.exceptionDetails.exception) {
+ return params.exceptionDetails.text;
+ }
+ if (realm === undefined) {
+ return JSON.stringify(params.exceptionDetails.exception);
+ }
+ return realm.stringifyObject(params.exceptionDetails.exception);
+ })();
+ this.#eventManager.registerPromiseEvent(textPromise.then((text) => ({
+ method: protocol_js_1$8.Log.EventNames.LogEntryAddedEvent,
+ params: {
+ level: 'error',
+ source: {
+ realm: realm?.realmId ?? 'UNKNOWN',
+ context: realm?.browsingContextId ?? 'UNKNOWN',
+ },
+ text,
+ timestamp: Math.round(params.timestamp),
+ stackTrace: getBidiStackTrace(params.exceptionDetails.stackTrace),
+ type: 'javascript',
+ },
+ })), realm?.browsingContextId ?? 'UNKNOWN', protocol_js_1$8.Log.EventNames.LogEntryAddedEvent);
+ });
+ }
+}
+logManager.LogManager = LogManager;
+
+var networkProcessor = {};
+
+var DefaultMap$1 = {};
+
+/**
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(DefaultMap$1, "__esModule", { value: true });
+DefaultMap$1.DefaultMap = void 0;
+/**
+ * A subclass of Map whose functionality is almost the same as its parent
+ * except for the fact that DefaultMap never returns undefined. It provides a
+ * default value for keys that do not exist.
+ */
+class DefaultMap extends Map {
+ /** The default value to return whenever a key is not present in the map. */
+ #getDefaultValue;
+ constructor(getDefaultValue, entries) {
+ super(entries);
+ this.#getDefaultValue = getDefaultValue;
+ }
+ get(key) {
+ if (!this.has(key)) {
+ this.set(key, this.#getDefaultValue(key));
+ }
+ return super.get(key);
+ }
+}
+DefaultMap$1.DefaultMap = DefaultMap;
+
+var networkRequest = {};
+
+/*
+ * Copyright 2023 Google LLC.
+ * 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.
+ *
+ */
+Object.defineProperty(networkRequest, "__esModule", { value: true });
+networkRequest.NetworkRequest = void 0;
+const deferred_js_1$1 = deferred;
+const protocol_js_1$7 = protocol;
+class NetworkRequest {
+ static #unknown = 'UNKNOWN';
+ /**
+ * Each network request has an associated request id, which is a string
+ * uniquely identifying that request.
+ *
+ * The identifier for a request resulting from a redirect matches that of the
+ * request that initiated it.
+ */
+ requestId;
+ #servedFromCache = false;
+ #redirectCount;
+ #eventManager;
+ #requestWillBeSentEvent;
+ #requestWillBeSentExtraInfoEvent;
+ #responseReceivedEvent;
+ #responseReceivedExtraInfoEvent;
+ #beforeRequestSentDeferred;
+ #responseReceivedDeferred;
+ constructor(requestId, eventManager) {
+ this.requestId = requestId;
+ this.#redirectCount = 0;
+ this.#eventManager = eventManager;
+ this.#beforeRequestSentDeferred = new deferred_js_1$1.Deferred();
+ this.#responseReceivedDeferred = new deferred_js_1$1.Deferred();
+ }
+ onRequestWillBeSentEvent(event) {
+ if (this.#requestWillBeSentEvent !== undefined) {
+ // TODO: Handle redirect event, requestId is same for the redirect chain
+ return;
+ }
+ this.#requestWillBeSentEvent = event;
+ if (this.#requestWillBeSentExtraInfoEvent !== undefined) {
+ this.#beforeRequestSentDeferred.resolve();
+ }
+ this.#sendBeforeRequestEvent();
+ }
+ onRequestWillBeSentExtraInfoEvent(event) {
+ if (this.#requestWillBeSentExtraInfoEvent !== undefined) {
+ // TODO: Handle redirect event, requestId is same for the redirect chain
+ return;
+ }
+ this.#requestWillBeSentExtraInfoEvent = event;
+ if (this.#requestWillBeSentEvent !== undefined) {
+ this.#beforeRequestSentDeferred.resolve();
+ }
+ }
+ onResponseReceivedEventExtraInfo(event) {
+ if (this.#responseReceivedExtraInfoEvent !== undefined) {
+ // TODO: Handle redirect event, requestId is same for the redirect chain
+ return;
+ }
+ this.#responseReceivedExtraInfoEvent = event;
+ if (this.#responseReceivedEvent !== undefined) {
+ this.#responseReceivedDeferred.resolve();
+ }
+ }
+ onResponseReceivedEvent(responseReceivedEvent) {
+ if (this.#responseReceivedEvent !== undefined) {
+ // TODO: Handle redirect event, requestId is same for the redirect chain
+ return;
+ }
+ this.#responseReceivedEvent = responseReceivedEvent;
+ if (!responseReceivedEvent.hasExtraInfo &&
+ !this.#beforeRequestSentDeferred.isFinished) {
+ this.#beforeRequestSentDeferred.resolve();
+ }
+ if (!responseReceivedEvent.hasExtraInfo ||
+ this.#responseReceivedExtraInfoEvent !== undefined ||
+ this.#servedFromCache) {
+ this.#responseReceivedDeferred.resolve();
+ }
+ this.#sendResponseReceivedEvent();
+ }
+ onServedFromCache() {
+ if (this.#requestWillBeSentEvent !== undefined) {
+ this.#beforeRequestSentDeferred.resolve();
+ }
+ if (this.#responseReceivedEvent !== undefined) {
+ this.#responseReceivedDeferred.resolve();
+ }
+ this.#servedFromCache = true;
+ }
+ onLoadingFailedEvent(event) {
+ this.#beforeRequestSentDeferred.resolve();
+ this.#responseReceivedDeferred.reject(event);
+ this.#eventManager.registerEvent({
+ method: protocol_js_1$7.Network.EventNames.FetchErrorEvent,
+ params: {
+ ...this.#getBaseEventParams(),
+ errorText: event.errorText,
+ },
+ }, this.#requestWillBeSentEvent?.frameId ?? null);
+ }
+ #getBaseEventParams() {
+ return {
+ context: this.#requestWillBeSentEvent?.frameId ?? null,
+ navigation: this.#requestWillBeSentEvent?.loaderId ?? null,
+ // TODO: implement.
+ redirectCount: this.#redirectCount,
+ request: this.#getRequestData(),
+ // Timestamp should be in milliseconds, while CDP provides it in seconds.
+ timestamp: Math.round((this.#requestWillBeSentEvent?.wallTime ?? 0) * 1000),
+ };
+ }
+ #getRequestData() {
+ const cookies = this.#requestWillBeSentExtraInfoEvent
+ ? NetworkRequest.#getCookies(this.#requestWillBeSentExtraInfoEvent.associatedCookies)
+ : [];
+ return {
+ request: this.#requestWillBeSentEvent?.requestId ?? NetworkRequest.#unknown,
+ url: this.#requestWillBeSentEvent?.request.url ?? NetworkRequest.#unknown,
+ method: this.#requestWillBeSentEvent?.request.method ?? NetworkRequest.#unknown,
+ headers: Object.keys(this.#requestWillBeSentEvent?.request.headers ?? []).map((key) => ({
+ name: key,
+ value: this.#requestWillBeSentEvent?.request.headers[key],
+ })),
+ cookies,
+ // TODO: implement.
+ headersSize: -1,
+ // TODO: implement.
+ bodySize: 0,
+ timings: {
+ // TODO: implement.
+ timeOrigin: 0,
+ // TODO: implement.
+ requestTime: 0,
+ // TODO: implement.
+ redirectStart: 0,
+ // TODO: implement.
+ redirectEnd: 0,
+ // TODO: implement.
+ fetchStart: 0,
+ // TODO: implement.
+ dnsStart: 0,
+ // TODO: implement.
+ dnsEnd: 0,
+ // TODO: implement.
+ connectStart: 0,
+ // TODO: implement.
+ connectEnd: 0,
+ // TODO: implement.
+ tlsStart: 0,
+ // TODO: implement.
+ tlsEnd: 0,
+ // TODO: implement.
+ requestStart: 0,
+ // TODO: implement.
+ responseStart: 0,
+ // TODO: implement.
+ responseEnd: 0,
+ },
+ };
+ }
+ #sendBeforeRequestEvent() {
+ if (!this.#isIgnoredEvent()) {
+ this.#eventManager.registerPromiseEvent(this.#beforeRequestSentDeferred.then(() => this.#getBeforeRequestEvent()), this.#requestWillBeSentEvent?.frameId ?? null, protocol_js_1$7.Network.EventNames.BeforeRequestSentEvent);
+ }
+ }
+ #getBeforeRequestEvent() {
+ if (this.#requestWillBeSentEvent === undefined) {
+ throw new Error('RequestWillBeSentEvent is not set');
+ }
+ return {
+ method: protocol_js_1$7.Network.EventNames.BeforeRequestSentEvent,
+ params: {
+ ...this.#getBaseEventParams(),
+ initiator: {
+ type: NetworkRequest.#getInitiatorType(this.#requestWillBeSentEvent.initiator.type),
+ },
+ },
+ };
+ }
+ #sendResponseReceivedEvent() {
+ if (!this.#isIgnoredEvent()) {
+ this.#eventManager.registerPromiseEvent(this.#responseReceivedDeferred.then(() => this.#getResponseReceivedEvent()), this.#responseReceivedEvent?.frameId ?? null, protocol_js_1$7.Network.EventNames.ResponseCompletedEvent);
+ }
+ }
+ #getResponseReceivedEvent() {
+ if (this.#requestWillBeSentEvent === undefined) {
+ throw new Error('RequestWillBeSentEvent is not set');
+ }
+ if (this.#responseReceivedEvent === undefined) {
+ throw new Error('ResponseReceivedEvent is not set');
+ }
+ // Chromium sends wrong extraInfo events for responses served from cache.
+ // See https://github.com/puppeteer/puppeteer/issues/9965 and
+ // https://crbug.com/1340398.
+ if (this.#responseReceivedEvent.response.fromDiskCache) {
+ this.#responseReceivedExtraInfoEvent = undefined;
+ }
+ return {
+ method: protocol_js_1$7.Network.EventNames.ResponseCompletedEvent,
+ params: {
+ ...this.#getBaseEventParams(),
+ response: {
+ url: this.#responseReceivedEvent.response.url,
+ protocol: this.#responseReceivedEvent.response.protocol ?? '',
+ status: this.#responseReceivedExtraInfoEvent?.statusCode ||
+ this.#responseReceivedEvent.response.status,
+ statusText: this.#responseReceivedEvent.response.statusText,
+ fromCache: (this.#responseReceivedEvent.response.fromDiskCache ||
+ this.#responseReceivedEvent.response.fromPrefetchCache) ??
+ false,
+ headers: NetworkRequest.#getHeaders(this.#responseReceivedEvent.response.headers),
+ mimeType: this.#responseReceivedEvent.response.mimeType,
+ bytesReceived: this.#responseReceivedEvent.response.encodedDataLength,
+ headersSize: this.#responseReceivedExtraInfoEvent?.headersText?.length ?? 0,
+ // TODO: consider removing from spec.
+ bodySize: 0,
+ content: {
+ // TODO: consider removing from spec.
+ size: 0,
+ },
+ },
+ },
+ };
+ }
+ #isIgnoredEvent() {
+ return (this.#requestWillBeSentEvent?.request.url.endsWith('/favicon.ico') ??
+ false);
+ }
+ static #getHeaders(headers) {
+ return Object.keys(headers).map((key) => ({
+ name: key,
+ value: headers[key],
+ }));
+ }
+ static #getInitiatorType(initiatorType) {
+ switch (initiatorType) {
+ case 'parser':
+ case 'script':
+ case 'preflight':
+ return initiatorType;
+ default:
+ return 'other';
+ }
+ }
+ static #getCookies(associatedCookies) {
+ return associatedCookies.map((cookieInfo) => {
+ return {
+ name: cookieInfo.cookie.name,
+ value: cookieInfo.cookie.value,
+ domain: cookieInfo.cookie.domain,
+ path: cookieInfo.cookie.path,
+ expires: cookieInfo.cookie.expires,
+ size: cookieInfo.cookie.size,
+ httpOnly: cookieInfo.cookie.httpOnly,
+ secure: cookieInfo.cookie.secure,
+ sameSite: NetworkRequest.#getCookiesSameSite(cookieInfo.cookie.sameSite),
+ };
+ });
+ }
+ static #getCookiesSameSite(cdpSameSiteValue) {
+ switch (cdpSameSiteValue) {
+ case 'Strict':
+ return 'strict';
+ case 'Lax':
+ return 'lax';
+ default:
+ return 'none';
+ }
+ }
+}
+networkRequest.NetworkRequest = NetworkRequest;
+
+/*
+ * Copyright 2023 Google LLC.
+ * 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.
+ */
+Object.defineProperty(networkProcessor, "__esModule", { value: true });
+networkProcessor.NetworkProcessor = void 0;
+const DefaultMap_js_1$1 = DefaultMap$1;
+const networkRequest_js_1 = networkRequest;
+class NetworkProcessor {
+ #eventManager;
+ /**
+ * Map of request ID to NetworkRequest objects. Needed as long as information
+ * about requests comes from different events.
+ */
+ #requestMap;
+ constructor(eventManager) {
+ this.#eventManager = eventManager;
+ this.#requestMap = new DefaultMap_js_1$1.DefaultMap((requestId) => new networkRequest_js_1.NetworkRequest(requestId, this.#eventManager));
+ }
+ static async create(cdpClient, eventManager) {
+ const networkProcessor = new NetworkProcessor(eventManager);
+ cdpClient.on('Network.requestWillBeSent', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onRequestWillBeSentEvent(params);
+ });
+ cdpClient.on('Network.requestWillBeSentExtraInfo', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onRequestWillBeSentExtraInfoEvent(params);
+ });
+ cdpClient.on('Network.responseReceived', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onResponseReceivedEvent(params);
+ });
+ cdpClient.on('Network.responseReceivedExtraInfo', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onResponseReceivedEventExtraInfo(params);
+ });
+ cdpClient.on('Network.loadingFailed', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onLoadingFailedEvent(params);
+ });
+ cdpClient.on('Network.requestServedFromCache', (params) => {
+ networkProcessor
+ .#getOrCreateNetworkRequest(params.requestId)
+ .onServedFromCache();
+ });
+ await cdpClient.sendCommand('Network.enable');
+ return networkProcessor;
+ }
+ #getOrCreateNetworkRequest(requestId) {
+ return this.#requestMap.get(requestId);
+ }
+}
+networkProcessor.NetworkProcessor = NetworkProcessor;
+
+Object.defineProperty(cdpTarget, "__esModule", { value: true });
+cdpTarget.CdpTarget = void 0;
+const logManager_js_1 = logManager;
+const protocol_js_1$6 = protocol;
+const deferred_js_1 = deferred;
+const networkProcessor_js_1 = networkProcessor;
+const log_js_1$3 = log;
+class CdpTarget {
+ #targetId;
+ #parentTargetId;
+ #cdpClient;
+ #cdpSessionId;
+ #eventManager;
+ #preloadScriptStorage;
+ #logger;
+ #targetUnblocked;
+ #networkDomainActivated;
+ #browsingContextStorage;
+ static create(targetId, parentTargetId, cdpClient, cdpSessionId, realmStorage, eventManager, preloadScriptStorage, browsingContextStorage, logger) {
+ const cdpTarget = new CdpTarget(targetId, parentTargetId, cdpClient, cdpSessionId, eventManager, preloadScriptStorage, browsingContextStorage, logger);
+ logManager_js_1.LogManager.create(cdpTarget, realmStorage, eventManager);
+ cdpTarget.#setEventListeners();
+ // No need to await.
+ // Deferred will be resolved when the target is unblocked.
+ void cdpTarget.#unblock();
+ return cdpTarget;
+ }
+ constructor(targetId, parentTargetId, cdpClient, cdpSessionId, eventManager, preloadScriptStorage, browsingContextStorage, logger) {
+ this.#targetId = targetId;
+ this.#parentTargetId = parentTargetId;
+ this.#cdpClient = cdpClient;
+ this.#cdpSessionId = cdpSessionId;
+ this.#eventManager = eventManager;
+ this.#preloadScriptStorage = preloadScriptStorage;
+ this.#browsingContextStorage = browsingContextStorage;
+ this.#logger = logger;
+ this.#networkDomainActivated = false;
+ this.#targetUnblocked = new deferred_js_1.Deferred();
+ }
+ /** Returns a promise that resolves when the target is unblocked. */
+ get targetUnblocked() {
+ return this.#targetUnblocked;
+ }
+ get targetId() {
+ return this.#targetId;
+ }
+ get cdpClient() {
+ return this.#cdpClient;
+ }
+ /**
+ * Needed for CDP escape path.
+ */
+ get cdpSessionId() {
+ return this.#cdpSessionId;
+ }
+ /**
+ * Enables all the required CDP domains and unblocks the target.
+ */
+ async #unblock() {
+ try {
+ // Enable Network domain, if it is enabled globally.
+ // TODO: enable Network domain for OOPiF targets.
+ if (this.#eventManager.isNetworkDomainEnabled) {
+ await this.enableNetworkDomain();
+ }
+ await this.#cdpClient.sendCommand('Runtime.enable');
+ await this.#cdpClient.sendCommand('Page.enable');
+ await this.#cdpClient.sendCommand('Page.setLifecycleEventsEnabled', {
+ enabled: true,
+ });
+ await this.#cdpClient.sendCommand('Target.setAutoAttach', {
+ autoAttach: true,
+ waitForDebuggerOnStart: true,
+ flatten: true,
+ });
+ await this.#loadPreloadScripts();
+ await this.#cdpClient.sendCommand('Runtime.runIfWaitingForDebugger');
+ }
+ catch (error) {
+ // The target might have been closed before the initialization finished.
+ if (!this.#cdpClient.isCloseError(error)) {
+ throw error;
+ }
+ }
+ this.#targetUnblocked.resolve();
+ }
+ /**
+ * Enables the Network domain (creates NetworkProcessor on the target's cdp
+ * client) if it is not enabled yet.
+ */
+ async enableNetworkDomain() {
+ if (!this.#networkDomainActivated) {
+ this.#networkDomainActivated = true;
+ await networkProcessor_js_1.NetworkProcessor.create(this.cdpClient, this.#eventManager);
+ }
+ }
+ #setEventListeners() {
+ this.#cdpClient.on('*', (cdpMethod, params) => {
+ this.#eventManager.registerEvent({
+ method: protocol_js_1$6.CDP.EventNames.EventReceivedEvent,
+ params: {
+ cdpMethod: cdpMethod,
+ cdpParams: params ?? {},
+ cdpSession: this.#cdpSessionId,
+ },
+ }, null);
+ });
+ }
+ /** Loads all top-level and parent preload scripts. */
+ async #loadPreloadScripts() {
+ for (const script of this.#preloadScriptStorage.findPreloadScripts({
+ contextIds: [null, this.#parentTargetId],
+ })) {
+ const { functionDeclaration, sandbox } = script;
+ // The spec provides a function, and CDP expects an evaluation.
+ const cdpPreloadScriptId = await this.addPreloadScript(`(${functionDeclaration})();`, sandbox);
+ // Upon attaching to a new target, run preload scripts on each execution
+ // context before `Runtime.runIfWaitingForDebugger`.
+ //
+ // Otherwise a browsing context might be created without the evaluation of
+ // preload scripts.
+ await Promise.all(this.#browsingContextStorage
+ .getAllContexts()
+ .filter((context) => context.cdpTarget === this)
+ .map((context) => context
+ .getOrCreateSandbox(sandbox)
+ .then((realm) => this.cdpClient.sendCommand('Runtime.evaluate', {
+ expression: `(${functionDeclaration})();`,
+ contextId: realm.executionContextId,
+ }))
+ .catch((error) => {
+ this.#logger?.(log_js_1$3.LogType.cdp, 'Could not evaluate preload script', error);
+ })));
+ this.#preloadScriptStorage.appendCdpPreloadScript(script, {
+ target: this,
+ preloadScriptId: cdpPreloadScriptId,
+ });
+ }
+ }
+ /**
+ * Issues `Page.addScriptToEvaluateOnNewDocument` CDP command with the given
+ * script source in evaluated form and world name / sandbox.
+ *
+ * @return The CDP preload script ID.
+ */
+ async addPreloadScript(scriptSource, sandbox) {
+ const result = await this.cdpClient.sendCommand('Page.addScriptToEvaluateOnNewDocument', {
+ source: scriptSource,
+ worldName: sandbox,
+ });
+ return result.identifier;
+ }
+ /**
+ * Issues `Page.removeScriptToEvaluateOnNewDocument` CDP command with the
+ * given CDP preload script ID.
+ */
+ async removePreloadScript(cdpPreloadScriptId) {
+ await this.cdpClient.sendCommand('Page.removeScriptToEvaluateOnNewDocument', {
+ identifier: cdpPreloadScriptId,
+ });
+ }
+}
+cdpTarget.CdpTarget = CdpTarget;
+
+Object.defineProperty(browsingContextProcessor, "__esModule", { value: true });
+browsingContextProcessor.BrowsingContextProcessor = void 0;
+const protocol_js_1$5 = protocol;
+const log_js_1$2 = log;
+const InputStateManager_js_1 = InputStateManager$1;
+const ActionDispatcher_js_1 = ActionDispatcher$1;
+const PreloadScriptStorage_js_1 = PreloadScriptStorage$1;
+const browsingContextImpl_js_1 = browsingContextImpl;
+const cdpTarget_js_1 = cdpTarget;
+class BrowsingContextProcessor {
+ #browsingContextStorage;
+ #cdpConnection;
+ #eventManager;
+ #logger;
+ #realmStorage;
+ #selfTargetId;
+ #preloadScriptStorage;
+ #inputStateManager = new InputStateManager_js_1.InputStateManager();
+ constructor(realmStorage, cdpConnection, selfTargetId, eventManager, browsingContextStorage, logger) {
+ this.#browsingContextStorage = browsingContextStorage;
+ this.#cdpConnection = cdpConnection;
+ this.#eventManager = eventManager;
+ this.#logger = logger;
+ this.#realmStorage = realmStorage;
+ this.#selfTargetId = selfTargetId;
+ this.#preloadScriptStorage = new PreloadScriptStorage_js_1.PreloadScriptStorage();
+ this.#setEventListeners(this.#cdpConnection.browserClient());
+ }
+ /**
+ * This method is called for each CDP session, since this class is responsible
+ * for creating and destroying all targets and browsing contexts.
+ */
+ #setEventListeners(cdpClient) {
+ cdpClient.on('Target.attachedToTarget', (params) => {
+ this.#handleAttachedToTargetEvent(params, cdpClient);
+ });
+ cdpClient.on('Target.detachedFromTarget', (params) => {
+ this.#handleDetachedFromTargetEvent(params);
+ });
+ cdpClient.on('Page.frameAttached', (params) => {
+ this.#handleFrameAttachedEvent(params);
+ });
+ cdpClient.on('Page.frameDetached', (params) => {
+ this.#handleFrameDetachedEvent(params);
+ });
+ }
+ #handleFrameAttachedEvent(params) {
+ const parentBrowsingContext = this.#browsingContextStorage.findContext(params.parentFrameId);
+ if (parentBrowsingContext !== undefined) {
+ browsingContextImpl_js_1.BrowsingContextImpl.create(parentBrowsingContext.cdpTarget, this.#realmStorage, params.frameId, params.parentFrameId, this.#eventManager, this.#browsingContextStorage, this.#logger);
+ }
+ }
+ #handleFrameDetachedEvent(params) {
+ // In case of OOPiF no need in deleting BrowsingContext.
+ if (params.reason === 'swap') {
+ return;
+ }
+ this.#browsingContextStorage.findContext(params.frameId)?.delete();
+ }
+ #handleAttachedToTargetEvent(params, parentSessionCdpClient) {
+ const { sessionId, targetInfo } = params;
+ const targetCdpClient = this.#cdpConnection.getCdpClient(sessionId);
+ if (!this.#isValidTarget(targetInfo)) {
+ // DevTools or some other not supported by BiDi target. Just release
+ // debugger and ignore them.
+ targetCdpClient
+ .sendCommand('Runtime.runIfWaitingForDebugger')
+ .then(() => parentSessionCdpClient.sendCommand('Target.detachFromTarget', params))
+ .catch((error) => this.#logger?.(log_js_1$2.LogType.system, error));
+ return;
+ }
+ this.#logger?.(log_js_1$2.LogType.browsingContexts, 'AttachedToTarget event received:', JSON.stringify(params, null, 2));
+ this.#setEventListeners(targetCdpClient);
+ const maybeContext = this.#browsingContextStorage.findContext(targetInfo.targetId);
+ const cdpTarget = cdpTarget_js_1.CdpTarget.create(targetInfo.targetId, maybeContext?.parentId ?? null, targetCdpClient, sessionId, this.#realmStorage, this.#eventManager, this.#preloadScriptStorage, this.#browsingContextStorage, this.#logger);
+ if (maybeContext) {
+ // OOPiF.
+ maybeContext.updateCdpTarget(cdpTarget);
+ }
+ else {
+ // New context.
+ browsingContextImpl_js_1.BrowsingContextImpl.create(cdpTarget, this.#realmStorage, targetInfo.targetId, null, this.#eventManager, this.#browsingContextStorage, this.#logger);
+ }
+ }
+ #handleDetachedFromTargetEvent(params) {
+ // XXX: params.targetId is deprecated. Update this class to track using
+ // params.sessionId instead.
+ // https://github.com/GoogleChromeLabs/chromium-bidi/issues/60
+ const contextId = params.targetId;
+ this.#browsingContextStorage.findContext(contextId)?.delete();
+ this.#preloadScriptStorage.removeCdpPreloadScripts({ targetId: contextId });
+ }
+ async #getRealm(target) {
+ if ('realm' in target) {
+ return this.#realmStorage.getRealm({
+ realmId: target.realm,
+ });
+ }
+ const context = this.#browsingContextStorage.getContext(target.context);
+ return context.getOrCreateSandbox(target.sandbox);
+ }
+ process_browsingContext_getTree(params) {
+ const resultContexts = params.root === undefined
+ ? this.#browsingContextStorage.getTopLevelContexts()
+ : [this.#browsingContextStorage.getContext(params.root)];
+ return {
+ result: {
+ contexts: resultContexts.map((c) => c.serializeToBidiValue(params.maxDepth ?? Number.MAX_VALUE)),
+ },
+ };
+ }
+ async process_browsingContext_create(params) {
+ const browserCdpClient = this.#cdpConnection.browserClient();
+ let referenceContext;
+ if (params.referenceContext !== undefined) {
+ referenceContext = this.#browsingContextStorage.getContext(params.referenceContext);
+ if (!referenceContext.isTopLevelContext()) {
+ throw new protocol_js_1$5.Message.InvalidArgumentException(`referenceContext should be a top-level context`);
+ }
+ }
+ let result;
+ switch (params.type) {
+ case 'tab':
+ result = await browserCdpClient.sendCommand('Target.createTarget', {
+ url: 'about:blank',
+ newWindow: false,
+ });
+ break;
+ case 'window':
+ result = await browserCdpClient.sendCommand('Target.createTarget', {
+ url: 'about:blank',
+ newWindow: true,
+ });
+ break;
+ }
+ // Wait for the new tab to be loaded to avoid race conditions in the
+ // `browsingContext` events, when the `browsingContext.domContentLoaded` and
+ // `browsingContext.load` events from the initial `about:blank` navigation
+ // are emitted after the next navigation is started.
+ // Details: https://github.com/web-platform-tests/wpt/issues/35846
+ const contextId = result.targetId;
+ const context = this.#browsingContextStorage.getContext(contextId);
+ await context.awaitLoaded();
+ return {
+ result: {
+ context: context.id,
+ },
+ };
+ }
+ process_browsingContext_navigate(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ return context.navigate(params.url, params.wait ?? 'none');
+ }
+ process_browsingContext_reload(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ return context.reload(params.ignoreCache ?? false, params.wait ?? 'none');
+ }
+ async process_browsingContext_captureScreenshot(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ return context.captureScreenshot();
+ }
+ async process_browsingContext_print(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ return context.print(params);
+ }
+ async process_script_addPreloadScript(params) {
+ if (params.arguments !== undefined && params.arguments.length > 0) {
+ // TODO: Handle arguments.
+ throw new Error('add preload script arguments are not supported');
+ }
+ const cdpTargets = new Set(
+ // TODO: The unique target can be in a non-top-level browsing context.
+ // We need all the targets.
+ // To get them, we can walk through all the contexts and collect their targets into the set.
+ params.context === undefined || params.context === null
+ ? this.#browsingContextStorage
+ .getTopLevelContexts()
+ .map((context) => context.cdpTarget)
+ : [this.#browsingContextStorage.getContext(params.context).cdpTarget]);
+ const cdpPreloadScripts = [];
+ for (const cdpTarget of cdpTargets) {
+ const cdpPreloadScriptId = await cdpTarget.addPreloadScript(
+ // The spec provides a function, and CDP expects an evaluation.
+ `(${params.functionDeclaration})();`, params.sandbox);
+ cdpPreloadScripts.push({
+ target: cdpTarget,
+ preloadScriptId: cdpPreloadScriptId,
+ });
+ }
+ const preloadScript = this.#preloadScriptStorage.addPreloadScripts(params.context ?? null, cdpPreloadScripts, params.functionDeclaration, params.sandbox);
+ return {
+ result: {
+ script: preloadScript.id,
+ },
+ };
+ }
+ async process_script_removePreloadScript(params) {
+ const bidiId = params.script;
+ const scripts = this.#preloadScriptStorage.findPreloadScripts({
+ id: bidiId,
+ });
+ if (scripts.length === 0) {
+ throw new protocol_js_1$5.Message.NoSuchScriptException(`No preload script with BiDi ID '${bidiId}'`);
+ }
+ for (const script of scripts) {
+ for (const cdpPreloadScript of script.cdpPreloadScripts) {
+ const cdpTarget = cdpPreloadScript.target;
+ const cdpPreloadScriptId = cdpPreloadScript.preloadScriptId;
+ await cdpTarget.removePreloadScript(cdpPreloadScriptId);
+ }
+ }
+ this.#preloadScriptStorage.removeBiDiPreloadScripts({
+ id: bidiId,
+ });
+ return { result: {} };
+ }
+ async process_script_evaluate(params) {
+ const realm = await this.#getRealm(params.target);
+ return realm.scriptEvaluate(params.expression, params.awaitPromise, params.resultOwnership ?? 'none', params.serializationOptions ?? {});
+ }
+ process_script_getRealms(params) {
+ if (params.context !== undefined) {
+ // Make sure the context is known.
+ this.#browsingContextStorage.getContext(params.context);
+ }
+ const realms = this.#realmStorage
+ .findRealms({
+ browsingContextId: params.context,
+ type: params.type,
+ })
+ .map((realm) => realm.toBiDi());
+ return { result: { realms } };
+ }
+ async process_script_callFunction(params) {
+ const realm = await this.#getRealm(params.target);
+ return realm.callFunction(params.functionDeclaration, params.this || {
+ type: 'undefined',
+ }, // `this` is `undefined` by default.
+ params.arguments || [], // `arguments` is `[]` by default.
+ params.awaitPromise, params.resultOwnership ?? 'none', params.serializationOptions ?? {});
+ }
+ async process_script_disown(params) {
+ const realm = await this.#getRealm(params.target);
+ await Promise.all(params.handles.map(async (h) => realm.disown(h)));
+ return { result: {} };
+ }
+ async process_input_performActions(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ const inputState = this.#inputStateManager.get(context.top);
+ const actionsByTick = this.#getActionsByTick(params, inputState);
+ const dispatcher = new ActionDispatcher_js_1.ActionDispatcher(inputState, context);
+ await dispatcher.dispatchActions(actionsByTick);
+ return { result: {} };
+ }
+ #getActionsByTick(params, inputState) {
+ const actionsByTick = [];
+ for (const action of params.actions) {
+ switch (action.type) {
+ case protocol_js_1$5.Input.SourceActionsType.Pointer: {
+ action.parameters ??= { pointerType: protocol_js_1$5.Input.PointerType.Mouse };
+ action.parameters.pointerType ??= protocol_js_1$5.Input.PointerType.Mouse;
+ const source = inputState.getOrCreate(action.id, protocol_js_1$5.Input.SourceActionsType.Pointer, action.parameters.pointerType);
+ if (source.subtype !== action.parameters.pointerType) {
+ throw new protocol_js_1$5.Message.InvalidArgumentException(`Expected input source ${action.id} to be ${source.subtype}; got ${action.parameters.pointerType}.`);
+ }
+ break;
+ }
+ default:
+ inputState.getOrCreate(action.id, action.type);
+ }
+ const actions = action.actions.map((item) => ({
+ id: action.id,
+ action: item,
+ }));
+ for (let i = 0; i < actions.length; i++) {
+ if (actionsByTick.length === i) {
+ actionsByTick.push([]);
+ }
+ actionsByTick[i].push(actions[i]);
+ }
+ }
+ return actionsByTick;
+ }
+ async process_input_releaseActions(params) {
+ const context = this.#browsingContextStorage.getContext(params.context);
+ const topContext = context.top;
+ const inputState = this.#inputStateManager.get(topContext);
+ const dispatcher = new ActionDispatcher_js_1.ActionDispatcher(inputState, context);
+ await dispatcher.dispatchTickActions(inputState.cancelList.reverse());
+ this.#inputStateManager.delete(topContext);
+ return { result: {} };
+ }
+ async process_browsingContext_close(commandParams) {
+ const browserCdpClient = this.#cdpConnection.browserClient();
+ const context = this.#browsingContextStorage.getContext(commandParams.context);
+ if (!context.isTopLevelContext()) {
+ throw new protocol_js_1$5.Message.InvalidArgumentException('A top-level browsing context cannot be closed.');
+ }
+ const detachedFromTargetPromise = new Promise((resolve) => {
+ const onContextDestroyed = (eventParams) => {
+ if (eventParams.targetId === commandParams.context) {
+ browserCdpClient.off('Target.detachedFromTarget', onContextDestroyed);
+ resolve();
+ }
+ };
+ browserCdpClient.on('Target.detachedFromTarget', onContextDestroyed);
+ });
+ await browserCdpClient.sendCommand('Target.closeTarget', {
+ targetId: commandParams.context,
+ });
+ // Sometimes CDP command finishes before `detachedFromTarget` event,
+ // sometimes after. Wait for the CDP command to be finished, and then wait
+ // for `detachedFromTarget` if it hasn't emitted.
+ await detachedFromTargetPromise;
+ return { result: {} };
+ }
+ #isValidTarget(target) {
+ if (target.targetId === this.#selfTargetId) {
+ return false;
+ }
+ return ['page', 'iframe'].includes(target.type);
+ }
+ async process_cdp_sendCommand(params) {
+ const client = params.cdpSession
+ ? this.#cdpConnection.getCdpClient(params.cdpSession)
+ : this.#cdpConnection.browserClient();
+ const sendCdpCommandResult = await client.sendCommand(params.cdpMethod, params.cdpParams);
+ return {
+ result: sendCdpCommandResult,
+ cdpSession: params.cdpSession,
+ };
+ }
+ process_cdp_getSession(params) {
+ const context = params.context;
+ const sessionId = this.#browsingContextStorage.getContext(context).cdpTarget.cdpSessionId;
+ if (sessionId === undefined) {
+ return { result: { cdpSession: null } };
+ }
+ return { result: { cdpSession: sessionId } };
+ }
+}
+browsingContextProcessor.BrowsingContextProcessor = BrowsingContextProcessor;
+
+var OutgoingBidiMessage$1 = {};
+
+/**
+ * Copyright 2021 Google LLC.
+ * 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.
+ */
+Object.defineProperty(OutgoingBidiMessage$1, "__esModule", { value: true });
+OutgoingBidiMessage$1.OutgoingBidiMessage = void 0;
+class OutgoingBidiMessage {
+ #message;
+ #channel;
+ constructor(message, channel) {
+ this.#message = message;
+ this.#channel = channel;
+ }
+ static async createFromPromise(messagePromise, channel) {
+ return messagePromise.then((message) => new OutgoingBidiMessage(message, channel));
+ }
+ static createResolved(message, channel) {
+ return Promise.resolve(new OutgoingBidiMessage(message, channel));
+ }
+ get message() {
+ return this.#message;
+ }
+ get channel() {
+ return this.#channel;
+ }
+}
+OutgoingBidiMessage$1.OutgoingBidiMessage = OutgoingBidiMessage;
+
+/**
+ * Copyright 2021 Google LLC.
+ * 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.
+ */
+Object.defineProperty(CommandProcessor$1, "__esModule", { value: true });
+CommandProcessor$1.CommandProcessor = void 0;
+const protocol_js_1$4 = protocol;
+const log_js_1$1 = log;
+const EventEmitter_js_1$1 = EventEmitter$1;
+const browsingContextProcessor_js_1 = browsingContextProcessor;
+const OutgoingBidiMessage_js_1$1 = OutgoingBidiMessage$1;
+class BidiNoOpParser {
+ parseAddPreloadScriptParams(params) {
+ return params;
+ }
+ parseRemovePreloadScriptParams(params) {
+ return params;
+ }
+ parseGetRealmsParams(params) {
+ return params;
+ }
+ parseCallFunctionParams(params) {
+ return params;
+ }
+ parseEvaluateParams(params) {
+ return params;
+ }
+ parseDisownParams(params) {
+ return params;
+ }
+ parseSendCommandParams(params) {
+ return params;
+ }
+ parseGetSessionParams(params) {
+ return params;
+ }
+ parseSubscribeParams(params) {
+ return params;
+ }
+ parseNavigateParams(params) {
+ return params;
+ }
+ parseReloadParams(params) {
+ return params;
+ }
+ parseGetTreeParams(params) {
+ return params;
+ }
+ parseCreateParams(params) {
+ return params;
+ }
+ parseCloseParams(params) {
+ return params;
+ }
+ parseCaptureScreenshotParams(params) {
+ return params;
+ }
+ parsePrintParams(params) {
+ return params;
+ }
+ parsePerformActionsParams(params) {
+ return params;
+ }
+ parseReleaseActionsParams(params) {
+ return params;
+ }
+}
+class CommandProcessor extends EventEmitter_js_1$1.EventEmitter {
+ #contextProcessor;
+ #eventManager;
+ #parser;
+ #logger;
+ constructor(realmStorage, cdpConnection, eventManager, selfTargetId, parser = new BidiNoOpParser(), browsingContextStorage, logger) {
+ super();
+ this.#eventManager = eventManager;
+ this.#logger = logger;
+ this.#contextProcessor = new browsingContextProcessor_js_1.BrowsingContextProcessor(realmStorage, cdpConnection, selfTargetId, eventManager, browsingContextStorage, logger);
+ this.#parser = parser;
+ }
+ static #process_session_status() {
+ return { result: { ready: false, message: 'already connected' } };
+ }
+ async #process_session_subscribe(params, channel) {
+ await this.#eventManager.subscribe(params.events, params.contexts ?? [null], channel);
+ return { result: {} };
+ }
+ async #process_session_unsubscribe(params, channel) {
+ await this.#eventManager.unsubscribe(params.events, params.contexts ?? [null], channel);
+ return { result: {} };
+ }
+ async #processCommand(commandData) {
+ switch (commandData.method) {
+ case 'session.status':
+ return CommandProcessor.#process_session_status();
+ case 'session.subscribe':
+ return this.#process_session_subscribe(this.#parser.parseSubscribeParams(commandData.params), commandData.channel ?? null);
+ case 'session.unsubscribe':
+ return this.#process_session_unsubscribe(this.#parser.parseSubscribeParams(commandData.params), commandData.channel ?? null);
+ case 'browsingContext.create':
+ return this.#contextProcessor.process_browsingContext_create(this.#parser.parseCreateParams(commandData.params));
+ case 'browsingContext.close':
+ return this.#contextProcessor.process_browsingContext_close(this.#parser.parseCloseParams(commandData.params));
+ case 'browsingContext.getTree':
+ return this.#contextProcessor.process_browsingContext_getTree(this.#parser.parseGetTreeParams(commandData.params));
+ case 'browsingContext.navigate':
+ return this.#contextProcessor.process_browsingContext_navigate(this.#parser.parseNavigateParams(commandData.params));
+ case 'browsingContext.captureScreenshot':
+ return this.#contextProcessor.process_browsingContext_captureScreenshot(this.#parser.parseCaptureScreenshotParams(commandData.params));
+ case 'browsingContext.print':
+ return this.#contextProcessor.process_browsingContext_print(this.#parser.parsePrintParams(commandData.params));
+ case 'browsingContext.reload':
+ return this.#contextProcessor.process_browsingContext_reload(this.#parser.parseReloadParams(commandData.params));
+ case 'script.addPreloadScript':
+ return this.#contextProcessor.process_script_addPreloadScript(this.#parser.parseAddPreloadScriptParams(commandData.params));
+ case 'script.removePreloadScript':
+ return this.#contextProcessor.process_script_removePreloadScript(this.#parser.parseRemovePreloadScriptParams(commandData.params));
+ case 'script.getRealms':
+ return this.#contextProcessor.process_script_getRealms(this.#parser.parseGetRealmsParams(commandData.params));
+ case 'script.callFunction':
+ return this.#contextProcessor.process_script_callFunction(this.#parser.parseCallFunctionParams(commandData.params));
+ case 'script.evaluate':
+ return this.#contextProcessor.process_script_evaluate(this.#parser.parseEvaluateParams(commandData.params));
+ case 'script.disown':
+ return this.#contextProcessor.process_script_disown(this.#parser.parseDisownParams(commandData.params));
+ case 'input.performActions':
+ return this.#contextProcessor.process_input_performActions(this.#parser.parsePerformActionsParams(commandData.params));
+ case 'input.releaseActions':
+ return this.#contextProcessor.process_input_releaseActions(this.#parser.parseReleaseActionsParams(commandData.params));
+ case 'cdp.sendCommand':
+ return this.#contextProcessor.process_cdp_sendCommand(this.#parser.parseSendCommandParams(commandData.params));
+ case 'cdp.getSession':
+ return this.#contextProcessor.process_cdp_getSession(this.#parser.parseGetSessionParams(commandData.params));
+ }
+ // Intentionally kept outside of the switch statement to ensure that
+ // ESLint @typescript-eslint/switch-exhaustiveness-check triggers if a new
+ // command is added.
+ throw new protocol_js_1$4.Message.UnknownCommandException(`Unknown command '${commandData.method}'.`);
+ }
+ async processCommand(command) {
+ try {
+ const result = await this.#processCommand(command);
+ const response = {
+ id: command.id,
+ ...result,
+ };
+ this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(response, command.channel ?? null));
+ }
+ catch (e) {
+ if (e instanceof protocol_js_1$4.Message.ErrorResponse) {
+ const errorResponse = e;
+ this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(errorResponse.toErrorResponse(command.id), command.channel ?? null));
+ }
+ else {
+ const error = e;
+ this.#logger?.(log_js_1$1.LogType.bidi, error);
+ this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(new protocol_js_1$4.Message.UnknownErrorException(error.message).toErrorResponse(command.id), command.channel ?? null));
+ }
+ }
+ }
+}
+CommandProcessor$1.CommandProcessor = CommandProcessor;
+
+var browsingContextStorage = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(browsingContextStorage, "__esModule", { value: true });
+browsingContextStorage.BrowsingContextStorage = void 0;
+const protocol_js_1$3 = protocol;
+/** Container class for browsing contexts. */
+class BrowsingContextStorage {
+ /** Map from context ID to context implementation. */
+ #contexts = new Map();
+ /** Gets all top-level contexts, i.e. those with no parent. */
+ getTopLevelContexts() {
+ return this.getAllContexts().filter((context) => context.isTopLevelContext());
+ }
+ /** Gets all contexts. */
+ getAllContexts() {
+ return Array.from(this.#contexts.values());
+ }
+ /** Deletes the context with the given ID. */
+ deleteContextById(id) {
+ this.#contexts.delete(id);
+ }
+ /** Deletes the given context. */
+ deleteContext(context) {
+ this.#contexts.delete(context.id);
+ }
+ /** Tracks the given context. */
+ addContext(context) {
+ this.#contexts.set(context.id, context);
+ }
+ /** Returns true whether there is an existing context with the given ID. */
+ hasContext(id) {
+ return this.#contexts.has(id);
+ }
+ /** Gets the context with the given ID, if any. */
+ findContext(id) {
+ return this.#contexts.get(id);
+ }
+ /** Returns the top-level context ID of the given context, if any. */
+ findTopLevelContextId(id) {
+ if (id === null) {
+ return null;
+ }
+ const maybeContext = this.findContext(id);
+ const parentId = maybeContext?.parentId ?? null;
+ if (parentId === null) {
+ return id;
+ }
+ return this.findTopLevelContextId(parentId);
+ }
+ /** Gets the context with the given ID, if any, otherwise throws. */
+ getContext(id) {
+ const result = this.findContext(id);
+ if (result === undefined) {
+ throw new protocol_js_1$3.Message.NoSuchFrameException(`Context ${id} not found`);
+ }
+ return result;
+ }
+}
+browsingContextStorage.BrowsingContextStorage = BrowsingContextStorage;
+
+var EventManager$1 = {};
+
+var buffer = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(buffer, "__esModule", { value: true });
+buffer.Buffer = void 0;
+/**
+ * Implements a FIFO buffer with a fixed size.
+ */
+let Buffer$1 = class Buffer {
+ #capacity;
+ #entries = [];
+ #onItemRemoved;
+ /**
+ * @param capacity
+ * @param onItemRemoved optional delegate called for each removed element.
+ */
+ constructor(capacity, onItemRemoved) {
+ this.#capacity = capacity;
+ this.#onItemRemoved = onItemRemoved;
+ }
+ get() {
+ return this.#entries;
+ }
+ add(value) {
+ this.#entries.push(value);
+ while (this.#entries.length > this.#capacity) {
+ const item = this.#entries.shift();
+ if (item !== undefined) {
+ this.#onItemRemoved?.(item);
+ }
+ }
+ }
+};
+buffer.Buffer = Buffer$1;
+
+var idWrapper = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(idWrapper, "__esModule", { value: true });
+idWrapper.IdWrapper = void 0;
+/**
+ * Creates an object with a positive unique incrementing id.
+ */
+class IdWrapper {
+ static #counter = 0;
+ #id;
+ constructor() {
+ this.#id = ++IdWrapper.#counter;
+ }
+ get id() {
+ return this.#id;
+ }
+}
+idWrapper.IdWrapper = IdWrapper;
+
+var SubscriptionManager$1 = {};
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(SubscriptionManager$1, "__esModule", { value: true });
+SubscriptionManager$1.SubscriptionManager = SubscriptionManager$1.unrollEvents = SubscriptionManager$1.cartesianProduct = void 0;
+const protocol_js_1$2 = protocol;
+/**
+ * Returns the cartesian product of the given arrays.
+ *
+ * Example:
+ * cartesian([1, 2], ['a', 'b']); => [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
+ */
+function cartesianProduct(...a) {
+ return a.reduce((a, b) => a.flatMap((d) => b.map((e) => [d, e].flat())));
+}
+SubscriptionManager$1.cartesianProduct = cartesianProduct;
+/** Expands "AllEvents" events into atomic events. */
+function unrollEvents(events) {
+ const allEvents = [];
+ for (const event of events) {
+ switch (event) {
+ case protocol_js_1$2.BrowsingContext.AllEvents:
+ allEvents.push(...Object.values(protocol_js_1$2.BrowsingContext.EventNames));
+ break;
+ case protocol_js_1$2.CDP.AllEvents:
+ allEvents.push(...Object.values(protocol_js_1$2.CDP.EventNames));
+ break;
+ case protocol_js_1$2.Log.AllEvents:
+ allEvents.push(...Object.values(protocol_js_1$2.Log.EventNames));
+ break;
+ case protocol_js_1$2.Network.AllEvents:
+ allEvents.push(...Object.values(protocol_js_1$2.Network.EventNames));
+ break;
+ case protocol_js_1$2.Script.AllEvents:
+ allEvents.push(...Object.values(protocol_js_1$2.Script.EventNames));
+ break;
+ default:
+ allEvents.push(event);
+ }
+ }
+ return allEvents;
+}
+SubscriptionManager$1.unrollEvents = unrollEvents;
+class SubscriptionManager {
+ #subscriptionPriority = 0;
+ // BrowsingContext `null` means the event has subscription across all the
+ // browsing contexts.
+ // Channel `null` means no `channel` should be added.
+ #channelToContextToEventMap = new Map();
+ #browsingContextStorage;
+ constructor(browsingContextStorage) {
+ this.#browsingContextStorage = browsingContextStorage;
+ }
+ getChannelsSubscribedToEvent(eventMethod, contextId) {
+ const prioritiesAndChannels = Array.from(this.#channelToContextToEventMap.keys())
+ .map((channel) => ({
+ priority: this.#getEventSubscriptionPriorityForChannel(eventMethod, contextId, channel),
+ channel,
+ }))
+ .filter(({ priority }) => priority !== null);
+ // Sort channels by priority.
+ return prioritiesAndChannels
+ .sort((a, b) => a.priority - b.priority)
+ .map(({ channel }) => channel);
+ }
+ #getEventSubscriptionPriorityForChannel(eventMethod, contextId, channel) {
+ const contextToEventMap = this.#channelToContextToEventMap.get(channel);
+ if (contextToEventMap === undefined) {
+ return null;
+ }
+ const maybeTopLevelContextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
+ // `null` covers global subscription.
+ const relevantContexts = [...new Set([null, maybeTopLevelContextId])];
+ // Get all the subscription priorities.
+ const priorities = relevantContexts
+ .map((c) => contextToEventMap.get(c)?.get(eventMethod))
+ .filter((p) => p !== undefined);
+ if (priorities.length === 0) {
+ // Not subscribed, return null.
+ return null;
+ }
+ // Return minimal priority.
+ return Math.min(...priorities);
+ }
+ subscribe(event, contextId, channel) {
+ // All the subscriptions are handled on the top-level contexts.
+ contextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
+ if (event === protocol_js_1$2.BrowsingContext.AllEvents) {
+ Object.values(protocol_js_1$2.BrowsingContext.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
+ return;
+ }
+ if (event === protocol_js_1$2.CDP.AllEvents) {
+ Object.values(protocol_js_1$2.CDP.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
+ return;
+ }
+ if (event === protocol_js_1$2.Log.AllEvents) {
+ Object.values(protocol_js_1$2.Log.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
+ return;
+ }
+ if (event === protocol_js_1$2.Network.AllEvents) {
+ Object.values(protocol_js_1$2.Network.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
+ return;
+ }
+ if (event === protocol_js_1$2.Script.AllEvents) {
+ Object.values(protocol_js_1$2.Script.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
+ return;
+ }
+ if (!this.#channelToContextToEventMap.has(channel)) {
+ this.#channelToContextToEventMap.set(channel, new Map());
+ }
+ const contextToEventMap = this.#channelToContextToEventMap.get(channel);
+ if (!contextToEventMap.has(contextId)) {
+ contextToEventMap.set(contextId, new Map());
+ }
+ const eventMap = contextToEventMap.get(contextId);
+ // Do not re-subscribe to events to keep the priority.
+ if (eventMap.has(event)) {
+ return;
+ }
+ eventMap.set(event, this.#subscriptionPriority++);
+ }
+ /**
+ * Unsubscribes atomically from all events in the given contexts and channel.
+ */
+ unsubscribeAll(events, contextIds, channel) {
+ // Assert all contexts are known.
+ for (const contextId of contextIds) {
+ if (contextId !== null) {
+ this.#browsingContextStorage.getContext(contextId);
+ }
+ }
+ const eventContextPairs = cartesianProduct(unrollEvents(events), contextIds);
+ // Assert all unsubscriptions are valid.
+ // If any of the unsubscriptions are invalid, do not unsubscribe from anything.
+ eventContextPairs
+ .map(([event, contextId]) => this.#checkUnsubscribe(event, contextId, channel))
+ .forEach((unsubscribe) => unsubscribe());
+ }
+ /**
+ * Unsubscribes from the event in the given context and channel.
+ * Syntactic sugar for "unsubscribeAll".
+ */
+ unsubscribe(eventName, contextId, channel) {
+ this.unsubscribeAll([eventName], [contextId], channel);
+ }
+ #checkUnsubscribe(event, contextId, channel) {
+ // All the subscriptions are handled on the top-level contexts.
+ contextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
+ if (!this.#channelToContextToEventMap.has(channel)) {
+ throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
+ }
+ const contextToEventMap = this.#channelToContextToEventMap.get(channel);
+ if (!contextToEventMap.has(contextId)) {
+ throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
+ }
+ const eventMap = contextToEventMap.get(contextId);
+ if (!eventMap.has(event)) {
+ throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
+ }
+ return () => {
+ eventMap.delete(event);
+ // Clean up maps if empty.
+ if (eventMap.size === 0) {
+ contextToEventMap.delete(event);
+ }
+ if (contextToEventMap.size === 0) {
+ this.#channelToContextToEventMap.delete(channel);
+ }
+ };
+ }
+}
+SubscriptionManager$1.SubscriptionManager = SubscriptionManager;
+
+/**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+Object.defineProperty(EventManager$1, "__esModule", { value: true });
+EventManager$1.EventManager = void 0;
+const protocol_js_1$1 = protocol;
+const buffer_js_1 = buffer;
+const idWrapper_js_1 = idWrapper;
+const OutgoingBidiMessage_js_1 = OutgoingBidiMessage$1;
+const DefaultMap_js_1 = DefaultMap$1;
+const SubscriptionManager_js_1 = SubscriptionManager$1;
+class EventWrapper {
+ #idWrapper;
+ #contextId;
+ #event;
+ constructor(event, contextId) {
+ this.#idWrapper = new idWrapper_js_1.IdWrapper();
+ this.#contextId = contextId;
+ this.#event = event;
+ }
+ get id() {
+ return this.#idWrapper.id;
+ }
+ get contextId() {
+ return this.#contextId;
+ }
+ get event() {
+ return this.#event;
+ }
+}
+/**
+ * Maps event name to a desired buffer length.
+ */
+const eventBufferLength = new Map([
+ [protocol_js_1$1.Log.EventNames.LogEntryAddedEvent, 100],
+]);
+class EventManager {
+ static #NETWORK_DOMAIN_PREFIX = 'network';
+ /**
+ * Maps event name to a set of contexts where this event already happened.
+ * Needed for getting buffered events from all the contexts in case of
+ * subscripting to all contexts.
+ */
+ #eventToContextsMap = new DefaultMap_js_1.DefaultMap(() => new Set());
+ /**
+ * Maps `eventName` + `browsingContext` to buffer. Used to get buffered events
+ * during subscription. Channel-agnostic.
+ */
+ #eventBuffers = new Map();
+ /**
+ * Maps `eventName` + `browsingContext` + `channel` to last sent event id.
+ * Used to avoid sending duplicated events when user
+ * subscribes -> unsubscribes -> subscribes.
+ */
+ #lastMessageSent = new Map();
+ #subscriptionManager;
+ #bidiServer;
+ #isNetworkDomainEnabled;
+ constructor(bidiServer) {
+ this.#bidiServer = bidiServer;
+ this.#subscriptionManager = new SubscriptionManager_js_1.SubscriptionManager(bidiServer.getBrowsingContextStorage());
+ this.#isNetworkDomainEnabled = false;
+ }
+ get isNetworkDomainEnabled() {
+ return this.#isNetworkDomainEnabled;
+ }
+ /**
+ * Returns consistent key to be used to access value maps.
+ */
+ static #getMapKey(eventName, browsingContext, channel) {
+ return JSON.stringify({ eventName, browsingContext, channel });
+ }
+ registerEvent(event, contextId) {
+ this.registerPromiseEvent(Promise.resolve(event), contextId, event.method);
+ }
+ registerPromiseEvent(event, contextId, eventName) {
+ const eventWrapper = new EventWrapper(event, contextId);
+ const sortedChannels = this.#subscriptionManager.getChannelsSubscribedToEvent(eventName, contextId);
+ this.#bufferEvent(eventWrapper, eventName);
+ // Send events to channels in the subscription priority.
+ for (const channel of sortedChannels) {
+ this.#bidiServer.emitOutgoingMessage(OutgoingBidiMessage_js_1.OutgoingBidiMessage.createFromPromise(event, channel));
+ this.#markEventSent(eventWrapper, channel, eventName);
+ }
+ }
+ async subscribe(eventNames, contextIds, channel) {
+ // First check if all the contexts are known.
+ for (const contextId of contextIds) {
+ if (contextId !== null) {
+ // Assert the context is known. Throw exception otherwise.
+ this.#bidiServer.getBrowsingContextStorage().getContext(contextId);
+ }
+ }
+ for (const eventName of eventNames) {
+ for (const contextId of contextIds) {
+ await this.#handleDomains(eventName, contextId);
+ this.#subscriptionManager.subscribe(eventName, contextId, channel);
+ for (const eventWrapper of this.#getBufferedEvents(eventName, contextId, channel)) {
+ // The order of the events is important.
+ this.#bidiServer.emitOutgoingMessage(OutgoingBidiMessage_js_1.OutgoingBidiMessage.createFromPromise(eventWrapper.event, channel));
+ this.#markEventSent(eventWrapper, channel, eventName);
+ }
+ }
+ }
+ }
+ /**
+ * Enables domains for the subscribed event in the required contexts or
+ * globally.
+ */
+ async #handleDomains(eventName, contextId) {
+ // Enable network domain if user subscribed to any of network events.
+ if (eventName.startsWith(EventManager.#NETWORK_DOMAIN_PREFIX)) {
+ // Enable for all the contexts.
+ if (contextId === null) {
+ this.#isNetworkDomainEnabled = true;
+ await Promise.all(this.#bidiServer
+ .getBrowsingContextStorage()
+ .getAllContexts()
+ .map((context) => context.cdpTarget.enableNetworkDomain()));
+ }
+ else {
+ await this.#bidiServer
+ .getBrowsingContextStorage()
+ .getContext(contextId)
+ .cdpTarget.enableNetworkDomain();
+ }
+ }
+ }
+ unsubscribe(eventNames, contextIds, channel) {
+ this.#subscriptionManager.unsubscribeAll(eventNames, contextIds, channel);
+ }
+ /**
+ * If the event is buffer-able, put it in the buffer.
+ */
+ #bufferEvent(eventWrapper, eventName) {
+ if (!eventBufferLength.has(eventName)) {
+ // Do nothing if the event is no buffer-able.
+ return;
+ }
+ const bufferMapKey = EventManager.#getMapKey(eventName, eventWrapper.contextId);
+ if (!this.#eventBuffers.has(bufferMapKey)) {
+ this.#eventBuffers.set(bufferMapKey, new buffer_js_1.Buffer(eventBufferLength.get(eventName)));
+ }
+ this.#eventBuffers.get(bufferMapKey).add(eventWrapper);
+ // Add the context to the list of contexts having `eventName` events.
+ this.#eventToContextsMap.get(eventName).add(eventWrapper.contextId);
+ }
+ /**
+ * If the event is buffer-able, mark it as sent to the given contextId and channel.
+ */
+ #markEventSent(eventWrapper, channel, eventName) {
+ if (!eventBufferLength.has(eventName)) {
+ // Do nothing if the event is no buffer-able.
+ return;
+ }
+ const lastSentMapKey = EventManager.#getMapKey(eventName, eventWrapper.contextId, channel);
+ this.#lastMessageSent.set(lastSentMapKey, Math.max(this.#lastMessageSent.get(lastSentMapKey) ?? 0, eventWrapper.id));
+ }
+ /**
+ * Returns events which are buffered and not yet sent to the given channel events.
+ */
+ #getBufferedEvents(eventName, contextId, channel) {
+ const bufferMapKey = EventManager.#getMapKey(eventName, contextId);
+ const lastSentMapKey = EventManager.#getMapKey(eventName, contextId, channel);
+ const lastSentMessageId = this.#lastMessageSent.get(lastSentMapKey) ?? -Infinity;
+ const result = this.#eventBuffers
+ .get(bufferMapKey)
+ ?.get()
+ .filter((wrapper) => wrapper.id > lastSentMessageId) ?? [];
+ if (contextId === null) {
+ // For global subscriptions, events buffered in each context should be sent back.
+ Array.from(this.#eventToContextsMap.get(eventName).keys())
+ .filter((_contextId) =>
+ // Events without context are already in the result.
+ _contextId !== null &&
+ // Events from deleted contexts should not be sent.
+ this.#bidiServer.getBrowsingContextStorage().hasContext(_contextId))
+ .map((_contextId) => this.#getBufferedEvents(eventName, _contextId, channel))
+ .forEach((events) => result.push(...events));
+ }
+ return result.sort((e1, e2) => e1.id - e2.id);
+ }
+}
+EventManager$1.EventManager = EventManager;
+
+var realmStorage = {};
+
+Object.defineProperty(realmStorage, "__esModule", { value: true });
+realmStorage.RealmStorage = void 0;
+const protocol_js_1 = protocol;
+/** Container class for browsing realms. */
+class RealmStorage {
+ /** Tracks handles and their realms sent to the client. */
+ #knownHandlesToRealm = new Map();
+ /** Map from realm ID to Realm. */
+ #realmMap = new Map();
+ get knownHandlesToRealm() {
+ return this.#knownHandlesToRealm;
+ }
+ get realmMap() {
+ return this.#realmMap;
+ }
+ /** Finds all realms that match the given filter. */
+ findRealms(filter) {
+ return Array.from(this.#realmMap.values()).filter((realm) => {
+ if (filter.realmId !== undefined && filter.realmId !== realm.realmId) {
+ return false;
+ }
+ if (filter.browsingContextId !== undefined &&
+ filter.browsingContextId !== realm.browsingContextId) {
+ return false;
+ }
+ if (filter.navigableId !== undefined &&
+ filter.navigableId !== realm.navigableId) {
+ return false;
+ }
+ if (filter.executionContextId !== undefined &&
+ filter.executionContextId !== realm.executionContextId) {
+ return false;
+ }
+ if (filter.origin !== undefined && filter.origin !== realm.origin) {
+ return false;
+ }
+ if (filter.type !== undefined && filter.type !== realm.type) {
+ return false;
+ }
+ if (filter.sandbox !== undefined && filter.sandbox !== realm.sandbox) {
+ return false;
+ }
+ if (filter.cdpSessionId !== undefined &&
+ filter.cdpSessionId !== realm.cdpSessionId) {
+ return false;
+ }
+ return true;
+ });
+ }
+ findRealm(filter) {
+ const maybeRealms = this.findRealms(filter);
+ if (maybeRealms.length !== 1) {
+ return undefined;
+ }
+ return maybeRealms[0];
+ }
+ /** Gets the only realm that matches the given filter, if any, otherwise throws. */
+ getRealm(filter) {
+ const maybeRealm = this.findRealm(filter);
+ if (maybeRealm === undefined) {
+ throw new protocol_js_1.Message.NoSuchFrameException(`Realm ${JSON.stringify(filter)} not found`);
+ }
+ return maybeRealm;
+ }
+ /** Deletes all realms that match the given filter. */
+ deleteRealms(filter) {
+ this.findRealms(filter).map((realm) => {
+ this.#realmMap.delete(realm.realmId);
+ Array.from(this.#knownHandlesToRealm.entries())
+ .filter(([, r]) => r === realm.realmId)
+ .map(([handle]) => this.#knownHandlesToRealm.delete(handle));
+ });
+ }
+}
+realmStorage.RealmStorage = RealmStorage;
+
+/**
+ * Copyright 2021 Google LLC.
+ * 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.
+ */
+Object.defineProperty(BidiServer$1, "__esModule", { value: true });
+BidiServer$1.BidiServer = void 0;
+const EventEmitter_js_1 = EventEmitter$1;
+const log_js_1 = log;
+const processingQueue_js_1 = processingQueue;
+const CommandProcessor_js_1 = CommandProcessor$1;
+const browsingContextStorage_js_1 = browsingContextStorage;
+const EventManager_js_1 = EventManager$1;
+const realmStorage_js_1 = realmStorage;
+class BidiServer extends EventEmitter_js_1.EventEmitter {
+ #messageQueue;
+ #transport;
+ #commandProcessor;
+ #browsingContextStorage;
+ #realmStorage;
+ #logger;
+ #handleIncomingMessage = (message) => {
+ void this.#commandProcessor.processCommand(message).catch((error) => {
+ this.#logger?.(log_js_1.LogType.system, error);
+ });
+ };
+ #processOutgoingMessage = async (messageEntry) => {
+ const message = messageEntry.message;
+ if (messageEntry.channel !== null) {
+ message['channel'] = messageEntry.channel;
+ }
+ await this.#transport.sendMessage(message);
+ };
+ constructor(bidiTransport, cdpConnection, selfTargetId, parser, logger) {
+ super();
+ this.#logger = logger;
+ this.#browsingContextStorage = new browsingContextStorage_js_1.BrowsingContextStorage();
+ this.#realmStorage = new realmStorage_js_1.RealmStorage();
+ this.#messageQueue = new processingQueue_js_1.ProcessingQueue(this.#processOutgoingMessage, this.#logger);
+ this.#transport = bidiTransport;
+ this.#transport.setOnMessage(this.#handleIncomingMessage);
+ this.#commandProcessor = new CommandProcessor_js_1.CommandProcessor(this.#realmStorage, cdpConnection, new EventManager_js_1.EventManager(this), selfTargetId, parser, this.#browsingContextStorage, this.#logger);
+ this.#commandProcessor.on('response', (response) => {
+ this.emitOutgoingMessage(response);
+ });
+ }
+ static async createAndStart(bidiTransport, cdpConnection, selfTargetId, parser, logger) {
+ const server = new BidiServer(bidiTransport, cdpConnection, selfTargetId, parser, logger);
+ const cdpClient = cdpConnection.browserClient();
+ // Needed to get events about new targets.
+ await cdpClient.sendCommand('Target.setDiscoverTargets', { discover: true });
+ // Needed to automatically attach to new targets.
+ await cdpClient.sendCommand('Target.setAutoAttach', {
+ autoAttach: true,
+ waitForDebuggerOnStart: true,
+ flatten: true,
+ });
+ await server.topLevelContextsLoaded();
+ return server;
+ }
+ async topLevelContextsLoaded() {
+ await Promise.all(this.#browsingContextStorage
+ .getTopLevelContexts()
+ .map((c) => c.awaitLoaded()));
+ }
+ /**
+ * Sends BiDi message.
+ */
+ emitOutgoingMessage(messageEntry) {
+ this.#messageQueue.add(messageEntry);
+ }
+ close() {
+ this.#transport.close();
+ }
+ getBrowsingContextStorage() {
+ return this.#browsingContextStorage;
+ }
+}
+BidiServer$1.BidiServer = BidiServer;
+
+(function (exports) {
+ /**
+ * Copyright 2022 Google LLC.
+ * 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.
+ */
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.EventEmitter = exports.BidiServer = void 0;
+ var BidiServer_js_1 = BidiServer$1;
+ Object.defineProperty(exports, "BidiServer", { enumerable: true, get: function () { return BidiServer_js_1.BidiServer; } });
+ var EventEmitter_js_1 = EventEmitter$1;
+ Object.defineProperty(exports, "EventEmitter", { enumerable: true, get: function () { return EventEmitter_js_1.EventEmitter; } });
+
+} (bidiMapper));
+
/**
* Copyright 2023 Google Inc. All rights reserved.
*
@@ -1742,7 +7219,7 @@ async function connectBidiOverCDP(cdp) {
pptrTransport.onmessage(JSON.stringify(message));
});
const pptrBiDiConnection = new Connection(pptrTransport);
- const bidiServer = await index.bidiMapper.BidiServer.createAndStart(transportBiDi, cdpConnectionAdapter, '');
+ const bidiServer = await bidiMapper.BidiServer.createAndStart(transportBiDi, cdpConnectionAdapter, '');
return pptrBiDiConnection;
}
/**
@@ -1786,7 +7263,7 @@ _CDPConnectionAdapter_cdp = new WeakMap(), _CDPConnectionAdapter_adapters = new
*
* @internal
*/
-class CDPClientAdapter extends index.bidiMapper.EventEmitter {
+class CDPClientAdapter extends bidiMapper.EventEmitter {
constructor(client) {
super();
_CDPClientAdapter_closed.set(this, false);
@@ -1825,7 +7302,7 @@ _CDPClientAdapter_closed = new WeakMap(), _CDPClientAdapter_client = new WeakMap
* to send and receive commands to the BiDiServer.
* @internal
*/
-class NoOpTransport extends index.bidiMapper.EventEmitter {
+class NoOpTransport extends bidiMapper.EventEmitter {
constructor() {
super(...arguments);
_NoOpTransport_onMessage.set(this, async (_m) => {
diff --git a/dist/index.js b/dist/index.js
index 0cb9df9..231c57f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -41,6 +41,8 @@ var vm2_resolverCompat = require('./vm2/resolver-compat.js');
var require$$1$6 = require('module');
var require$$2$2 = require('http2');
var require$$2$3 = require('inspector');
+var require$$0$j = require('chromium-bidi/lib/cjs/bidiMapper/BidiMapper');
+var require$$1$7 = require('chromium-bidi/lib/cjs/cdp/CdpConnection');
require('./vm2/main.js');
require('./vm2/script.js');
require('vm');
@@ -340,7 +342,7 @@ function __importStar$b(mod) {
return result;
}
-function __importDefault$b(mod) {
+function __importDefault$a(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
@@ -384,7 +386,7 @@ var tslib_es6 = {
__asyncValues,
__makeTemplateObject,
__importStar: __importStar$b,
- __importDefault: __importDefault$b,
+ __importDefault: __importDefault$a,
__classPrivateFieldGet: __classPrivateFieldGet$M,
__classPrivateFieldSet: __classPrivateFieldSet$I,
__classPrivateFieldIn,
@@ -407,7 +409,7 @@ var tslib_es6$1 = /*#__PURE__*/Object.freeze({
__exportStar: __exportStar,
__extends: __extends,
__generator: __generator,
- __importDefault: __importDefault$b,
+ __importDefault: __importDefault$a,
__importStar: __importStar$b,
__makeTemplateObject: __makeTemplateObject,
__metadata: __metadata,
@@ -4384,7 +4386,7 @@ var constants$9 = {
headerNameLowerCasedRecord: headerNameLowerCasedRecord$1
};
-const assert$f = require$$0$7;
+const assert$d = require$$0$7;
const { kDestroyed: kDestroyed$1, kBodyUsed: kBodyUsed$1 } = symbols$4;
const { IncomingMessage } = require$$0$6;
const stream$6 = require$$0$9;
@@ -4509,7 +4511,7 @@ function getHostname (host) {
if (host[0] === '[') {
const idx = host.indexOf(']');
- assert$f(idx !== -1);
+ assert$d(idx !== -1);
return host.substring(1, idx)
}
@@ -4526,7 +4528,7 @@ function getServerName (host) {
return null
}
- assert$f.strictEqual(typeof host, 'string');
+ assert$d.strictEqual(typeof host, 'string');
const servername = getHostname(host);
if (net$9.isIP(servername)) {
@@ -10536,7 +10538,7 @@ const {
InvalidArgumentError: InvalidArgumentError$k,
NotSupportedError: NotSupportedError$1
} = errors$4;
-const assert$e = require$$0$7;
+const assert$c = require$$0$7;
const { kHTTP2BuildRequest: kHTTP2BuildRequest$1, kHTTP2CopyHeaders: kHTTP2CopyHeaders$1, kHTTP1BuildRequest: kHTTP1BuildRequest$1 } = symbols$4;
const util$s = util$u;
@@ -10784,8 +10786,8 @@ let Request$1 = class Request {
}
onConnect (abort) {
- assert$e(!this.aborted);
- assert$e(!this.completed);
+ assert$c(!this.aborted);
+ assert$c(!this.completed);
if (this.error) {
abort(this.error);
@@ -10796,8 +10798,8 @@ let Request$1 = class Request {
}
onHeaders (statusCode, headers, resume, statusText) {
- assert$e(!this.aborted);
- assert$e(!this.completed);
+ assert$c(!this.aborted);
+ assert$c(!this.completed);
if (channels$1.headers.hasSubscribers) {
channels$1.headers.publish({ request: this, response: { statusCode, headers, statusText } });
@@ -10811,8 +10813,8 @@ let Request$1 = class Request {
}
onData (chunk) {
- assert$e(!this.aborted);
- assert$e(!this.completed);
+ assert$c(!this.aborted);
+ assert$c(!this.completed);
try {
return this[kHandler].onData(chunk)
@@ -10823,8 +10825,8 @@ let Request$1 = class Request {
}
onUpgrade (statusCode, headers, socket) {
- assert$e(!this.aborted);
- assert$e(!this.completed);
+ assert$c(!this.aborted);
+ assert$c(!this.completed);
return this[kHandler].onUpgrade(statusCode, headers, socket)
}
@@ -10832,7 +10834,7 @@ let Request$1 = class Request {
onComplete (trailers) {
this.onFinally();
- assert$e(!this.aborted);
+ assert$c(!this.aborted);
this.completed = true;
if (channels$1.trailers.hasSubscribers) {
@@ -11030,9 +11032,9 @@ function processHeader (request, key, val, skipAppend = false) {
var request$3 = Request$1;
-const EventEmitter$7 = require$$0$5;
+const EventEmitter$5 = require$$0$5;
-let Dispatcher$4 = class Dispatcher extends EventEmitter$7 {
+let Dispatcher$4 = class Dispatcher extends EventEmitter$5 {
dispatch () {
throw new Error('not implemented')
}
@@ -11240,7 +11242,7 @@ let DispatcherBase$4 = class DispatcherBase extends Dispatcher$3 {
var dispatcherBase = DispatcherBase$4;
const net$8 = require$$0$a;
-const assert$d = require$$0$7;
+const assert$b = require$$0$7;
const util$r = util$u;
const { InvalidArgumentError: InvalidArgumentError$i, ConnectTimeoutError } = errors$4;
@@ -11332,7 +11334,7 @@ function buildConnector$4 ({ allowH2, maxCachedSessions, socketPath, timeout, ..
const sessionKey = servername || hostname;
const session = sessionCache.get(sessionKey) || null;
- assert$d(sessionKey);
+ assert$b(sessionKey);
socket = tls$6.connect({
highWaterMark: 16384, // TLS in node can't have bigger HWM anyway...
@@ -11353,7 +11355,7 @@ function buildConnector$4 ({ allowH2, maxCachedSessions, socketPath, timeout, ..
sessionCache.set(sessionKey, session);
});
} else {
- assert$d(!httpSocket, 'httpSocket can only be sent on TLS update');
+ assert$b(!httpSocket, 'httpSocket can only be sent on TLS update');
socket = net$8.connect({
highWaterMark: 64 * 1024, // Same as nodejs fs streams.
...options,
@@ -11736,7 +11738,7 @@ function requireConstants$2 () {
const util$q = util$u;
const { kBodyUsed } = symbols$4;
-const assert$c = require$$0$7;
+const assert$a = require$$0$7;
const { InvalidArgumentError: InvalidArgumentError$h } = errors$4;
const EE = require$$0$5;
@@ -11751,7 +11753,7 @@ class BodyAsyncIterable {
}
async * [Symbol.asyncIterator] () {
- assert$c(!this[kBodyUsed], 'disturbed');
+ assert$a(!this[kBodyUsed], 'disturbed');
this[kBodyUsed] = true;
yield * this[kBody$1];
}
@@ -11780,7 +11782,7 @@ let RedirectHandler$2 = class RedirectHandler {
if (util$q.bodyLength(this.opts.body) === 0) {
this.opts.body
.on('data', function () {
- assert$c(false);
+ assert$a(false);
});
}
@@ -11929,7 +11931,7 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
}
}
} else {
- assert$c(headers == null, 'headers must be an object or an array');
+ assert$a(headers == null, 'headers must be an object or an array');
}
return ret
}
@@ -11978,7 +11980,7 @@ function requireLlhttp_simdWasm () {
/* global WebAssembly */
-const assert$b = require$$0$7;
+const assert$9 = require$$0$7;
const net$7 = require$$0$a;
const http$7 = require$$0$6;
const { pipeline: pipeline$1 } = require$$0$9;
@@ -12399,7 +12401,7 @@ let Client$6 = class Client extends DispatcherBase$3 {
};
function onHttp2SessionError (err) {
- assert$b(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID');
+ assert$9(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID');
this[kSocket][kError$2] = err;
@@ -12427,7 +12429,7 @@ function onHTTP2GoAway (code) {
client[kHTTP2Session] = null;
if (client.destroyed) {
- assert$b(this[kPending$2] === 0);
+ assert$9(this[kPending$2] === 0);
// Fail entire queue.
const requests = client[kQueue$1].splice(client[kRunningIdx]);
@@ -12445,7 +12447,7 @@ function onHTTP2GoAway (code) {
client[kPendingIdx] = client[kRunningIdx];
- assert$b(client[kRunning$3] === 0);
+ assert$9(client[kRunning$3] === 0);
client.emit('disconnect',
client[kUrl$3],
@@ -12485,35 +12487,35 @@ async function lazyllhttp () {
return 0
},
wasm_on_status: (p, at, len) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
const start = at - currentBufferPtr + currentBufferRef.byteOffset;
return currentParser.onStatus(new FastBuffer$3(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_message_begin: (p) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
return currentParser.onMessageBegin() || 0
},
wasm_on_header_field: (p, at, len) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
const start = at - currentBufferPtr + currentBufferRef.byteOffset;
return currentParser.onHeaderField(new FastBuffer$3(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_header_value: (p, at, len) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
const start = at - currentBufferPtr + currentBufferRef.byteOffset;
return currentParser.onHeaderValue(new FastBuffer$3(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
},
wasm_on_body: (p, at, len) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
const start = at - currentBufferPtr + currentBufferRef.byteOffset;
return currentParser.onBody(new FastBuffer$3(currentBufferRef.buffer, start, len)) || 0
},
wasm_on_message_complete: (p) => {
- assert$b.strictEqual(currentParser.ptr, p);
+ assert$9.strictEqual(currentParser.ptr, p);
return currentParser.onMessageComplete() || 0
}
@@ -12537,7 +12539,7 @@ const TIMEOUT_IDLE = 3;
let Parser$1 = class Parser {
constructor (client, socket, { exports }) {
- assert$b(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0);
+ assert$9(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0);
this.llhttp = exports;
this.ptr = this.llhttp.llhttp_alloc(constants$6.TYPE.RESPONSE);
@@ -12591,12 +12593,12 @@ let Parser$1 = class Parser {
return
}
- assert$b(this.ptr != null);
- assert$b(currentParser == null);
+ assert$9(this.ptr != null);
+ assert$9(currentParser == null);
this.llhttp.llhttp_resume(this.ptr);
- assert$b(this.timeoutType === TIMEOUT_BODY);
+ assert$9(this.timeoutType === TIMEOUT_BODY);
if (this.timeout) {
// istanbul ignore else: only for jest
if (this.timeout.refresh) {
@@ -12620,9 +12622,9 @@ let Parser$1 = class Parser {
}
execute (data) {
- assert$b(this.ptr != null);
- assert$b(currentParser == null);
- assert$b(!this.paused);
+ assert$9(this.ptr != null);
+ assert$9(currentParser == null);
+ assert$9(!this.paused);
const { socket, llhttp } = this;
@@ -12682,8 +12684,8 @@ let Parser$1 = class Parser {
}
destroy () {
- assert$b(this.ptr != null);
- assert$b(currentParser == null);
+ assert$9(this.ptr != null);
+ assert$9(currentParser == null);
this.llhttp.llhttp_free(this.ptr);
this.ptr = null;
@@ -12758,21 +12760,21 @@ let Parser$1 = class Parser {
onUpgrade (head) {
const { upgrade, client, socket, headers, statusCode } = this;
- assert$b(upgrade);
+ assert$9(upgrade);
const request = client[kQueue$1][client[kRunningIdx]];
- assert$b(request);
+ assert$9(request);
- assert$b(!socket.destroyed);
- assert$b(socket === client[kSocket]);
- assert$b(!this.paused);
- assert$b(request.upgrade || request.method === 'CONNECT');
+ assert$9(!socket.destroyed);
+ assert$9(socket === client[kSocket]);
+ assert$9(!this.paused);
+ assert$9(request.upgrade || request.method === 'CONNECT');
this.statusCode = null;
this.statusText = '';
this.shouldKeepAlive = null;
- assert$b(this.headers.length % 2 === 0);
+ assert$9(this.headers.length % 2 === 0);
this.headers = [];
this.headersSize = 0;
@@ -12817,8 +12819,8 @@ let Parser$1 = class Parser {
return -1
}
- assert$b(!this.upgrade);
- assert$b(this.statusCode < 200);
+ assert$9(!this.upgrade);
+ assert$9(this.statusCode < 200);
if (statusCode === 100) {
util$p.destroy(socket, new SocketError$2('bad response', util$p.getSocketInfo(socket)));
@@ -12831,7 +12833,7 @@ let Parser$1 = class Parser {
return -1
}
- assert$b.strictEqual(this.timeoutType, TIMEOUT_HEADERS);
+ assert$9.strictEqual(this.timeoutType, TIMEOUT_HEADERS);
this.statusCode = statusCode;
this.shouldKeepAlive = (
@@ -12853,18 +12855,18 @@ let Parser$1 = class Parser {
}
if (request.method === 'CONNECT') {
- assert$b(client[kRunning$3] === 1);
+ assert$9(client[kRunning$3] === 1);
this.upgrade = true;
return 2
}
if (upgrade) {
- assert$b(client[kRunning$3] === 1);
+ assert$9(client[kRunning$3] === 1);
this.upgrade = true;
return 2
}
- assert$b(this.headers.length % 2 === 0);
+ assert$9(this.headers.length % 2 === 0);
this.headers = [];
this.headersSize = 0;
@@ -12919,9 +12921,9 @@ let Parser$1 = class Parser {
}
const request = client[kQueue$1][client[kRunningIdx]];
- assert$b(request);
+ assert$9(request);
- assert$b.strictEqual(this.timeoutType, TIMEOUT_BODY);
+ assert$9.strictEqual(this.timeoutType, TIMEOUT_BODY);
if (this.timeout) {
// istanbul ignore else: only for jest
if (this.timeout.refresh) {
@@ -12929,7 +12931,7 @@ let Parser$1 = class Parser {
}
}
- assert$b(statusCode >= 200);
+ assert$9(statusCode >= 200);
if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) {
util$p.destroy(socket, new ResponseExceededMaxSizeError());
@@ -12955,9 +12957,9 @@ let Parser$1 = class Parser {
}
const request = client[kQueue$1][client[kRunningIdx]];
- assert$b(request);
+ assert$9(request);
- assert$b(statusCode >= 100);
+ assert$9(statusCode >= 100);
this.statusCode = null;
this.statusText = '';
@@ -12966,7 +12968,7 @@ let Parser$1 = class Parser {
this.keepAlive = '';
this.connection = '';
- assert$b(this.headers.length % 2 === 0);
+ assert$9(this.headers.length % 2 === 0);
this.headers = [];
this.headersSize = 0;
@@ -12985,7 +12987,7 @@ let Parser$1 = class Parser {
client[kQueue$1][client[kRunningIdx]++] = null;
if (socket[kWriting]) {
- assert$b.strictEqual(client[kRunning$3], 0);
+ assert$9.strictEqual(client[kRunning$3], 0);
// Response completed before request.
util$p.destroy(socket, new InformationalError('reset'));
return constants$6.ERROR.PAUSED
@@ -13016,7 +13018,7 @@ function onParserTimeout (parser) {
/* istanbul ignore else */
if (timeoutType === TIMEOUT_HEADERS) {
if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning$3] > 1) {
- assert$b(!parser.paused, 'cannot be paused while waiting for headers');
+ assert$9(!parser.paused, 'cannot be paused while waiting for headers');
util$p.destroy(socket, new HeadersTimeoutError());
}
} else if (timeoutType === TIMEOUT_BODY) {
@@ -13024,7 +13026,7 @@ function onParserTimeout (parser) {
util$p.destroy(socket, new BodyTimeoutError());
}
} else if (timeoutType === TIMEOUT_IDLE) {
- assert$b(client[kRunning$3] === 0 && client[kKeepAliveTimeoutValue]);
+ assert$9(client[kRunning$3] === 0 && client[kKeepAliveTimeoutValue]);
util$p.destroy(socket, new InformationalError('socket idle timeout'));
}
}
@@ -13039,7 +13041,7 @@ function onSocketReadable () {
function onSocketError (err) {
const { [kClient$1]: client, [kParser]: parser } = this;
- assert$b(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID');
+ assert$9(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID');
if (client[kHTTPConnVersion] !== 'h2') {
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
@@ -13065,14 +13067,14 @@ function onError (client, err) {
// Error is not caused by running request and not a recoverable
// socket error.
- assert$b(client[kPendingIdx] === client[kRunningIdx]);
+ assert$9(client[kPendingIdx] === client[kRunningIdx]);
const requests = client[kQueue$1].splice(client[kRunningIdx]);
for (let i = 0; i < requests.length; i++) {
const request = requests[i];
errorRequest(client, request, err);
}
- assert$b(client[kSize$4] === 0);
+ assert$9(client[kSize$4] === 0);
}
}
@@ -13108,7 +13110,7 @@ function onSocketClose () {
client[kSocket] = null;
if (client.destroyed) {
- assert$b(client[kPending$2] === 0);
+ assert$9(client[kPending$2] === 0);
// Fail entire queue.
const requests = client[kQueue$1].splice(client[kRunningIdx]);
@@ -13126,7 +13128,7 @@ function onSocketClose () {
client[kPendingIdx] = client[kRunningIdx];
- assert$b(client[kRunning$3] === 0);
+ assert$9(client[kRunning$3] === 0);
client.emit('disconnect', client[kUrl$3], [client], err);
@@ -13134,8 +13136,8 @@ function onSocketClose () {
}
async function connect$1 (client) {
- assert$b(!client[kConnecting]);
- assert$b(!client[kSocket]);
+ assert$9(!client[kConnecting]);
+ assert$9(!client[kSocket]);
let { host, hostname, protocol, port } = client[kUrl$3];
@@ -13143,10 +13145,10 @@ async function connect$1 (client) {
if (hostname[0] === '[') {
const idx = hostname.indexOf(']');
- assert$b(idx !== -1);
+ assert$9(idx !== -1);
const ip = hostname.substring(1, idx);
- assert$b(net$7.isIP(ip));
+ assert$9(net$7.isIP(ip));
hostname = ip;
}
@@ -13191,7 +13193,7 @@ async function connect$1 (client) {
client[kConnecting] = false;
- assert$b(socket);
+ assert$9(socket);
const isH2 = socket.alpnProtocol === 'h2';
if (isH2) {
@@ -13283,7 +13285,7 @@ async function connect$1 (client) {
}
if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
- assert$b(client[kRunning$3] === 0);
+ assert$9(client[kRunning$3] === 0);
while (client[kPending$2] > 0 && client[kQueue$1][client[kPendingIdx]].servername === client[kServerName]) {
const request = client[kQueue$1][client[kPendingIdx]++];
errorRequest(client, request, err);
@@ -13323,7 +13325,7 @@ function resume$2 (client, sync) {
function _resume (client, sync) {
while (true) {
if (client.destroyed) {
- assert$b(client[kPending$2] === 0);
+ assert$9(client[kPending$2] === 0);
return
}
@@ -13581,12 +13583,12 @@ function write (client, request) {
if (contentLength === 0) {
socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1');
} else {
- assert$b(contentLength === null, 'no body must not have content length');
+ assert$9(contentLength === null, 'no body must not have content length');
socket.write(`${header}\r\n`, 'latin1');
}
request.onRequestSent();
} else if (util$p.isBuffer(body)) {
- assert$b(contentLength === body.byteLength, 'buffer body must have content length');
+ assert$9(contentLength === body.byteLength, 'buffer body must have content length');
socket.cork();
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1');
@@ -13608,7 +13610,7 @@ function write (client, request) {
} else if (util$p.isIterable(body)) {
writeIterable({ body, client, request, socket, contentLength, header, expectsPayload });
} else {
- assert$b(false);
+ assert$9(false);
}
return true
@@ -13730,7 +13732,7 @@ function writeH2 (client, session, request) {
}
if (contentLength != null) {
- assert$b(body, 'no body must not have content length');
+ assert$9(body, 'no body must not have content length');
headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`;
}
@@ -13819,7 +13821,7 @@ function writeH2 (client, session, request) {
if (!body) {
request.onRequestSent();
} else if (util$p.isBuffer(body)) {
- assert$b(contentLength === body.byteLength, 'buffer body must have content length');
+ assert$9(contentLength === body.byteLength, 'buffer body must have content length');
stream.cork();
stream.write(body);
stream.uncork();
@@ -13873,13 +13875,13 @@ function writeH2 (client, session, request) {
socket: client[kSocket]
});
} else {
- assert$b(false);
+ assert$9(false);
}
}
}
function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) {
- assert$b(contentLength !== 0 || client[kRunning$3] === 0, 'stream body cannot be pipelined');
+ assert$9(contentLength !== 0 || client[kRunning$3] === 0, 'stream body cannot be pipelined');
if (client[kHTTPConnVersion] === 'h2') {
// For HTTP/2, is enough to pipe the stream
@@ -13949,7 +13951,7 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength,
finished = true;
- assert$b(socket.destroyed || (socket[kWriting] && client[kRunning$3] <= 1));
+ assert$9(socket.destroyed || (socket[kWriting] && client[kRunning$3] <= 1));
socket
.off('drain', onDrain)
@@ -13994,7 +13996,7 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength,
}
async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) {
- assert$b(contentLength === body.size, 'blob body must have content length');
+ assert$9(contentLength === body.size, 'blob body must have content length');
const isH2 = client[kHTTPConnVersion] === 'h2';
try {
@@ -14029,7 +14031,7 @@ async function writeBlob ({ h2stream, body, client, request, socket, contentLeng
}
async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) {
- assert$b(contentLength !== 0 || client[kRunning$3] === 0, 'iterator body cannot be pipelined');
+ assert$9(contentLength !== 0 || client[kRunning$3] === 0, 'iterator body cannot be pipelined');
let callback = null;
function onDrain () {
@@ -14041,7 +14043,7 @@ async function writeIterable ({ h2stream, body, client, request, socket, content
}
const waitForDrain = () => new Promise((resolve, reject) => {
- assert$b(callback === null);
+ assert$9(callback === null);
if (socket[kError$2]) {
reject(socket[kError$2]);
@@ -14237,7 +14239,7 @@ class AsyncWriter {
socket[kWriting] = false;
if (err) {
- assert$b(client[kRunning$3] <= 1, 'pipeline should only contain this request');
+ assert$9(client[kRunning$3] <= 1, 'pipeline should only contain this request');
util$p.destroy(socket, err);
}
}
@@ -14246,7 +14248,7 @@ class AsyncWriter {
function errorRequest (client, request, err) {
try {
request.onError(err);
- assert$b(request.aborted);
+ assert$9(request.aborted);
} catch (err) {
client.emit('error', err);
}
@@ -15078,7 +15080,7 @@ var api$1 = {};
var apiRequest = {exports: {}};
-const assert$a = require$$0$7;
+const assert$8 = require$$0$7;
const { Readable: Readable$4 } = require$$0$9;
const { RequestAbortedError: RequestAbortedError$7, NotSupportedError, InvalidArgumentError: InvalidArgumentError$c } = errors$4;
const util$m = util$u;
@@ -15221,7 +15223,7 @@ var readable$1 = class BodyReadable extends Readable$4 {
if (this[kConsume]) {
// TODO: Is this the best way to force a lock?
this[kBody].getReader(); // Ensure stream is locked.
- assert$a(this[kBody].locked);
+ assert$8(this[kBody].locked);
}
}
return this[kBody]
@@ -15290,7 +15292,7 @@ async function consume (stream, type) {
throw new TypeError('unusable')
}
- assert$a(!stream[kConsume]);
+ assert$8(!stream[kConsume]);
return new Promise((resolve, reject) => {
stream[kConsume] = {
@@ -15397,14 +15399,14 @@ function consumeFinish (consume, err) {
consume.body = null;
}
-const assert$9 = require$$0$7;
+const assert$7 = require$$0$7;
const {
ResponseStatusCodeError
} = errors$4;
const { toUSVString } = util$u;
async function getResolveErrorBodyCallback$2 ({ callback, body, contentType, statusCode, statusMessage, headers }) {
- assert$9(body);
+ assert$7(body);
let chunks = [];
let limit = 0;
@@ -15912,7 +15914,7 @@ const {
const util$i = util$u;
const { AsyncResource: AsyncResource$2 } = require$$4$1;
const { addSignal: addSignal$2, removeSignal: removeSignal$2 } = abortSignal;
-const assert$8 = require$$0$7;
+const assert$6 = require$$0$7;
const kResume = Symbol('resume');
@@ -16046,7 +16048,7 @@ class PipelineHandler extends AsyncResource$2 {
onConnect (abort, context) {
const { ret, res } = this;
- assert$8(!res, 'pipeline cannot be retried');
+ assert$6(!res, 'pipeline cannot be retried');
if (ret.destroyed) {
throw new RequestAbortedError$3()
@@ -16151,7 +16153,7 @@ const { InvalidArgumentError: InvalidArgumentError$8, RequestAbortedError: Reque
const { AsyncResource: AsyncResource$1 } = require$$4$1;
const util$h = util$u;
const { addSignal: addSignal$1, removeSignal: removeSignal$1 } = abortSignal;
-const assert$7 = require$$0$7;
+const assert$5 = require$$0$7;
class UpgradeHandler extends AsyncResource$1 {
constructor (opts, callback) {
@@ -16196,7 +16198,7 @@ class UpgradeHandler extends AsyncResource$1 {
onUpgrade (statusCode, rawHeaders, socket) {
const { callback, opaque, context } = this;
- assert$7.strictEqual(statusCode, 101);
+ assert$5.strictEqual(statusCode, 101);
removeSignal$1(this);
@@ -17496,7 +17498,7 @@ function throwIfProxyAuthIsSent (headers) {
var proxyAgent = ProxyAgent$1;
-const assert$6 = require$$0$7;
+const assert$4 = require$$0$7;
const { kRetryHandlerDefaultRetry } = symbols$4;
const { RequestRetryError } = errors$4;
@@ -17712,8 +17714,8 @@ let RetryHandler$1 = class RetryHandler {
const { start, size, end = size } = contentRange;
- assert$6(this.start === start, 'content-range mismatch');
- assert$6(this.end == null || this.end === end, 'content-range mismatch');
+ assert$4(this.start === start, 'content-range mismatch');
+ assert$4(this.end == null || this.end === end, 'content-range mismatch');
this.resume = resume;
return true
@@ -17735,12 +17737,12 @@ let RetryHandler$1 = class RetryHandler {
const { start, size, end = size } = range;
- assert$6(
+ assert$4(
start != null && Number.isFinite(start) && this.start !== start,
'content-range mismatch'
);
- assert$6(Number.isFinite(start));
- assert$6(
+ assert$4(Number.isFinite(start));
+ assert$4(
end != null && Number.isFinite(end) && this.end !== end,
'invalid content-length'
);
@@ -17755,8 +17757,8 @@ let RetryHandler$1 = class RetryHandler {
this.end = contentLength != null ? Number(contentLength) : null;
}
- assert$6(Number.isFinite(this.start));
- assert$6(
+ assert$4(Number.isFinite(this.start));
+ assert$4(
this.end == null || Number.isFinite(this.end),
'invalid content-length'
);
@@ -31992,7 +31994,7 @@ const SELECTORS = {
PURCHASE_NUMBER_LIST: '#reportRow .nums'
};
-function mitt$1(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}}
+function mitt(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e]);},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]));},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e);}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e);});}}}
/**
* Copyright 2022 Google Inc. All rights reserved.
@@ -32021,13 +32023,13 @@ function mitt$1(n){return {all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.
*
* @public
*/
-let EventEmitter$6 = class EventEmitter {
+let EventEmitter$4 = class EventEmitter {
/**
* @internal
*/
constructor() {
this.eventsMap = new Map();
- this.emitter = mitt$1(this.eventsMap);
+ this.emitter = mitt(this.eventsMap);
}
/**
* Bind an event listener to fire when an event occurs.
@@ -32203,7 +32205,7 @@ const WEB_PERMISSION_TO_PROTOCOL_PERMISSION = new Map([
*
* @public
*/
-let Browser$1 = class Browser extends EventEmitter$6 {
+let Browser$1 = class Browser extends EventEmitter$4 {
/**
* @internal
*/
@@ -32411,7 +32413,7 @@ let Browser$1 = class Browser extends EventEmitter$6 {
*
* @public
*/
-let BrowserContext$1 = class BrowserContext extends EventEmitter$6 {
+let BrowserContext$1 = class BrowserContext extends EventEmitter$4 {
/**
* @internal
*/
@@ -32514,7 +32516,7 @@ let BrowserContext$1 = class BrowserContext extends EventEmitter$6 {
*
* @internal
*/
-const assert$5 = (value, message) => {
+const assert$3 = (value, message) => {
if (!value) {
throw new Error(message);
}
@@ -33961,7 +33963,7 @@ class QueryHandler {
*/
static async *queryAll(element, selector) {
const world = element.executionContext()._world;
- assert$5(world);
+ assert$3(world);
const handle = await element.evaluateHandle(this._querySelectorAll, selector, LazyArg.create(context => {
return context.puppeteerUtil;
}));
@@ -33974,7 +33976,7 @@ class QueryHandler {
*/
static async queryOne(element, selector) {
const world = element.executionContext()._world;
- assert$5(world);
+ assert$3(world);
const result = await element.evaluateHandle(this._querySelector, selector, LazyArg.create(context => {
return context.puppeteerUtil;
}));
@@ -34093,7 +34095,7 @@ const parseARIASelector = (selector) => {
const queryOptions = {};
const defaultName = selector.replace(ATTRIBUTE_REGEXP, (_, attribute, __, value) => {
attribute = attribute.trim();
- assert$5(isKnownAttribute(attribute), `Unknown aria attribute "${attribute}" in selector`);
+ assert$3(isKnownAttribute(attribute), `Unknown aria attribute "${attribute}" in selector`);
queryOptions[attribute] = normalizeValue$1(value);
return '';
});
@@ -34263,9 +34265,9 @@ class CustomQueryHandlerRegistry {
if (__classPrivateFieldGet$H(this, _CustomQueryHandlerRegistry_handlers, "f").has(name)) {
throw new Error(`Cannot register over existing handler: ${name}`);
}
- assert$5(!__classPrivateFieldGet$H(this, _CustomQueryHandlerRegistry_handlers, "f").has(name), `Cannot register over existing handler: ${name}`);
- assert$5(/^[a-zA-Z]+$/.test(name), `Custom query handler names may only contain [a-zA-Z]`);
- assert$5(handler.queryAll || handler.queryOne, `At least one query method must be implemented.`);
+ assert$3(!__classPrivateFieldGet$H(this, _CustomQueryHandlerRegistry_handlers, "f").has(name), `Cannot register over existing handler: ${name}`);
+ assert$3(/^[a-zA-Z]+$/.test(name), `Custom query handler names may only contain [a-zA-Z]`);
+ assert$3(handler.queryAll || handler.queryOne, `At least one query method must be implemented.`);
const Handler = (_a = class extends QueryHandler {
},
__setFunctionName(_a, "Handler"),
@@ -34554,7 +34556,7 @@ class CDPJSHandle extends JSHandle$2 {
}, propertyName);
}
async getProperties() {
- assert$5(__classPrivateFieldGet$G(this, _CDPJSHandle_remoteObject, "f").objectId);
+ assert$3(__classPrivateFieldGet$G(this, _CDPJSHandle_remoteObject, "f").objectId);
// We use Runtime.getProperties rather than iterative building because the
// iterative approach might create a distorted snapshot.
const response = await this.client.send('Runtime.getProperties', {
@@ -34860,7 +34862,7 @@ class CDPElementHandle extends ElementHandle$1 {
* This method creates and captures a dragevent from the element.
*/
async drag(target) {
- assert$5(__classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).isDragInterceptionEnabled(), 'Drag Interception is not enabled!');
+ assert$3(__classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).isDragInterceptionEnabled(), 'Drag Interception is not enabled!');
await __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "m", _CDPElementHandle_scrollIntoViewIfNeeded).call(this);
const start = await this.clickablePoint();
return await __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).mouse.drag(start, target);
@@ -34881,7 +34883,7 @@ class CDPElementHandle extends ElementHandle$1 {
await __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).mouse.drop(destination, data);
}
async dragAndDrop(target, options) {
- assert$5(__classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).isDragInterceptionEnabled(), 'Drag Interception is not enabled!');
+ assert$3(__classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).isDragInterceptionEnabled(), 'Drag Interception is not enabled!');
await __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "m", _CDPElementHandle_scrollIntoViewIfNeeded).call(this);
const startPoint = await this.clickablePoint();
const targetPoint = await target.clickablePoint();
@@ -34889,7 +34891,7 @@ class CDPElementHandle extends ElementHandle$1 {
}
async select(...values) {
for (const value of values) {
- assert$5(isString$3(value), 'Values must be strings. Found value "' +
+ assert$3(isString$3(value), 'Values must be strings. Found value "' +
value +
'" of type "' +
typeof value +
@@ -34930,7 +34932,7 @@ class CDPElementHandle extends ElementHandle$1 {
const isMultiple = await this.evaluate(element => {
return element.multiple;
});
- assert$5(filePaths.length <= 1 || isMultiple, 'Multiple file uploads only work with ');
+ assert$3(filePaths.length <= 1 || isMultiple, 'Multiple file uploads only work with ');
// Locate all files and confirm that they exist.
let path;
try {
@@ -35042,7 +35044,7 @@ class CDPElementHandle extends ElementHandle$1 {
async screenshot(options = {}) {
let needsViewportReset = false;
let boundingBox = await this.boundingBox();
- assert$5(boundingBox, 'Node is either not visible or not an HTMLElement');
+ assert$3(boundingBox, 'Node is either not visible or not an HTMLElement');
const viewport = __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "a", _CDPElementHandle_page_get).viewport();
if (viewport &&
(boundingBox.width > viewport.width ||
@@ -35056,9 +35058,9 @@ class CDPElementHandle extends ElementHandle$1 {
}
await __classPrivateFieldGet$F(this, _CDPElementHandle_instances, "m", _CDPElementHandle_scrollIntoViewIfNeeded).call(this);
boundingBox = await this.boundingBox();
- assert$5(boundingBox, 'Node is either not visible or not an HTMLElement');
- assert$5(boundingBox.width !== 0, 'Node has 0 width.');
- assert$5(boundingBox.height !== 0, 'Node has 0 height.');
+ assert$3(boundingBox, 'Node is either not visible or not an HTMLElement');
+ assert$3(boundingBox.width !== 0, 'Node has 0 width.');
+ assert$3(boundingBox.height !== 0, 'Node has 0 height.');
const layoutMetrics = await this.client.send('Page.getLayoutMetrics');
// Fallback to `layoutViewport` in case of using Firefox.
const { pageX, pageY } = layoutMetrics.cssVisualViewport || layoutMetrics.layoutViewport;
@@ -35362,7 +35364,7 @@ const getSourcePuppeteerURLIfAvailable = (object) => {
* @internal
*/
function valueFromRemoteObject(remoteObject) {
- assert$5(!remoteObject.objectId, 'Cannot extract value when objectId is given');
+ assert$3(!remoteObject.objectId, 'Cannot extract value when objectId is given');
if (remoteObject.unserializableValue) {
if (remoteObject.type === 'bigint') {
return BigInt(remoteObject.unserializableValue.replace('n', ''));
@@ -35486,7 +35488,7 @@ function createJSHandle(context, remoteObject) {
*/
function evaluationString(fun, ...args) {
if (isString$3(fun)) {
- assert$5(args.length === 0, 'Cannot evaluate a string with arguments');
+ assert$3(args.length === 0, 'Cannot evaluate a string with arguments');
return fun;
}
function serializeArgument(arg) {
@@ -35721,15 +35723,15 @@ class HTTPRequest extends HTTPRequest$1 {
return __classPrivateFieldGet$D(this, _HTTPRequest_url, "f");
}
continueRequestOverrides() {
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
return __classPrivateFieldGet$D(this, _HTTPRequest_continueRequestOverrides, "f");
}
responseForRequest() {
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
return __classPrivateFieldGet$D(this, _HTTPRequest_responseForRequest, "f");
}
abortErrorReason() {
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
return __classPrivateFieldGet$D(this, _HTTPRequest_abortErrorReason, "f");
}
interceptResolutionState() {
@@ -35804,8 +35806,8 @@ class HTTPRequest extends HTTPRequest$1 {
if (__classPrivateFieldGet$D(this, _HTTPRequest_url, "f").startsWith('data:')) {
return;
}
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
- assert$5(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
if (priority === undefined) {
return __classPrivateFieldGet$D(this, _HTTPRequest_instances, "m", _HTTPRequest_continue).call(this, overrides);
}
@@ -35833,8 +35835,8 @@ class HTTPRequest extends HTTPRequest$1 {
if (__classPrivateFieldGet$D(this, _HTTPRequest_url, "f").startsWith('data:')) {
return;
}
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
- assert$5(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
if (priority === undefined) {
return __classPrivateFieldGet$D(this, _HTTPRequest_instances, "m", _HTTPRequest_respond).call(this, response);
}
@@ -35860,9 +35862,9 @@ class HTTPRequest extends HTTPRequest$1 {
return;
}
const errorReason = errorReasons[errorCode];
- assert$5(errorReason, 'Unknown error code: ' + errorCode);
- assert$5(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
- assert$5(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
+ assert$3(errorReason, 'Unknown error code: ' + errorCode);
+ assert$3(__classPrivateFieldGet$D(this, _HTTPRequest_allowInterception, "f"), 'Request Interception is not enabled!');
+ assert$3(!__classPrivateFieldGet$D(this, _HTTPRequest_interceptionHandled, "f"), 'Request is already handled!');
if (priority === undefined) {
return __classPrivateFieldGet$D(this, _HTTPRequest_instances, "m", _HTTPRequest_abort).call(this, errorReason);
}
@@ -36535,7 +36537,7 @@ const NetworkManagerEmittedEvents = {
/**
* @internal
*/
-class NetworkManager extends EventEmitter$6 {
+class NetworkManager extends EventEmitter$4 {
constructor(client, ignoreHTTPSErrors, frameManager) {
super();
_NetworkManager_instances.add(this);
@@ -36603,7 +36605,7 @@ class NetworkManager extends EventEmitter$6 {
__classPrivateFieldSet$y(this, _NetworkManager_extraHTTPHeaders, {}, "f");
for (const key of Object.keys(extraHTTPHeaders)) {
const value = extraHTTPHeaders[key];
- assert$5(isString$3(value), `Expected value of header "${key}" to be String, but "${typeof value}" is found.`);
+ assert$3(isString$3(value), `Expected value of header "${key}" to be String, but "${typeof value}" is found.`);
__classPrivateFieldGet$z(this, _NetworkManager_extraHTTPHeaders, "f")[key.toLowerCase()] = value;
}
await __classPrivateFieldGet$z(this, _NetworkManager_client, "f").send('Network.setExtraHTTPHeaders', {
@@ -37025,7 +37027,7 @@ var LocatorEmittedEvents;
*
* @internal
*/
-class Locator extends EventEmitter$6 {
+class Locator extends EventEmitter$4 {
constructor(page, selector, options = {
visibility: 'visible',
timeout: page.getDefaultTimeout(),
@@ -37466,7 +37468,7 @@ var _Page_handlerMap;
*
* @public
*/
-let Page$1 = class Page extends EventEmitter$6 {
+let Page$1 = class Page extends EventEmitter$4 {
/**
* @internal
*/
@@ -37950,7 +37952,7 @@ let Page$1 = class Page extends EventEmitter$6 {
let height = 11;
if (options.format) {
const format = paperFormats[options.format.toLowerCase()];
- assert$5(format, 'Unknown paper format: ' + options.format);
+ assert$3(format, 'Unknown paper format: ' + options.format);
width = format.width;
height = format.height;
}
@@ -38072,7 +38074,7 @@ function convertPrintParameterToInches$2(parameter, lengthUnit = 'in') {
valueText = text;
}
const value = Number(valueText);
- assert$5(!isNaN(value), 'Failed to parse parameter value: ' + text);
+ assert$3(!isNaN(value), 'Failed to parse parameter value: ' + text);
pixels = value * unitToPixels$2[unit];
}
else {
@@ -38898,7 +38900,7 @@ _CallbackRegistry_callbacks = new WeakMap(), _CallbackRegistry_idGenerator = new
/**
* @public
*/
-class Connection extends EventEmitter$6 {
+class Connection extends EventEmitter$4 {
constructor(url, transport, delay = 0, timeout) {
super();
_Connection_instances.add(this);
@@ -39113,7 +39115,7 @@ const CDPSessionEmittedEvents = {
*
* @public
*/
-let CDPSession$2 = class CDPSession extends EventEmitter$6 {
+let CDPSession$2 = class CDPSession extends EventEmitter$4 {
/**
* @internal
*/
@@ -39181,7 +39183,7 @@ class CDPSessionImpl extends CDPSession$2 {
}
}
else {
- assert$5(!object.id);
+ assert$3(!object.id);
this.emit(object.method, object.params);
}
}
@@ -39553,7 +39555,7 @@ let JSCoverage$1 = class JSCoverage {
__classPrivateFieldSet$s(this, _JSCoverage_client, client, "f");
}
async start(options = {}) {
- assert$5(!__classPrivateFieldGet$s(this, _JSCoverage_enabled, "f"), 'JSCoverage is already enabled');
+ assert$3(!__classPrivateFieldGet$s(this, _JSCoverage_enabled, "f"), 'JSCoverage is already enabled');
const { resetOnNavigation = true, reportAnonymousScripts = false, includeRawScriptCoverage = false, useBlockCoverage = true, } = options;
__classPrivateFieldSet$s(this, _JSCoverage_resetOnNavigation, resetOnNavigation, "f");
__classPrivateFieldSet$s(this, _JSCoverage_reportAnonymousScripts, reportAnonymousScripts, "f");
@@ -39576,7 +39578,7 @@ let JSCoverage$1 = class JSCoverage {
]);
}
async stop() {
- assert$5(__classPrivateFieldGet$s(this, _JSCoverage_enabled, "f"), 'JSCoverage is not enabled');
+ assert$3(__classPrivateFieldGet$s(this, _JSCoverage_enabled, "f"), 'JSCoverage is not enabled');
__classPrivateFieldSet$s(this, _JSCoverage_enabled, false, "f");
const result = await Promise.all([
__classPrivateFieldGet$s(this, _JSCoverage_client, "f").send('Profiler.takePreciseCoverage'),
@@ -39653,7 +39655,7 @@ let CSSCoverage$1 = class CSSCoverage {
__classPrivateFieldSet$s(this, _CSSCoverage_client, client, "f");
}
async start(options = {}) {
- assert$5(!__classPrivateFieldGet$s(this, _CSSCoverage_enabled, "f"), 'CSSCoverage is already enabled');
+ assert$3(!__classPrivateFieldGet$s(this, _CSSCoverage_enabled, "f"), 'CSSCoverage is already enabled');
const { resetOnNavigation = true } = options;
__classPrivateFieldSet$s(this, _CSSCoverage_resetOnNavigation, resetOnNavigation, "f");
__classPrivateFieldSet$s(this, _CSSCoverage_enabled, true, "f");
@@ -39670,7 +39672,7 @@ let CSSCoverage$1 = class CSSCoverage {
]);
}
async stop() {
- assert$5(__classPrivateFieldGet$s(this, _CSSCoverage_enabled, "f"), 'CSSCoverage is not enabled');
+ assert$3(__classPrivateFieldGet$s(this, _CSSCoverage_enabled, "f"), 'CSSCoverage is not enabled');
__classPrivateFieldSet$s(this, _CSSCoverage_enabled, false, "f");
const ruleTrackingResponse = await __classPrivateFieldGet$s(this, _CSSCoverage_client, "f").send('CSS.stopRuleUsageTracking');
await Promise.all([
@@ -39695,9 +39697,9 @@ let CSSCoverage$1 = class CSSCoverage {
const coverage = [];
for (const styleSheetId of __classPrivateFieldGet$s(this, _CSSCoverage_stylesheetURLs, "f").keys()) {
const url = __classPrivateFieldGet$s(this, _CSSCoverage_stylesheetURLs, "f").get(styleSheetId);
- assert$5(typeof url !== 'undefined', `Stylesheet URL is undefined (styleSheetId=${styleSheetId})`);
+ assert$3(typeof url !== 'undefined', `Stylesheet URL is undefined (styleSheetId=${styleSheetId})`);
const text = __classPrivateFieldGet$s(this, _CSSCoverage_stylesheetSources, "f").get(styleSheetId);
- assert$5(typeof text !== 'undefined', `Stylesheet text is undefined (styleSheetId=${styleSheetId})`);
+ assert$3(typeof text !== 'undefined', `Stylesheet text is undefined (styleSheetId=${styleSheetId})`);
const ranges = convertToDisjointRanges$1(styleSheetIdToCoverage.get(styleSheetId) || []);
coverage.push({ url, ranges, text });
}
@@ -39876,7 +39878,7 @@ let Dialog$1 = class Dialog {
*
*/
async accept(promptText) {
- assert$5(!__classPrivateFieldGet$r(this, _Dialog_handled, "f"), 'Cannot accept dialog which is already handled!');
+ assert$3(!__classPrivateFieldGet$r(this, _Dialog_handled, "f"), 'Cannot accept dialog which is already handled!');
__classPrivateFieldSet$r(this, _Dialog_handled, true, "f");
await __classPrivateFieldGet$r(this, _Dialog_client, "f").send('Page.handleJavaScriptDialog', {
accept: true,
@@ -39887,7 +39889,7 @@ let Dialog$1 = class Dialog {
* A promise which will resolve once the dialog has been dismissed
*/
async dismiss() {
- assert$5(!__classPrivateFieldGet$r(this, _Dialog_handled, "f"), 'Cannot dismiss dialog which is already handled!');
+ assert$3(!__classPrivateFieldGet$r(this, _Dialog_handled, "f"), 'Cannot dismiss dialog which is already handled!');
__classPrivateFieldSet$r(this, _Dialog_handled, true, "f");
await __classPrivateFieldGet$r(this, _Dialog_client, "f").send('Page.handleJavaScriptDialog', {
accept: false,
@@ -40025,7 +40027,7 @@ let FileChooser$2 = class FileChooser {
* absolute.
*/
async accept(paths) {
- assert$5(!__classPrivateFieldGet$p(this, _FileChooser_handled, "f"), 'Cannot accept FileChooser which is already handled!');
+ assert$3(!__classPrivateFieldGet$p(this, _FileChooser_handled, "f"), 'Cannot accept FileChooser which is already handled!');
__classPrivateFieldSet$p(this, _FileChooser_handled, true, "f");
await __classPrivateFieldGet$p(this, _FileChooser_element, "f").uploadFile(...paths);
}
@@ -40033,7 +40035,7 @@ let FileChooser$2 = class FileChooser {
* Closes the file chooser without selecting any files.
*/
cancel() {
- assert$5(!__classPrivateFieldGet$p(this, _FileChooser_handled, "f"), 'Cannot cancel FileChooser which is already handled!');
+ assert$3(!__classPrivateFieldGet$p(this, _FileChooser_handled, "f"), 'Cannot cancel FileChooser which is already handled!');
__classPrivateFieldSet$p(this, _FileChooser_handled, true, "f");
}
};
@@ -40154,9 +40156,9 @@ class DeviceRequestPrompt {
* Select a device in the prompt's list.
*/
async select(device) {
- assert$5(__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f") !== null, 'Cannot select device through detached session!');
- assert$5(this.devices.includes(device), 'Cannot select unknown device!');
- assert$5(!__classPrivateFieldGet$o(this, _DeviceRequestPrompt_handled, "f"), 'Cannot select DeviceRequestPrompt which is already handled!');
+ assert$3(__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f") !== null, 'Cannot select device through detached session!');
+ assert$3(this.devices.includes(device), 'Cannot select unknown device!');
+ assert$3(!__classPrivateFieldGet$o(this, _DeviceRequestPrompt_handled, "f"), 'Cannot select DeviceRequestPrompt which is already handled!');
__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f").off('DeviceAccess.deviceRequestPrompted', __classPrivateFieldGet$o(this, _DeviceRequestPrompt_updateDevicesHandle, "f"));
__classPrivateFieldSet$o(this, _DeviceRequestPrompt_handled, true, "f");
return __classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f").send('DeviceAccess.selectPrompt', {
@@ -40168,8 +40170,8 @@ class DeviceRequestPrompt {
* Cancel the prompt.
*/
async cancel() {
- assert$5(__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f") !== null, 'Cannot cancel prompt through detached session!');
- assert$5(!__classPrivateFieldGet$o(this, _DeviceRequestPrompt_handled, "f"), 'Cannot cancel DeviceRequestPrompt which is already handled!');
+ assert$3(__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f") !== null, 'Cannot cancel prompt through detached session!');
+ assert$3(!__classPrivateFieldGet$o(this, _DeviceRequestPrompt_handled, "f"), 'Cannot cancel DeviceRequestPrompt which is already handled!');
__classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f").off('DeviceAccess.deviceRequestPrompted', __classPrivateFieldGet$o(this, _DeviceRequestPrompt_updateDevicesHandle, "f"));
__classPrivateFieldSet$o(this, _DeviceRequestPrompt_handled, true, "f");
return __classPrivateFieldGet$o(this, _DeviceRequestPrompt_client, "f").send('DeviceAccess.cancelPrompt', { id: __classPrivateFieldGet$o(this, _DeviceRequestPrompt_id, "f") });
@@ -40220,7 +40222,7 @@ class DeviceRequestPromptManager {
* requestDevice.
*/
async waitForDevicePrompt(options = {}) {
- assert$5(__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_client, "f") !== null, 'Cannot wait for device prompt through detached session!');
+ assert$3(__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_client, "f") !== null, 'Cannot wait for device prompt through detached session!');
const needsEnable = __classPrivateFieldGet$o(this, _DeviceRequestPromptManager_deviceRequestPrompDeferreds, "f").size === 0;
let enablePromise;
if (needsEnable) {
@@ -40248,7 +40250,7 @@ _DeviceRequestPromptManager_client = new WeakMap(), _DeviceRequestPromptManager_
if (!__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_deviceRequestPrompDeferreds, "f").size) {
return;
}
- assert$5(__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_client, "f") !== null);
+ assert$3(__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_client, "f") !== null);
const devicePrompt = new DeviceRequestPrompt(__classPrivateFieldGet$o(this, _DeviceRequestPromptManager_client, "f"), __classPrivateFieldGet$o(this, _DeviceRequestPromptManager_timeoutSettings, "f"), event);
for (const promise of __classPrivateFieldGet$o(this, _DeviceRequestPromptManager_deviceRequestPrompDeferreds, "f")) {
promise.resolve(devicePrompt);
@@ -40631,7 +40633,7 @@ class LifecycleWatcher {
__classPrivateFieldSet$m(this, _LifecycleWatcher_initialLoaderId, frame._loaderId, "f");
__classPrivateFieldSet$m(this, _LifecycleWatcher_expectedLifecycle, waitUntil.map(value => {
const protocolEvent = puppeteerToProtocolLifecycle.get(value);
- assert$5(protocolEvent, 'Unknown value for options.waitUntil: ' + value);
+ assert$3(protocolEvent, 'Unknown value for options.waitUntil: ' + value);
return protocolEvent;
}), "f");
__classPrivateFieldSet$m(this, _LifecycleWatcher_frameManager, frameManager, "f");
@@ -41011,7 +41013,7 @@ class IsolatedWorld {
_IsolatedWorld_taskManager.set(this, new TaskManager());
// If multiple waitFor are set up asynchronously, we need to wait for the
// first one to set up the binding in the page before running the others.
- _IsolatedWorld_mutex.set(this, new Mutex$2());
+ _IsolatedWorld_mutex.set(this, new Mutex());
_IsolatedWorld_onBindingCalled.set(this, async (event) => {
let payload;
try {
@@ -41144,38 +41146,38 @@ class IsolatedWorld {
}
async click(selector, options = {}) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
await handle.click(options);
await handle.dispose();
}
async focus(selector) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
await handle.focus();
await handle.dispose();
}
async hover(selector) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
await handle.hover();
await handle.dispose();
}
async select(selector, ...values) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
const result = await handle.select(...values);
await handle.dispose();
return result;
}
async tap(selector) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
await handle.tap();
await handle.dispose();
}
async type(selector, text, options) {
const handle = await this.$(selector);
- assert$5(handle, `No element found for selector: ${selector}`);
+ assert$3(handle, `No element found for selector: ${selector}`);
await handle.type(text, options);
await handle.dispose();
}
@@ -41240,7 +41242,7 @@ class IsolatedWorld {
}
async adoptHandle(handle) {
const context = await this.executionContext();
- assert$5(handle.executionContext() !== context, 'Cannot adopt handle that already belongs to this execution context');
+ assert$3(handle.executionContext() !== context, 'Cannot adopt handle that already belongs to this execution context');
const nodeInfo = await __classPrivateFieldGet$k(this, _IsolatedWorld_instances, "a", _IsolatedWorld_client_get).send('DOM.describeNode', {
objectId: handle.id,
});
@@ -41266,7 +41268,7 @@ _IsolatedWorld_frame = new WeakMap(), _IsolatedWorld_document = new WeakMap(), _
}, _IsolatedWorld_timeoutSettings_get = function _IsolatedWorld_timeoutSettings_get() {
return __classPrivateFieldGet$k(this, _IsolatedWorld_instances, "a", _IsolatedWorld_frameManager_get).timeoutSettings;
};
-let Mutex$2 = class Mutex {
+class Mutex {
constructor() {
_Mutex_locked.set(this, false);
_Mutex_acquirers.set(this, []);
@@ -41292,7 +41294,7 @@ let Mutex$2 = class Mutex {
}
resolve();
}
-};
+}
_Mutex_locked = new WeakMap(), _Mutex_acquirers = new WeakMap();
/**
@@ -41595,7 +41597,7 @@ class Frame extends Frame$1 {
return this._frameManager._deviceRequestPromptManager(__classPrivateFieldGet$j(this, _Frame_client, "f"));
}
const parentFrame = this.parentFrame();
- assert$5(parentFrame !== null);
+ assert$3(parentFrame !== null);
return parentFrame._deviceRequestPromptManager();
}
waitForDevicePrompt(options = {}) {
@@ -41792,7 +41794,7 @@ const FrameManagerEmittedEvents = {
*
* @internal
*/
-class FrameManager extends EventEmitter$6 {
+class FrameManager extends EventEmitter$4 {
get timeoutSettings() {
return __classPrivateFieldGet$h(this, _FrameManager_timeoutSettings, "f");
}
@@ -41890,7 +41892,7 @@ class FrameManager extends EventEmitter$6 {
}
executionContextById(contextId, session = __classPrivateFieldGet$h(this, _FrameManager_client, "f")) {
const context = this.getExecutionContextById(contextId, session);
- assert$5(context, 'INTERNAL ERROR: missing context with id = ' + contextId);
+ assert$3(context, 'INTERNAL ERROR: missing context with id = ' + contextId);
return context;
}
getExecutionContextById(contextId, session = __classPrivateFieldGet$h(this, _FrameManager_client, "f")) {
@@ -41901,7 +41903,7 @@ class FrameManager extends EventEmitter$6 {
}
mainFrame() {
const mainFrame = this._frameTree.getMainFrame();
- assert$5(mainFrame, 'Requesting main frame too early!');
+ assert$3(mainFrame, 'Requesting main frame too early!');
return mainFrame;
}
frames() {
@@ -42787,7 +42789,7 @@ _Keyboard_client = new WeakMap(), _Keyboard_pressedKeys = new WeakMap(), _Keyboa
location: 0,
};
const definition = _keyDefinitions[keyString];
- assert$5(definition, `Unknown key: "${keyString}"`);
+ assert$3(definition, `Unknown key: "${keyString}"`);
if (definition.key) {
description.key = definition.key;
}
@@ -43393,7 +43395,7 @@ let Tracing$1 = class Tracing {
* @param options - Optional `TracingOptions`.
*/
async start(options = {}) {
- assert$5(!__classPrivateFieldGet$e(this, _Tracing_recording, "f"), 'Cannot start recording trace while already recording trace.');
+ assert$3(!__classPrivateFieldGet$e(this, _Tracing_recording, "f"), 'Cannot start recording trace while already recording trace.');
const defaultCategories = [
'-*',
'devtools.timeline',
@@ -43502,7 +43504,7 @@ var _WebWorker_executionContext, _WebWorker_client, _WebWorker_url;
*
* @public
*/
-class WebWorker extends EventEmitter$6 {
+class WebWorker extends EventEmitter$4 {
/**
* @internal
*/
@@ -43683,7 +43685,7 @@ class CDPPage extends Page$1 {
__classPrivateFieldGet$c(this, _CDPPage_frameManager, "f").onAttachedToTarget(createdTarget);
if (createdTarget._getTargetInfo().type === 'worker') {
const session = createdTarget._session();
- assert$5(session);
+ assert$3(session);
const worker = new WebWorker(session, createdTarget.url(), __classPrivateFieldGet$c(this, _CDPPage_instances, "m", _CDPPage_addConsoleMessage).bind(this), __classPrivateFieldGet$c(this, _CDPPage_instances, "m", _CDPPage_handleException).bind(this));
__classPrivateFieldGet$c(this, _CDPPage_workers, "f").set(session.id(), worker);
this.emit("workercreated" /* PageEmittedEvents.WorkerCreated */, worker);
@@ -43911,8 +43913,8 @@ class CDPPage extends Page$1 {
}
async queryObjects(prototypeHandle) {
const context = await this.mainFrame().executionContext();
- assert$5(!prototypeHandle.disposed, 'Prototype JSHandle is disposed!');
- assert$5(prototypeHandle.id, 'Prototype JSHandle must not be referencing primitive value');
+ assert$3(!prototypeHandle.disposed, 'Prototype JSHandle is disposed!');
+ assert$3(prototypeHandle.id, 'Prototype JSHandle must not be referencing primitive value');
const response = await context._client.send('Runtime.queryObjects', {
prototypeObjectId: prototypeHandle.id,
});
@@ -43960,8 +43962,8 @@ class CDPPage extends Page$1 {
if (!item.url && startsWithHTTP) {
item.url = pageURL;
}
- assert$5(item.url !== 'about:blank', `Blank page can not have cookie "${item.name}"`);
- assert$5(!String.prototype.startsWith.call(item.url || '', 'data:'), `Data URL page can not have cookie "${item.name}"`);
+ assert$3(item.url !== 'about:blank', `Blank page can not have cookie "${item.name}"`);
+ assert$3(!String.prototype.startsWith.call(item.url || '', 'data:'), `Data URL page can not have cookie "${item.name}"`);
return item;
});
await this.deleteCookie(...items);
@@ -44112,7 +44114,7 @@ class CDPPage extends Page$1 {
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Page.setBypassCSP', { enabled });
}
async emulateMediaType(type) {
- assert$5(type === 'screen' ||
+ assert$3(type === 'screen' ||
type === 'print' ||
(type ?? undefined) === undefined, 'Unsupported media type: ' + type);
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Emulation.setEmulatedMedia', {
@@ -44120,7 +44122,7 @@ class CDPPage extends Page$1 {
});
}
async emulateCPUThrottling(factor) {
- assert$5(factor === null || factor >= 1, 'Throttling rate should be greater or equal to 1');
+ assert$3(factor === null || factor >= 1, 'Throttling rate should be greater or equal to 1');
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Emulation.setCPUThrottlingRate', {
rate: factor ?? 1,
});
@@ -44132,7 +44134,7 @@ class CDPPage extends Page$1 {
if (Array.isArray(features)) {
for (const mediaFeature of features) {
const name = mediaFeature.name;
- assert$5(/^(?:prefers-(?:color-scheme|reduced-motion)|color-gamut)$/.test(name), 'Unsupported media feature: ' + name);
+ assert$3(/^(?:prefers-(?:color-scheme|reduced-motion)|color-gamut)$/.test(name), 'Unsupported media feature: ' + name);
}
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Emulation.setEmulatedMedia', {
features: features,
@@ -44173,7 +44175,7 @@ class CDPPage extends Page$1 {
'tritanopia',
]);
try {
- assert$5(!type || visionDeficiencies.has(type), `Unsupported vision deficiency: ${type}`);
+ assert$3(!type || visionDeficiencies.has(type), `Unsupported vision deficiency: ${type}`);
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Emulation.setEmulatedVisionDeficiency', {
type: type || 'none',
});
@@ -44241,28 +44243,28 @@ class CDPPage extends Page$1 {
}
}
if (options.quality) {
- assert$5(screenshotType === "jpeg" /* Protocol.Page.CaptureScreenshotRequestFormat.Jpeg */ ||
+ assert$3(screenshotType === "jpeg" /* Protocol.Page.CaptureScreenshotRequestFormat.Jpeg */ ||
screenshotType === "webp" /* Protocol.Page.CaptureScreenshotRequestFormat.Webp */, 'options.quality is unsupported for the ' +
screenshotType +
' screenshots');
- assert$5(typeof options.quality === 'number', 'Expected options.quality to be a number but found ' +
+ assert$3(typeof options.quality === 'number', 'Expected options.quality to be a number but found ' +
typeof options.quality);
- assert$5(Number.isInteger(options.quality), 'Expected options.quality to be an integer');
- assert$5(options.quality >= 0 && options.quality <= 100, 'Expected options.quality to be between 0 and 100 (inclusive), got ' +
+ assert$3(Number.isInteger(options.quality), 'Expected options.quality to be an integer');
+ assert$3(options.quality >= 0 && options.quality <= 100, 'Expected options.quality to be between 0 and 100 (inclusive), got ' +
options.quality);
}
- assert$5(!options.clip || !options.fullPage, 'options.clip and options.fullPage are exclusive');
+ assert$3(!options.clip || !options.fullPage, 'options.clip and options.fullPage are exclusive');
if (options.clip) {
- assert$5(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' +
+ assert$3(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' +
typeof options.clip.x);
- assert$5(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' +
+ assert$3(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' +
typeof options.clip.y);
- assert$5(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' +
+ assert$3(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' +
typeof options.clip.width);
- assert$5(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' +
+ assert$3(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' +
typeof options.clip.height);
- assert$5(options.clip.width !== 0, 'Expected options.clip.width not to be 0.');
- assert$5(options.clip.height !== 0, 'Expected options.clip.height not to be 0.');
+ assert$3(options.clip.width !== 0, 'Expected options.clip.width not to be 0.');
+ assert$3(options.clip.height !== 0, 'Expected options.clip.height not to be 0.');
}
return __classPrivateFieldGet$c(this, _CDPPage_screenshotTaskQueue, "f").postTask(() => {
return __classPrivateFieldGet$c(this, _CDPPage_instances, "m", _CDPPage_screenshotTask).call(this, screenshotType, options);
@@ -44294,14 +44296,14 @@ class CDPPage extends Page$1 {
if (omitBackground) {
await __classPrivateFieldGet$c(this, _CDPPage_instances, "m", _CDPPage_resetDefaultBackgroundColor).call(this);
}
- assert$5(result.stream, '`stream` is missing from `Page.printToPDF');
+ assert$3(result.stream, '`stream` is missing from `Page.printToPDF');
return getReadableFromProtocolStream(__classPrivateFieldGet$c(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$5(buffer, 'Could not create buffer');
+ assert$3(buffer, 'Could not create buffer');
return buffer;
}
async title() {
@@ -44309,7 +44311,7 @@ class CDPPage extends Page$1 {
}
async close(options = { runBeforeUnload: undefined }) {
const connection = __classPrivateFieldGet$c(this, _CDPPage_client, "f").connection();
- assert$5(connection, 'Protocol error: Connection closed. Most likely the page has been closed.');
+ assert$3(connection, 'Protocol error: Connection closed. Most likely the page has been closed.');
const runBeforeUnload = !!options.runBeforeUnload;
if (runBeforeUnload) {
await __classPrivateFieldGet$c(this, _CDPPage_client, "f").send('Page.close');
@@ -44405,7 +44407,7 @@ _CDPPage_closed = new WeakMap(), _CDPPage_client = new WeakMap(), _CDPPage_targe
return;
}
const frame = __classPrivateFieldGet$c(this, _CDPPage_frameManager, "f").frame(event.frameId);
- assert$5(frame, 'This should never happen.');
+ assert$3(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$2(handle, event);
@@ -44526,7 +44528,7 @@ _CDPPage_closed = new WeakMap(), _CDPPage_client = new WeakMap(), _CDPPage_targe
if (validDialogTypes.has(event.type)) {
dialogType = event.type;
}
- assert$5(dialogType, 'Unknown javascript dialog type: ' + event.type);
+ assert$3(dialogType, 'Unknown javascript dialog type: ' + event.type);
const dialog = new Dialog$1(__classPrivateFieldGet$c(this, _CDPPage_client, "f"), dialogType, event.message, event.defaultPrompt);
this.emit("dialog" /* PageEmittedEvents.Dialog */, dialog);
}, _CDPPage_resetDefaultBackgroundColor =
@@ -44937,7 +44939,7 @@ var _ChromeTargetManager_instances, _ChromeTargetManager_connection, _ChromeTarg
*
* @internal
*/
-class ChromeTargetManager extends EventEmitter$6 {
+class ChromeTargetManager extends EventEmitter$4 {
constructor(connection, targetFactory, targetFilterCallback) {
super();
_ChromeTargetManager_instances.add(this);
@@ -45097,7 +45099,7 @@ class ChromeTargetManager extends EventEmitter$6 {
if (!(parentSession instanceof Connection)) {
// Sanity check: if parent session is not a connection, it should be
// present in #attachedTargetsBySessionId.
- assert$5(__classPrivateFieldGet$a(this, _ChromeTargetManager_attachedTargetsBySessionId, "f").has(parentSession.id()));
+ assert$3(__classPrivateFieldGet$a(this, _ChromeTargetManager_attachedTargetsBySessionId, "f").has(parentSession.id()));
}
interceptor(target, parentSession instanceof Connection
? null
@@ -45179,13 +45181,13 @@ _ChromeTargetManager_connection = new WeakMap(), _ChromeTargetManager_discovered
const listener = (event) => {
return __classPrivateFieldGet$a(this, _ChromeTargetManager_onAttachedToTarget, "f").call(this, session, event);
};
- assert$5(!__classPrivateFieldGet$a(this, _ChromeTargetManager_attachedToTargetListenersBySession, "f").has(session));
+ assert$3(!__classPrivateFieldGet$a(this, _ChromeTargetManager_attachedToTargetListenersBySession, "f").has(session));
__classPrivateFieldGet$a(this, _ChromeTargetManager_attachedToTargetListenersBySession, "f").set(session, listener);
session.on('Target.attachedToTarget', listener);
const detachedListener = (event) => {
return __classPrivateFieldGet$a(this, _ChromeTargetManager_onDetachedFromTarget, "f").call(this, session, event);
};
- assert$5(!__classPrivateFieldGet$a(this, _ChromeTargetManager_detachedFromTargetListenersBySession, "f").has(session));
+ assert$3(!__classPrivateFieldGet$a(this, _ChromeTargetManager_detachedFromTargetListenersBySession, "f").has(session));
__classPrivateFieldGet$a(this, _ChromeTargetManager_detachedFromTargetListenersBySession, "f").set(session, detachedListener);
session.on('Target.detachedFromTarget', detachedListener);
}, _ChromeTargetManager_removeAttachmentListeners = function _ChromeTargetManager_removeAttachmentListeners(session) {
@@ -45245,7 +45247,7 @@ var _FirefoxTargetManager_instances, _FirefoxTargetManager_connection, _FirefoxT
* - https://bugzilla.mozilla.org/show_bug.cgi?id=1636979
* @internal
*/
-class FirefoxTargetManager extends EventEmitter$6 {
+class FirefoxTargetManager extends EventEmitter$4 {
constructor(connection, targetFactory, targetFilterCallback) {
super();
_FirefoxTargetManager_instances.add(this);
@@ -45326,12 +45328,12 @@ class FirefoxTargetManager extends EventEmitter$6 {
throw new Error(`Session ${event.sessionId} was not created.`);
}
const target = __classPrivateFieldGet$9(this, _FirefoxTargetManager_availableTargetsByTargetId, "f").get(targetInfo.targetId);
- assert$5(target, `Target ${targetInfo.targetId} is missing`);
+ assert$3(target, `Target ${targetInfo.targetId} is missing`);
this.setupAttachmentListeners(session);
__classPrivateFieldGet$9(this, _FirefoxTargetManager_availableTargetsBySessionId, "f").set(session.id(), __classPrivateFieldGet$9(this, _FirefoxTargetManager_availableTargetsByTargetId, "f").get(targetInfo.targetId));
for (const hook of __classPrivateFieldGet$9(this, _FirefoxTargetManager_targetInterceptors, "f").get(parentSession) || []) {
if (!(parentSession instanceof Connection)) {
- assert$5(__classPrivateFieldGet$9(this, _FirefoxTargetManager_availableTargetsBySessionId, "f").has(parentSession.id()));
+ assert$3(__classPrivateFieldGet$9(this, _FirefoxTargetManager_availableTargetsBySessionId, "f").has(parentSession.id()));
}
await hook(target, parentSession instanceof Connection
? null
@@ -45361,7 +45363,7 @@ class FirefoxTargetManager extends EventEmitter$6 {
const listener = (event) => {
return __classPrivateFieldGet$9(this, _FirefoxTargetManager_onAttachedToTarget, "f").call(this, session, event);
};
- assert$5(!__classPrivateFieldGet$9(this, _FirefoxTargetManager_attachedToTargetListenersBySession, "f").has(session));
+ assert$3(!__classPrivateFieldGet$9(this, _FirefoxTargetManager_attachedToTargetListenersBySession, "f").has(session));
__classPrivateFieldGet$9(this, _FirefoxTargetManager_attachedToTargetListenersBySession, "f").set(session, listener);
session.on('Target.attachedToTarget', listener);
}
@@ -45985,7 +45987,7 @@ class CDPBrowserContext extends BrowserContext$1 {
* Only incognito browser contexts can be closed.
*/
async close() {
- assert$5(__classPrivateFieldGet$7(this, _CDPBrowserContext_id, "f"), 'Non-incognito profiles cannot be closed!');
+ assert$3(__classPrivateFieldGet$7(this, _CDPBrowserContext_id, "f"), 'Non-incognito profiles cannot be closed!');
await __classPrivateFieldGet$7(this, _CDPBrowserContext_browser, "f")._disposeContext(__classPrivateFieldGet$7(this, _CDPBrowserContext_id, "f"));
}
}
@@ -46044,7 +46046,7 @@ const getWebSocketTransportClass = async () => {
*/
async function _connectToCDPBrowser(options) {
const { browserWSEndpoint, browserURL, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, transport, headers = {}, slowMo = 0, targetFilter, _isPageTarget: isPageTarget, protocolTimeout, } = options;
- assert$5(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) ===
+ assert$3(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) ===
1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
let connection;
if (transport) {
@@ -50018,7 +50020,7 @@ var extension = { format: format$1, parse: parse$1 };
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Readable$" }] */
-const EventEmitter$5 = require$$0$5;
+const EventEmitter$3 = require$$0$5;
const https$6 = require$$1$2;
const http$5 = require$$0$6;
const net$6 = require$$0$a;
@@ -50056,7 +50058,7 @@ const subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
*
* @extends EventEmitter
*/
-let WebSocket$1 = class WebSocket extends EventEmitter$5 {
+let WebSocket$1 = class WebSocket extends EventEmitter$3 {
/**
* Create a new `WebSocket`.
*
@@ -54229,14 +54231,14 @@ var __importStar$4 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__i
__setModuleDefault$4(result, mod);
return result;
};
-var __importDefault$a = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$9 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(dist$8, "__esModule", { value: true });
dist$8.HttpProxyAgent = void 0;
const net$5 = __importStar$4(require$$0$a);
const tls$4 = __importStar$4(require$$1$1);
-const debug_1$8 = __importDefault$a(srcExports);
+const debug_1$8 = __importDefault$9(srcExports);
const events_1$1 = require$$0$5;
const agent_base_1$3 = dist$a;
const debug$c = (0, debug_1$8.default)('http-proxy-agent');
@@ -54356,12 +54358,12 @@ var dist$7 = {};
var parseProxyResponse$1 = {};
-var __importDefault$9 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$8 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(parseProxyResponse$1, "__esModule", { value: true });
parseProxyResponse$1.parseProxyResponse = void 0;
-const debug_1$7 = __importDefault$9(srcExports);
+const debug_1$7 = __importDefault$8(srcExports);
const debug$b = (0, debug_1$7.default)('https-proxy-agent:parse-proxy-response');
function parseProxyResponse(socket) {
return new Promise((resolve, reject) => {
@@ -54476,15 +54478,15 @@ var __importStar$3 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__i
__setModuleDefault$3(result, mod);
return result;
};
-var __importDefault$8 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$7 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(dist$7, "__esModule", { value: true });
dist$7.HttpsProxyAgent = void 0;
const net$4 = __importStar$3(require$$0$a);
const tls$3 = __importStar$3(require$$1$1);
-const assert_1 = __importDefault$8(require$$0$7);
-const debug_1$6 = __importDefault$8(srcExports);
+const assert_1 = __importDefault$7(require$$0$7);
+const debug_1$6 = __importDefault$7(srcExports);
const agent_base_1$2 = dist$a;
const parse_proxy_response_1 = parseProxyResponse$1;
const debug$a = (0, debug_1$6.default)('https-proxy-agent');
@@ -57550,14 +57552,14 @@ var __importStar$2 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__i
__setModuleDefault$2(result, mod);
return result;
};
-var __importDefault$7 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$6 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(dist$6, "__esModule", { value: true });
dist$6.SocksProxyAgent = void 0;
const socks_1 = build$5;
const agent_base_1$1 = dist$a;
-const debug_1$5 = __importDefault$7(srcExports);
+const debug_1$5 = __importDefault$6(srcExports);
const dns$1 = __importStar$2(require$$0$h);
const net$3 = __importStar$2(require$$0$a);
const tls$2 = __importStar$2(require$$1$1);
@@ -57787,16 +57789,16 @@ class NotModifiedError extends Error {
}
notmodified.default = NotModifiedError;
-var __importDefault$6 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$5 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(data$1, "__esModule", { value: true });
data$1.data = void 0;
-const debug_1$4 = __importDefault$6(srcExports);
+const debug_1$4 = __importDefault$5(srcExports);
const stream_1$3 = require$$0$9;
const crypto_1 = require$$5;
-const data_uri_to_buffer_1 = __importDefault$6(dist$4);
-const notmodified_1$2 = __importDefault$6(notmodified);
+const data_uri_to_buffer_1 = __importDefault$5(dist$4);
+const notmodified_1$2 = __importDefault$5(notmodified);
const debug$8 = (0, debug_1$4.default)('get-uri:data');
class DataReadable extends stream_1$3.Readable {
constructor(hash, buf) {
@@ -59320,14 +59322,14 @@ var stat$4 = {
isSrcSubdir
};
-var buffer$1;
+var buffer;
var hasRequiredBuffer;
function requireBuffer () {
- if (hasRequiredBuffer) return buffer$1;
+ if (hasRequiredBuffer) return buffer;
hasRequiredBuffer = 1;
/* eslint-disable node/no-deprecated-api */
- buffer$1 = function (size) {
+ buffer = function (size) {
if (typeof Buffer.allocUnsafe === 'function') {
try {
return Buffer.allocUnsafe(size)
@@ -59337,7 +59339,7 @@ function requireBuffer () {
}
return new Buffer(size)
};
- return buffer$1;
+ return buffer;
}
const fs$o = gracefulFs;
@@ -59737,7 +59739,7 @@ var copy$1 = {
const fs$l = gracefulFs;
const path$f = require$$1$3;
-const assert$4 = require$$0$7;
+const assert$2 = require$$0$7;
const isWindows = (process.platform === 'win32');
@@ -59767,11 +59769,11 @@ function rimraf$1 (p, options, cb) {
options = {};
}
- assert$4(p, 'rimraf: missing path');
- assert$4.strictEqual(typeof p, 'string', 'rimraf: path should be a string');
- assert$4.strictEqual(typeof cb, 'function', 'rimraf: callback function required');
- assert$4(options, 'rimraf: invalid options argument provided');
- assert$4.strictEqual(typeof options, 'object', 'rimraf: options should be object');
+ assert$2(p, 'rimraf: missing path');
+ assert$2.strictEqual(typeof p, 'string', 'rimraf: path should be a string');
+ assert$2.strictEqual(typeof cb, 'function', 'rimraf: callback function required');
+ assert$2(options, 'rimraf: invalid options argument provided');
+ assert$2.strictEqual(typeof options, 'object', 'rimraf: options should be object');
defaults$1(options);
@@ -59805,9 +59807,9 @@ function rimraf$1 (p, options, cb) {
// If anyone ever complains about this, then I guess the strategy could
// be made configurable somehow. But until then, YAGNI.
function rimraf_ (p, options, cb) {
- assert$4(p);
- assert$4(options);
- assert$4(typeof cb === 'function');
+ assert$2(p);
+ assert$2(options);
+ assert$2(typeof cb === 'function');
// sunos lets the root user unlink directories, which is... weird.
// so we have to lstat here and make sure it's not a dir.
@@ -59845,11 +59847,11 @@ function rimraf_ (p, options, cb) {
}
function fixWinEPERM (p, options, er, cb) {
- assert$4(p);
- assert$4(options);
- assert$4(typeof cb === 'function');
+ assert$2(p);
+ assert$2(options);
+ assert$2(typeof cb === 'function');
if (er) {
- assert$4(er instanceof Error);
+ assert$2(er instanceof Error);
}
options.chmod(p, 0o666, er2 => {
@@ -59872,10 +59874,10 @@ function fixWinEPERM (p, options, er, cb) {
function fixWinEPERMSync (p, options, er) {
let stats;
- assert$4(p);
- assert$4(options);
+ assert$2(p);
+ assert$2(options);
if (er) {
- assert$4(er instanceof Error);
+ assert$2(er instanceof Error);
}
try {
@@ -59906,12 +59908,12 @@ function fixWinEPERMSync (p, options, er) {
}
function rmdir (p, options, originalEr, cb) {
- assert$4(p);
- assert$4(options);
+ assert$2(p);
+ assert$2(options);
if (originalEr) {
- assert$4(originalEr instanceof Error);
+ assert$2(originalEr instanceof Error);
}
- assert$4(typeof cb === 'function');
+ assert$2(typeof cb === 'function');
// try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
// if we guessed wrong, and it's not a directory, then
@@ -59928,9 +59930,9 @@ function rmdir (p, options, originalEr, cb) {
}
function rmkids (p, options, cb) {
- assert$4(p);
- assert$4(options);
- assert$4(typeof cb === 'function');
+ assert$2(p);
+ assert$2(options);
+ assert$2(typeof cb === 'function');
options.readdir(p, (er, files) => {
if (er) return cb(er)
@@ -59963,10 +59965,10 @@ function rimrafSync (p, options) {
options = options || {};
defaults$1(options);
- assert$4(p, 'rimraf: missing path');
- assert$4.strictEqual(typeof p, 'string', 'rimraf: path should be a string');
- assert$4(options, 'rimraf: missing options');
- assert$4.strictEqual(typeof options, 'object', 'rimraf: options should be object');
+ assert$2(p, 'rimraf: missing path');
+ assert$2.strictEqual(typeof p, 'string', 'rimraf: path should be a string');
+ assert$2(options, 'rimraf: missing options');
+ assert$2.strictEqual(typeof options, 'object', 'rimraf: options should be object');
try {
st = options.lstatSync(p);
@@ -60001,10 +60003,10 @@ function rimrafSync (p, options) {
}
function rmdirSync (p, options, originalEr) {
- assert$4(p);
- assert$4(options);
+ assert$2(p);
+ assert$2(options);
if (originalEr) {
- assert$4(originalEr instanceof Error);
+ assert$2(originalEr instanceof Error);
}
try {
@@ -60021,8 +60023,8 @@ function rmdirSync (p, options, originalEr) {
}
function rmkidsSync (p, options) {
- assert$4(p);
- assert$4(options);
+ assert$2(p);
+ assert$2(options);
options.readdirSync(p).forEach(f => rimrafSync(path$f.join(p, f), options));
if (isWindows) {
@@ -60834,16 +60836,16 @@ class NotFoundError extends Error {
}
notfound.default = NotFoundError;
-var __importDefault$5 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$4 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(file$3, "__esModule", { value: true });
file$3.file = void 0;
-const debug_1$3 = __importDefault$5(srcExports);
+const debug_1$3 = __importDefault$4(srcExports);
const fs_1$1 = require$$0$4;
const fs_extra_1 = libExports;
-const notfound_1$1 = __importDefault$5(notfound);
-const notmodified_1$1 = __importDefault$5(notmodified);
+const notfound_1$1 = __importDefault$4(notfound);
+const notmodified_1$1 = __importDefault$4(notmodified);
const url_1$1 = require$$6$1;
const debug$6 = (0, debug_1$3.default)('get-uri:file');
/**
@@ -63176,7 +63178,7 @@ Object.defineProperty(StringEncoding, "__esModule", { value: true });
Object.defineProperty(exports, "enterPassiveModeIPv6", { enumerable: true, get: function () { return transfer_1.enterPassiveModeIPv6; } });
} (dist$3));
-var __importDefault$4 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$3 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(ftp$1, "__esModule", { value: true });
@@ -63184,9 +63186,9 @@ ftp$1.ftp = void 0;
const basic_ftp_1 = dist$3;
const stream_1 = require$$0$9;
const path_1 = require$$1$3;
-const debug_1$2 = __importDefault$4(srcExports);
-const notfound_1 = __importDefault$4(notfound);
-const notmodified_1 = __importDefault$4(notmodified);
+const debug_1$2 = __importDefault$3(srcExports);
+const notfound_1 = __importDefault$3(notfound);
+const notmodified_1 = __importDefault$3(notmodified);
const debug$5 = (0, debug_1$2.default)('get-uri:ftp');
/**
* Returns a Readable stream from an "ftp:" URI.
@@ -63478,12 +63480,12 @@ httpError.default = HTTPError;
var https$4 = {};
-var __importDefault$3 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$2 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(https$4, "__esModule", { value: true });
https$4.https = void 0;
-const https_1 = __importDefault$3(require$$1$2);
+const https_1 = __importDefault$2(require$$1$2);
const http_1 = http$3;
/**
* Returns a Readable stream from an "https:" URI.
@@ -83028,12 +83030,12 @@ var ip = {};
};
} (ip));
-var __importDefault$2 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault$1 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(myIpAddress$1, "__esModule", { value: true });
-const ip_1 = __importDefault$2(ip);
-const net_1 = __importDefault$2(require$$0$a);
+const ip_1 = __importDefault$1(ip);
+const net_1 = __importDefault$1(require$$0$a);
/**
* Returns the IP address of the host that the Navigator is running on, as
* a string in the dot-separated integer format.
@@ -83415,7 +83417,7 @@ var __importStar = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__imp
__setModuleDefault(result, mod);
return result;
};
-var __importDefault$1 = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
+var __importDefault = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(dist$9, "__esModule", { value: true });
@@ -83424,7 +83426,7 @@ const net$2 = __importStar(require$$0$a);
const tls$1 = __importStar(require$$1$1);
const crypto$1 = __importStar(require$$5);
const events_1 = require$$0$5;
-const debug_1$1 = __importDefault$1(srcExports);
+const debug_1$1 = __importDefault(srcExports);
const url_1 = require$$6$1;
const agent_base_1 = dist$a;
const http_proxy_agent_1 = dist$8;
@@ -85367,17 +85369,17 @@ var Readable$1 = stream$3.Readable;
var Writable$4 = stream$3.Writable;
var PassThrough$2 = stream$3.PassThrough;
var Pend = pend;
-var EventEmitter$4 = require$$0$5.EventEmitter;
+var EventEmitter$2 = require$$0$5.EventEmitter;
fdSlicer.createFromBuffer = createFromBuffer;
fdSlicer.createFromFd = createFromFd;
fdSlicer.BufferSlicer = BufferSlicer;
fdSlicer.FdSlicer = FdSlicer;
-util$6.inherits(FdSlicer, EventEmitter$4);
+util$6.inherits(FdSlicer, EventEmitter$2);
function FdSlicer(fd, options) {
options = options || {};
- EventEmitter$4.call(this);
+ EventEmitter$2.call(this);
this.fd = fd;
this.pend = new Pend();
@@ -85545,9 +85547,9 @@ WriteStream.prototype.destroy = function() {
this.context.unref();
};
-util$6.inherits(BufferSlicer, EventEmitter$4);
+util$6.inherits(BufferSlicer, EventEmitter$2);
function BufferSlicer(buffer, options) {
- EventEmitter$4.call(this);
+ EventEmitter$2.call(this);
options = options || {};
this.refCount = 0;
@@ -85657,7 +85659,7 @@ function createFromFd(fd, options) {
return new FdSlicer(fd, options);
}
-var Buffer$3 = require$$0$b.Buffer;
+var Buffer$2 = require$$0$b.Buffer;
var CRC_TABLE = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
@@ -85719,19 +85721,19 @@ if (typeof Int32Array !== 'undefined') {
}
function ensureBuffer(input) {
- if (Buffer$3.isBuffer(input)) {
+ if (Buffer$2.isBuffer(input)) {
return input;
}
var hasNewBufferAPI =
- typeof Buffer$3.alloc === "function" &&
- typeof Buffer$3.from === "function";
+ typeof Buffer$2.alloc === "function" &&
+ typeof Buffer$2.from === "function";
if (typeof input === "number") {
- return hasNewBufferAPI ? Buffer$3.alloc(input) : new Buffer$3(input);
+ return hasNewBufferAPI ? Buffer$2.alloc(input) : new Buffer$2(input);
}
else if (typeof input === "string") {
- return hasNewBufferAPI ? Buffer$3.from(input) : new Buffer$3(input);
+ return hasNewBufferAPI ? Buffer$2.from(input) : new Buffer$2(input);
}
else {
throw new Error("input must be buffer, number, or string, received " +
@@ -85747,7 +85749,7 @@ function bufferizeInt(num) {
function _crc32(buf, previous) {
buf = ensureBuffer(buf);
- if (Buffer$3.isBuffer(previous)) {
+ if (Buffer$2.isBuffer(previous)) {
previous = previous.readUInt32BE(0);
}
var crc = ~~previous ^ -1;
@@ -85774,7 +85776,7 @@ var zlib = zlib$2;
var fd_slicer = fdSlicer;
var crc32 = bufferCrc32;
var util$5 = require$$1;
-var EventEmitter$3 = require$$0$5.EventEmitter;
+var EventEmitter$1 = require$$0$5.EventEmitter;
var Transform = require$$0$9.Transform;
var PassThrough$1 = require$$0$9.PassThrough;
var Writable$3 = require$$0$9.Writable;
@@ -85959,10 +85961,10 @@ function fromRandomAccessReader(reader, totalSize, options, callback) {
});
}
-util$5.inherits(ZipFile$1, EventEmitter$3);
+util$5.inherits(ZipFile$1, EventEmitter$1);
function ZipFile$1(reader, centralDirectoryOffset, fileSize, entryCount, comment, autoClose, lazyEntries, decodeStrings, validateEntrySizes, strictFileNames) {
var self = this;
- EventEmitter$3.call(self);
+ EventEmitter$1.call(self);
self.reader = reader;
// forward close events
self.reader.on("error", function(err) {
@@ -86425,9 +86427,9 @@ AssertByteCountStream.prototype._flush = function(cb) {
cb();
};
-util$5.inherits(RandomAccessReader, EventEmitter$3);
+util$5.inherits(RandomAccessReader, EventEmitter$1);
function RandomAccessReader() {
- EventEmitter$3.call(this);
+ EventEmitter$1.call(this);
this.refCount = 0;
}
RandomAccessReader.prototype.ref = function() {
@@ -89973,7 +89975,7 @@ function requirePipeline () {
var readableExports = readable.exports;
-const { Buffer: Buffer$2 } = require$$0$b;
+const { Buffer: Buffer$1 } = require$$0$b;
const symbol = Symbol.for('BufferList');
function BufferList$1 (buf) {
@@ -90058,11 +90060,11 @@ BufferList$1.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
}
if (srcStart >= this.length) {
- return dst || Buffer$2.alloc(0)
+ return dst || Buffer$1.alloc(0)
}
if (srcEnd <= 0) {
- return dst || Buffer$2.alloc(0)
+ return dst || Buffer$1.alloc(0)
}
const copy = !!dst;
@@ -90078,7 +90080,7 @@ BufferList$1.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
// slice, but full concat if multiple buffers
return this._bufs.length === 1
? this._bufs[0]
- : Buffer$2.concat(this._bufs, this.length)
+ : Buffer$1.concat(this._bufs, this.length)
}
// copy, need to copy individual buffers
@@ -90099,7 +90101,7 @@ BufferList$1.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) {
if (!copy) {
// a slice, we need something to copy in to
- dst = Buffer$2.allocUnsafe(len);
+ dst = Buffer$1.allocUnsafe(len);
}
for (let i = off[0]; i < this._bufs.length; i++) {
@@ -90202,7 +90204,7 @@ BufferList$1.prototype.append = function append (buf) {
if (buf.buffer) {
// append a view of the underlying ArrayBuffer
- this._appendBuffer(Buffer$2.from(buf.buffer, buf.byteOffset, buf.byteLength));
+ this._appendBuffer(Buffer$1.from(buf.buffer, buf.byteOffset, buf.byteLength));
} else if (Array.isArray(buf)) {
for (let i = 0; i < buf.length; i++) {
this.append(buf[i]);
@@ -90219,7 +90221,7 @@ BufferList$1.prototype.append = function append (buf) {
buf = buf.toString();
}
- this._appendBuffer(Buffer$2.from(buf));
+ this._appendBuffer(Buffer$1.from(buf));
}
return this
@@ -90239,15 +90241,15 @@ BufferList$1.prototype.indexOf = function (search, offset, encoding) {
if (typeof search === 'function' || Array.isArray(search)) {
throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.')
} else if (typeof search === 'number') {
- search = Buffer$2.from([search]);
+ search = Buffer$1.from([search]);
} else if (typeof search === 'string') {
- search = Buffer$2.from(search, encoding);
+ search = Buffer$1.from(search, encoding);
} else if (this._isBufferList(search)) {
search = search.slice();
} else if (Array.isArray(search.buffer)) {
- search = Buffer$2.from(search.buffer, search.byteOffset, search.byteLength);
- } else if (!Buffer$2.isBuffer(search)) {
- search = Buffer$2.from(search);
+ search = Buffer$1.from(search.buffer, search.byteOffset, search.byteLength);
+ } else if (!Buffer$1.isBuffer(search)) {
+ search = Buffer$1.from(search);
}
offset = Number(offset || 0);
@@ -97547,7 +97549,7 @@ let PipeTransport$2 = class PipeTransport {
], "f");
}
send(message) {
- assert$5(!__classPrivateFieldGet$2(this, _PipeTransport_isClosed, "f"), '`PipeTransport` is closed.');
+ assert$3(!__classPrivateFieldGet$2(this, _PipeTransport_isClosed, "f"), '`PipeTransport` is closed.');
__classPrivateFieldGet$2(this, _PipeTransport_pipeWrite, "f").write(message);
__classPrivateFieldGet$2(this, _PipeTransport_pipeWrite, "f").write('\0');
}
@@ -97557,7 +97559,7 @@ let PipeTransport$2 = class PipeTransport {
}
};
_PipeTransport_pipeWrite = new WeakMap(), _PipeTransport_eventListeners = new WeakMap(), _PipeTransport_isClosed = new WeakMap(), _PipeTransport_pendingMessage = new WeakMap(), _PipeTransport_instances = new WeakSet(), _PipeTransport_dispatch = function _PipeTransport_dispatch(buffer) {
- assert$5(!__classPrivateFieldGet$2(this, _PipeTransport_isClosed, "f"), '`PipeTransport` is closed.');
+ assert$3(!__classPrivateFieldGet$2(this, _PipeTransport_isClosed, "f"), '`PipeTransport` is closed.');
let end = buffer.indexOf('\0');
if (end === -1) {
__classPrivateFieldSet$2(this, _PipeTransport_pendingMessage, __classPrivateFieldGet$2(this, _PipeTransport_pendingMessage, "f") + buffer.toString(), "f");
@@ -97930,7 +97932,7 @@ class ChromeLauncher extends ProductLauncher {
return argument.startsWith('--remote-debugging-');
})) {
if (pipe) {
- assert$5(!debuggingPort, 'Browser should be launched with either pipe or debugging port - not both.');
+ assert$3(!debuggingPort, 'Browser should be launched with either pipe or debugging port - not both.');
chromeArguments.push('--remote-debugging-pipe');
}
else {
@@ -97949,10 +97951,10 @@ class ChromeLauncher extends ProductLauncher {
userDataDirIndex = chromeArguments.length - 1;
}
const userDataDir = chromeArguments[userDataDirIndex].split('=', 2)[1];
- assert$5(typeof userDataDir === 'string', '`--user-data-dir` is malformed');
+ assert$3(typeof userDataDir === 'string', '`--user-data-dir` is malformed');
let chromeExecutable = executablePath;
if (!chromeExecutable) {
- assert$5(channel || !this.puppeteer._isPuppeteerCore, `An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``);
+ assert$3(channel || !this.puppeteer._isPuppeteerCore, `An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``);
chromeExecutable = this.executablePath(channel);
}
return {
@@ -98097,7 +98099,7 @@ class FirefoxLauncher extends ProductLauncher {
return argument.startsWith('--remote-debugging-');
})) {
if (pipe) {
- assert$5(debuggingPort === null, 'Browser should be launched with either pipe or debugging port - not both.');
+ assert$3(debuggingPort === null, 'Browser should be launched with either pipe or debugging port - not both.');
}
firefoxArguments.push(`--remote-debugging-port=${debuggingPort || 0}`);
}
@@ -98128,7 +98130,7 @@ class FirefoxLauncher extends ProductLauncher {
});
let firefoxExecutable;
if (this.puppeteer._isPuppeteerCore || executablePath) {
- assert$5(executablePath, `An \`executablePath\` must be specified for \`puppeteer-core\``);
+ assert$3(executablePath, `An \`executablePath\` must be specified for \`puppeteer-core\``);
firefoxExecutable = executablePath;
}
else {
@@ -106473,7 +106475,7 @@ const puppeteer = new PuppeteerNode({
configuration,
});
-const deferred$1 = () => {
+const deferred = () => {
let state = 'pending';
let resolve;
let reject;
@@ -106509,7 +106511,7 @@ const CONST = {
};
function lazyRun(callback, timeout = CONST.LAZY_RUN_DEFAULT) {
- const p = deferred$1();
+ const p = deferred();
setTimeout(() => {
callback()
.then(() => p.resolve())
@@ -106582,7 +106584,7 @@ class PuppeteerPage {
}
wait(param) {
return __awaiter$5(this, void 0, void 0, function* () {
- const p = deferred$1();
+ const p = deferred();
if (param === 'idle') {
yield this.page.waitForNavigation({ waitUntil: 'networkidle0' });
p.resolve();
@@ -106688,7 +106690,7 @@ var __awaiter$4 = (undefined && undefined.__awaiter) || function (thisArg, _argu
class PuppeteerController {
constructor(configs, logger) {
this.getBrowser = () => __awaiter$4(this, void 0, void 0, function* () {
- const p = deferred$1();
+ const p = deferred();
if (this.browser) {
p.resolve(this.browser);
}
@@ -107406,7 +107408,7 @@ function getPackageManagerExecCommand() {
Object.defineProperty(debug$3, "__esModule", {
value: true
});
-debug$3.assert = assert$3;
+debug$3.assert = assert$1;
debug$3.debugAssert = debugAssert;
debug$3.debugMode = debugMode;
debug$3.isUnderTest = isUnderTest;
@@ -107428,7 +107430,7 @@ var _env = env;
* limitations under the License.
*/
-function assert$3(value, message) {
+function assert$1(value, message) {
if (!value) throw new Error(message || 'Assertion error');
}
function debugAssert(value, message) {
@@ -149041,5671 +149043,6 @@ function requireBidiBrowser () {
var bidiOverCdp = {};
-var bidiMapper = {};
-
-var BidiServer$1 = {};
-
-var EventEmitter$2 = {};
-
-var mitt=function(n){return {all:n=n||new Map,on:function(e,t){var i=n.get(e);i?i.push(t):n.set(e,[t]);},off:function(e,t){var i=n.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):n.set(e,[]));},emit:function(e,t){var i=n.get(e);i&&i.slice().map(function(n){n(t);}),(i=n.get("*"))&&i.slice().map(function(n){n(e,t);});}}};
-
-var __importDefault = (vm2_bridge.commonjsGlobal && vm2_bridge.commonjsGlobal.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(EventEmitter$2, "__esModule", { value: true });
-EventEmitter$2.EventEmitter = void 0;
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-const mitt_1 = __importDefault(mitt);
-let EventEmitter$1 = class EventEmitter {
- #emitter = (0, mitt_1.default)();
- on(type, handler) {
- this.#emitter.on(type, handler);
- return this;
- }
- /**
- * Like `on` but the listener will only be fired once and then it will be removed.
- * @param event The event you'd like to listen to
- * @param handler The handler function to run when the event occurs
- * @return `this` to enable chaining method calls.
- */
- once(event, handler) {
- const onceHandler = (eventData) => {
- handler(eventData);
- this.off(event, onceHandler);
- };
- return this.on(event, onceHandler);
- }
- off(type, handler) {
- this.#emitter.off(type, handler);
- return this;
- }
- /**
- * Emits an event and call any associated listeners.
- *
- * @param event The event to emit.
- * @param eventData Any data to emit with the event.
- * @return `true` if there are any listeners, `false` otherwise.
- */
- emit(event, eventData) {
- this.#emitter.emit(event, eventData);
- }
-};
-EventEmitter$2.EventEmitter = EventEmitter$1;
-
-var log = {};
-
-(function (exports) {
- /**
- * Copyright 2021 Google LLC.
- * 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.
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.LogType = void 0;
- (function (LogType) {
- // keep-sorted start
- LogType["bidi"] = "BiDi Messages";
- LogType["browsingContexts"] = "Browsing Contexts";
- LogType["cdp"] = "CDP";
- LogType["system"] = "System";
- // keep-sorted end
- })(exports.LogType || (exports.LogType = {}));
-
-} (log));
-
-var processingQueue = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(processingQueue, "__esModule", { value: true });
-processingQueue.ProcessingQueue = void 0;
-const log_js_1$6 = log;
-class ProcessingQueue {
- #logger;
- #processor;
- #queue = [];
- // Flag to keep only 1 active processor.
- #isProcessing = false;
- constructor(processor, logger) {
- this.#processor = processor;
- this.#logger = logger;
- }
- add(entry) {
- this.#queue.push(entry);
- // No need in waiting. Just initialise processor if needed.
- void this.#processIfNeeded();
- }
- async #processIfNeeded() {
- if (this.#isProcessing) {
- return;
- }
- this.#isProcessing = true;
- while (this.#queue.length > 0) {
- const entryPromise = this.#queue.shift();
- if (entryPromise !== undefined) {
- await entryPromise
- .then((entry) => this.#processor(entry))
- .catch((e) => {
- this.#logger?.(log_js_1$6.LogType.system, 'Event was not processed:', e);
- });
- }
- }
- this.#isProcessing = false;
- }
-}
-processingQueue.ProcessingQueue = ProcessingQueue;
-
-var CommandProcessor$1 = {};
-
-var protocol = {};
-
-(function (exports) {
- /**
- * Copyright 2022 Google LLC.
- * 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.
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.Input = exports.CDP = exports.Network = exports.Log = exports.BrowsingContext = exports.Script = exports.Message = void 0;
- (function (Message) {
- // keep-sorted end;
- let ErrorCode;
- (function (ErrorCode) {
- // keep-sorted start
- ErrorCode["InvalidArgument"] = "invalid argument";
- ErrorCode["InvalidSessionId"] = "invalid session id";
- ErrorCode["MoveTargetOutOfBounds"] = "move target out of bounds";
- ErrorCode["NoSuchAlert"] = "no such alert";
- ErrorCode["NoSuchFrame"] = "no such frame";
- ErrorCode["NoSuchHandle"] = "no such handle";
- ErrorCode["NoSuchNode"] = "no such node";
- ErrorCode["NoSuchScript"] = "no such script";
- ErrorCode["SessionNotCreated"] = "session not created";
- ErrorCode["UnknownCommand"] = "unknown command";
- ErrorCode["UnknownError"] = "unknown error";
- ErrorCode["UnsupportedOperation"] = "unsupported operation";
- // keep-sorted end
- })(ErrorCode = Message.ErrorCode || (Message.ErrorCode = {}));
- class ErrorResponse {
- error;
- message;
- stacktrace;
- constructor(error, message, stacktrace) {
- this.error = error;
- this.message = message;
- this.stacktrace = stacktrace;
- }
- toErrorResponse(commandId) {
- return {
- id: commandId,
- error: this.error,
- message: this.message,
- stacktrace: this.stacktrace,
- };
- }
- }
- Message.ErrorResponse = ErrorResponse;
- class InvalidArgumentException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.InvalidArgument, message, stacktrace);
- }
- }
- Message.InvalidArgumentException = InvalidArgumentException;
- class MoveTargetOutOfBoundsException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.MoveTargetOutOfBounds, message, stacktrace);
- }
- }
- Message.MoveTargetOutOfBoundsException = MoveTargetOutOfBoundsException;
- class NoSuchHandleException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.NoSuchHandle, message, stacktrace);
- }
- }
- Message.NoSuchHandleException = NoSuchHandleException;
- class InvalidSessionIdException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.InvalidSessionId, message, stacktrace);
- }
- }
- Message.InvalidSessionIdException = InvalidSessionIdException;
- class NoSuchAlertException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.NoSuchAlert, message, stacktrace);
- }
- }
- Message.NoSuchAlertException = NoSuchAlertException;
- class NoSuchFrameException extends ErrorResponse {
- constructor(message) {
- super(ErrorCode.NoSuchFrame, message);
- }
- }
- Message.NoSuchFrameException = NoSuchFrameException;
- class NoSuchNodeException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.NoSuchNode, message, stacktrace);
- }
- }
- Message.NoSuchNodeException = NoSuchNodeException;
- class NoSuchScriptException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.NoSuchScript, message, stacktrace);
- }
- }
- Message.NoSuchScriptException = NoSuchScriptException;
- class SessionNotCreatedException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.SessionNotCreated, message, stacktrace);
- }
- }
- Message.SessionNotCreatedException = SessionNotCreatedException;
- class UnknownCommandException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.UnknownCommand, message, stacktrace);
- }
- }
- Message.UnknownCommandException = UnknownCommandException;
- class UnknownErrorException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.UnknownError, message, stacktrace);
- }
- }
- Message.UnknownErrorException = UnknownErrorException;
- class UnsupportedOperationException extends ErrorResponse {
- constructor(message, stacktrace) {
- super(ErrorCode.UnsupportedOperation, message, stacktrace);
- }
- }
- Message.UnsupportedOperationException = UnsupportedOperationException;
- })(exports.Message || (exports.Message = {}));
- (function (Script) {
- (function (EventNames) {
- EventNames["MessageEvent"] = "script.message";
- })(Script.EventNames || (Script.EventNames = {}));
- Script.AllEvents = 'script';
- })(exports.Script || (exports.Script = {}));
- (function (BrowsingContext) {
- (function (EventNames) {
- EventNames["LoadEvent"] = "browsingContext.load";
- EventNames["DomContentLoadedEvent"] = "browsingContext.domContentLoaded";
- EventNames["ContextCreatedEvent"] = "browsingContext.contextCreated";
- EventNames["ContextDestroyedEvent"] = "browsingContext.contextDestroyed";
- })(BrowsingContext.EventNames || (BrowsingContext.EventNames = {}));
- BrowsingContext.AllEvents = 'browsingContext';
- })(exports.BrowsingContext || (exports.BrowsingContext = {}));
- (function (Log) {
- Log.AllEvents = 'log';
- (function (EventNames) {
- EventNames["LogEntryAddedEvent"] = "log.entryAdded";
- })(Log.EventNames || (Log.EventNames = {}));
- })(exports.Log || (exports.Log = {}));
- (function (Network) {
- Network.AllEvents = 'network';
- (function (EventNames) {
- EventNames["BeforeRequestSentEvent"] = "network.beforeRequestSent";
- EventNames["FetchErrorEvent"] = "network.fetchError";
- EventNames["ResponseStartedEvent"] = "network.responseStarted";
- EventNames["ResponseCompletedEvent"] = "network.responseCompleted";
- })(Network.EventNames || (Network.EventNames = {}));
- })(exports.Network || (exports.Network = {}));
- (function (CDP) {
- CDP.AllEvents = 'cdp';
- (function (EventNames) {
- EventNames["EventReceivedEvent"] = "cdp.eventReceived";
- })(CDP.EventNames || (CDP.EventNames = {}));
- })(exports.CDP || (exports.CDP = {}));
- (function (Input) {
- (function (SourceActionsType) {
- SourceActionsType["None"] = "none";
- SourceActionsType["Key"] = "key";
- SourceActionsType["Pointer"] = "pointer";
- SourceActionsType["Wheel"] = "wheel";
- })(Input.SourceActionsType || (Input.SourceActionsType = {}));
- (function (PointerType) {
- PointerType["Mouse"] = "mouse";
- PointerType["Pen"] = "pen";
- PointerType["Touch"] = "touch";
- })(Input.PointerType || (Input.PointerType = {}));
- (function (ActionType) {
- ActionType["Pause"] = "pause";
- ActionType["KeyDown"] = "keyDown";
- ActionType["KeyUp"] = "keyUp";
- ActionType["PointerUp"] = "pointerUp";
- ActionType["PointerDown"] = "pointerDown";
- ActionType["PointerMove"] = "pointerMove";
- ActionType["Scroll"] = "scroll";
- })(Input.ActionType || (Input.ActionType = {}));
- })(exports.Input || (exports.Input = {}));
-
-} (protocol));
-
-var browsingContextProcessor = {};
-
-var InputStateManager$1 = {};
-
-var assert$2 = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(assert$2, "__esModule", { value: true });
-assert$2.assert = void 0;
-function assert$1(predicate) {
- if (!predicate) {
- throw new Error('Internal assertion failed.');
- }
-}
-assert$2.assert = assert$1;
-
-var InputState$1 = {};
-
-var Mutex$1 = {};
-
-/**
- * Copyright 2023 Google LLC.
- * Copyright (c) Microsoft Corporation.
- * Copyright 2022 The Chromium Authors.
- *
- * 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.
- */
-Object.defineProperty(Mutex$1, "__esModule", { value: true });
-Mutex$1.Mutex = void 0;
-/**
- * Use Mutex class to coordinate local concurrent operations.
- * Once `acquire` promise resolves, you hold the lock and must
- * call `release` function returned by `acquire` to release the
- * lock. Failing to `release` the lock may lead to deadlocks.
- */
-class Mutex {
- #locked = false;
- #acquirers = [];
- // This is FIFO.
- acquire() {
- const state = { resolved: false };
- if (this.#locked) {
- return new Promise((resolve) => {
- this.#acquirers.push(() => resolve(this.#release.bind(this, state)));
- });
- }
- this.#locked = true;
- return Promise.resolve(this.#release.bind(this, state));
- }
- #release(state) {
- if (state.resolved) {
- throw new Error('Cannot release more than once.');
- }
- state.resolved = true;
- const resolve = this.#acquirers.shift();
- if (!resolve) {
- this.#locked = false;
- return;
- }
- resolve();
- }
- async run(action) {
- const release = await this.acquire();
- try {
- // Note we need to await here because we want the await to release AFTER
- // that await happens. Returning action() will trigger the release
- // immediately which is counter to what we want.
- const result = await action();
- return result;
- }
- finally {
- release();
- }
- }
-}
-Mutex$1.Mutex = Mutex;
-
-var InputSource = {};
-
-(function (exports) {
- /**
- * Copyright 2023 Google LLC.
- * 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.
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.WheelSource = exports.PointerSource = exports.KeySource = exports.NoneSource = exports.SourceType = void 0;
- const protocol_js_1 = protocol;
- exports.SourceType = protocol_js_1.Input.SourceActionsType;
- class NoneSource {
- type = exports.SourceType.None;
- }
- exports.NoneSource = NoneSource;
- class KeySource {
- type = exports.SourceType.Key;
- pressed = new Set();
- // This is a bitfield that matches the modifiers parameter of
- // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent
- #modifiers = 0;
- get modifiers() {
- return this.#modifiers;
- }
- get alt() {
- return (this.#modifiers & 1) === 1;
- }
- set alt(value) {
- this.#setModifier(value, 1);
- }
- get ctrl() {
- return (this.#modifiers & 2) === 2;
- }
- set ctrl(value) {
- this.#setModifier(value, 2);
- }
- get meta() {
- return (this.#modifiers & 4) === 4;
- }
- set meta(value) {
- this.#setModifier(value, 4);
- }
- get shift() {
- return (this.#modifiers & 8) === 8;
- }
- set shift(value) {
- this.#setModifier(value, 8);
- }
- #setModifier(value, bit) {
- if (value) {
- this.#modifiers |= bit;
- }
- else {
- this.#modifiers ^= bit;
- }
- }
- }
- exports.KeySource = KeySource;
- class PointerSource {
- type = exports.SourceType.Pointer;
- subtype;
- pointerId;
- pressed = new Set();
- x = 0;
- y = 0;
- constructor(id, subtype) {
- this.pointerId = id;
- this.subtype = subtype;
- }
- // This is a bitfield that matches the buttons parameter of
- // https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchMouseEvent
- get buttons() {
- let buttons = 0;
- for (const button of this.pressed) {
- switch (button) {
- case 0:
- buttons |= 1;
- break;
- case 1:
- buttons |= 4;
- break;
- case 2:
- buttons |= 2;
- break;
- case 3:
- buttons |= 8;
- break;
- case 4:
- buttons |= 16;
- break;
- }
- }
- return buttons;
- }
- // --- Platform-specific state starts here ---
- // Input.dispatchMouseEvent doesn't know the concept of double click, so we
- // need to create it like for OSes:
- // https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/events/event.cc;l=479
- static #DOUBLE_CLICK_TIME_MS = 500;
- static #MAX_DOUBLE_CLICK_RADIUS = 2;
- #clickCount = 0;
- #lastClick;
- setClickCount(context) {
- if (!this.#lastClick ||
- // The click needs to be within a certain amount of ms.
- context.timeStamp - this.#lastClick.timeStamp >
- PointerSource.#DOUBLE_CLICK_TIME_MS ||
- // The click needs to be within a square radius.
- Math.abs(this.#lastClick.x - context.x) >
- PointerSource.#MAX_DOUBLE_CLICK_RADIUS ||
- Math.abs(this.#lastClick.y - context.y) >
- PointerSource.#MAX_DOUBLE_CLICK_RADIUS) {
- this.#clickCount = 0;
- }
- ++this.#clickCount;
- this.#lastClick = context;
- }
- get clickCount() {
- return this.#clickCount;
- }
- }
- exports.PointerSource = PointerSource;
- class WheelSource {
- type = exports.SourceType.Wheel;
- }
- exports.WheelSource = WheelSource;
-
-} (InputSource));
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(InputState$1, "__esModule", { value: true });
-InputState$1.InputState = void 0;
-const protocol_js_1$b = protocol;
-const Mutex_js_1 = Mutex$1;
-const InputSource_js_1 = InputSource;
-class InputState {
- cancelList = [];
- #sources = new Map();
- #mutex = new Mutex_js_1.Mutex();
- getOrCreate(id, type, subtype) {
- let source = this.#sources.get(id);
- if (!source) {
- switch (type) {
- case InputSource_js_1.SourceType.None:
- source = new InputSource_js_1.NoneSource();
- break;
- case InputSource_js_1.SourceType.Key:
- source = new InputSource_js_1.KeySource();
- break;
- case InputSource_js_1.SourceType.Pointer: {
- let pointerId = subtype === protocol_js_1$b.Input.PointerType.Mouse ? 0 : 2;
- const pointerIds = new Set();
- for (const [, source] of this.#sources) {
- if (source.type === InputSource_js_1.SourceType.Pointer) {
- pointerIds.add(source.pointerId);
- }
- }
- while (pointerIds.has(pointerId)) {
- ++pointerId;
- }
- source = new InputSource_js_1.PointerSource(pointerId, subtype);
- break;
- }
- case InputSource_js_1.SourceType.Wheel:
- source = new InputSource_js_1.WheelSource();
- break;
- default:
- throw new protocol_js_1$b.Message.InvalidArgumentException(`Expected "${InputSource_js_1.SourceType.None}", "${InputSource_js_1.SourceType.Key}", "${InputSource_js_1.SourceType.Pointer}", or "${InputSource_js_1.SourceType.Wheel}". Found unknown source type ${type}.`);
- }
- this.#sources.set(id, source);
- return source;
- }
- if (source.type !== type) {
- throw new protocol_js_1$b.Message.InvalidArgumentException(`Input source type of ${id} is ${source.type}, but received ${type}.`);
- }
- return source;
- }
- get(id) {
- const source = this.#sources.get(id);
- if (!source) {
- throw new protocol_js_1$b.Message.UnknownErrorException(`Internal error.`);
- }
- return source;
- }
- getGlobalKeyState() {
- const state = new InputSource_js_1.KeySource();
- for (const [, source] of this.#sources) {
- if (source.type !== InputSource_js_1.SourceType.Key) {
- continue;
- }
- for (const pressed of source.pressed) {
- state.pressed.add(pressed);
- }
- state.alt ||= source.alt;
- state.ctrl ||= source.ctrl;
- state.meta ||= source.meta;
- state.shift ||= source.shift;
- }
- return state;
- }
- get queue() {
- return this.#mutex;
- }
-}
-InputState$1.InputState = InputState;
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(InputStateManager$1, "__esModule", { value: true });
-InputStateManager$1.InputStateManager = void 0;
-const assert_js_1$1 = assert$2;
-const InputState_js_1 = InputState$1;
-class InputStateManager {
- // We use a weak map here as specified here:
- // https://www.w3.org/TR/webdriver/#dfn-browsing-context-input-state-map
- #states = new WeakMap();
- get(context) {
- (0, assert_js_1$1.assert)(context.isTopLevelContext());
- let state = this.#states.get(context);
- if (!state) {
- state = new InputState_js_1.InputState();
- this.#states.set(context, state);
- }
- return state;
- }
- delete(context) {
- this.#states.delete(context);
- }
-}
-InputStateManager$1.InputStateManager = InputStateManager;
-
-var ActionDispatcher$1 = {};
-
-var USKeyboardLayout = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(USKeyboardLayout, "__esModule", { value: true });
-USKeyboardLayout.KeyToKeyCode = void 0;
-// TODO: Remove this once https://crrev.com/c/4548290 is stably in Chromium.
-// `Input.dispatchKeyboardEvent` will automatically handle these conversions.
-USKeyboardLayout.KeyToKeyCode = {
- '0': 48,
- '1': 49,
- '2': 50,
- '3': 51,
- '4': 52,
- '5': 53,
- '6': 54,
- '7': 55,
- '8': 56,
- '9': 57,
- Abort: 3,
- Help: 6,
- Backspace: 8,
- Tab: 9,
- Numpad5: 12,
- NumpadEnter: 13,
- Enter: 13,
- '\\r': 13,
- '\\n': 13,
- ShiftLeft: 16,
- ShiftRight: 16,
- ControlLeft: 17,
- ControlRight: 17,
- AltLeft: 18,
- AltRight: 18,
- Pause: 19,
- CapsLock: 20,
- Escape: 27,
- Convert: 28,
- NonConvert: 29,
- Space: 32,
- Numpad9: 33,
- PageUp: 33,
- Numpad3: 34,
- PageDown: 34,
- End: 35,
- Numpad1: 35,
- Home: 36,
- Numpad7: 36,
- ArrowLeft: 37,
- Numpad4: 37,
- Numpad8: 38,
- ArrowUp: 38,
- ArrowRight: 39,
- Numpad6: 39,
- Numpad2: 40,
- ArrowDown: 40,
- Select: 41,
- Open: 43,
- PrintScreen: 44,
- Insert: 45,
- Numpad0: 45,
- Delete: 46,
- NumpadDecimal: 46,
- Digit0: 48,
- Digit1: 49,
- Digit2: 50,
- Digit3: 51,
- Digit4: 52,
- Digit5: 53,
- Digit6: 54,
- Digit7: 55,
- Digit8: 56,
- Digit9: 57,
- KeyA: 65,
- KeyB: 66,
- KeyC: 67,
- KeyD: 68,
- KeyE: 69,
- KeyF: 70,
- KeyG: 71,
- KeyH: 72,
- KeyI: 73,
- KeyJ: 74,
- KeyK: 75,
- KeyL: 76,
- KeyM: 77,
- KeyN: 78,
- KeyO: 79,
- KeyP: 80,
- KeyQ: 81,
- KeyR: 82,
- KeyS: 83,
- KeyT: 84,
- KeyU: 85,
- KeyV: 86,
- KeyW: 87,
- KeyX: 88,
- KeyY: 89,
- KeyZ: 90,
- MetaLeft: 91,
- MetaRight: 92,
- ContextMenu: 93,
- NumpadMultiply: 106,
- NumpadAdd: 107,
- NumpadSubtract: 109,
- NumpadDivide: 111,
- F1: 112,
- F2: 113,
- F3: 114,
- F4: 115,
- F5: 116,
- F6: 117,
- F7: 118,
- F8: 119,
- F9: 120,
- F10: 121,
- F11: 122,
- F12: 123,
- F13: 124,
- F14: 125,
- F15: 126,
- F16: 127,
- F17: 128,
- F18: 129,
- F19: 130,
- F20: 131,
- F21: 132,
- F22: 133,
- F23: 134,
- F24: 135,
- NumLock: 144,
- ScrollLock: 145,
- AudioVolumeMute: 173,
- AudioVolumeDown: 174,
- AudioVolumeUp: 175,
- MediaTrackNext: 176,
- MediaTrackPrevious: 177,
- MediaStop: 178,
- MediaPlayPause: 179,
- Semicolon: 186,
- Equal: 187,
- NumpadEqual: 187,
- Comma: 188,
- Minus: 189,
- Period: 190,
- Slash: 191,
- Backquote: 192,
- BracketLeft: 219,
- Backslash: 220,
- BracketRight: 221,
- Quote: 222,
- AltGraph: 225,
- Props: 247,
- Cancel: 3,
- Clear: 12,
- Shift: 16,
- Control: 17,
- Alt: 18,
- Accept: 30,
- ModeChange: 31,
- ' ': 32,
- Print: 42,
- Execute: 43,
- '\\u0000': 46,
- a: 65,
- b: 66,
- c: 67,
- d: 68,
- e: 69,
- f: 70,
- g: 71,
- h: 72,
- i: 73,
- j: 74,
- k: 75,
- l: 76,
- m: 77,
- n: 78,
- o: 79,
- p: 80,
- q: 81,
- r: 82,
- s: 83,
- t: 84,
- u: 85,
- v: 86,
- w: 87,
- x: 88,
- y: 89,
- z: 90,
- Meta: 91,
- '*': 106,
- '+': 107,
- '-': 109,
- '/': 111,
- ';': 186,
- '=': 187,
- ',': 188,
- '.': 190,
- '`': 192,
- '[': 219,
- '\\\\': 220,
- ']': 221,
- "'": 222,
- Attn: 246,
- CrSel: 247,
- ExSel: 248,
- EraseEof: 249,
- Play: 250,
- ZoomOut: 251,
- ')': 48,
- '!': 49,
- '@': 50,
- '#': 51,
- $: 52,
- '%': 53,
- '^': 54,
- '&': 55,
- '(': 57,
- A: 65,
- B: 66,
- C: 67,
- D: 68,
- E: 69,
- F: 70,
- G: 71,
- H: 72,
- I: 73,
- J: 74,
- K: 75,
- L: 76,
- M: 77,
- N: 78,
- O: 79,
- P: 80,
- Q: 81,
- R: 82,
- S: 83,
- T: 84,
- U: 85,
- V: 86,
- W: 87,
- X: 88,
- Y: 89,
- Z: 90,
- ':': 186,
- '<': 188,
- _: 189,
- '>': 190,
- '?': 191,
- '~': 192,
- '{': 219,
- '|': 220,
- '}': 221,
- '"': 222,
- Camera: 44,
- EndCall: 95,
- VolumeDown: 182,
- VolumeUp: 183,
-};
-
-var keyUtils = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(keyUtils, "__esModule", { value: true });
-keyUtils.getKeyLocation = keyUtils.getKeyCode = keyUtils.getNormalizedKey = void 0;
-function getNormalizedKey(value) {
- switch (value) {
- case '\uE000':
- return 'Unidentified';
- case '\uE001':
- return 'Cancel';
- case '\uE002':
- return 'Help';
- case '\uE003':
- return 'Backspace';
- case '\uE004':
- return 'Tab';
- case '\uE005':
- return 'Clear';
- case '\uE006':
- return 'Return';
- case '\uE007':
- return 'Enter';
- case '\uE008':
- return 'Shift';
- case '\uE009':
- return 'Control';
- case '\uE00A':
- return 'Alt';
- case '\uE00B':
- return 'Pause';
- case '\uE00C':
- return 'Escape';
- case '\uE00D':
- return ' ';
- case '\uE00E':
- return 'PageUp';
- case '\uE00F':
- return 'PageDown';
- case '\uE010':
- return 'End';
- case '\uE011':
- return 'Home';
- case '\uE012':
- return 'ArrowLeft';
- case '\uE013':
- return 'ArrowUp';
- case '\uE014':
- return 'ArrowRight';
- case '\uE015':
- return 'ArrowDown';
- case '\uE016':
- return 'Insert';
- case '\uE017':
- return 'Delete';
- case '\uE018':
- return ';';
- case '\uE019':
- return '=';
- case '\uE01A':
- return '0';
- case '\uE01B':
- return '1';
- case '\uE01C':
- return '2';
- case '\uE01D':
- return '3';
- case '\uE01E':
- return '4';
- case '\uE01F':
- return '5';
- case '\uE020':
- return '6';
- case '\uE021':
- return '7';
- case '\uE022':
- return '8';
- case '\uE023':
- return '9';
- case '\uE024':
- return '*';
- case '\uE025':
- return '+';
- case '\uE026':
- return ',';
- case '\uE027':
- return '-';
- case '\uE028':
- return '.';
- case '\uE029':
- return '/';
- case '\uE031':
- return 'F1';
- case '\uE032':
- return 'F2';
- case '\uE033':
- return 'F3';
- case '\uE034':
- return 'F4';
- case '\uE035':
- return 'F5';
- case '\uE036':
- return 'F6';
- case '\uE037':
- return 'F7';
- case '\uE038':
- return 'F8';
- case '\uE039':
- return 'F9';
- case '\uE03A':
- return 'F10';
- case '\uE03B':
- return 'F11';
- case '\uE03C':
- return 'F12';
- case '\uE03D':
- return 'Meta';
- case '\uE040':
- return 'ZenkakuHankaku';
- case '\uE050':
- return 'Shift';
- case '\uE051':
- return 'Control';
- case '\uE052':
- return 'Alt';
- case '\uE053':
- return 'Meta';
- case '\uE054':
- return 'PageUp';
- case '\uE055':
- return 'PageDown';
- case '\uE056':
- return 'End';
- case '\uE057':
- return 'Home';
- case '\uE058':
- return 'ArrowLeft';
- case '\uE059':
- return 'ArrowUp';
- case '\uE05A':
- return 'ArrowRight';
- case '\uE05B':
- return 'ArrowDown';
- case '\uE05C':
- return 'Insert';
- case '\uE05D':
- return 'Delete';
- default:
- return value;
- }
-}
-keyUtils.getNormalizedKey = getNormalizedKey;
-function getKeyCode(key) {
- switch (key) {
- case '`':
- case '~':
- return 'Backquote';
- case '\\':
- case '|':
- return 'Backslash';
- case '\uE003':
- return 'Backspace';
- case '[':
- case '{':
- return 'BracketLeft';
- case ']':
- case '}':
- return 'BracketRight';
- case ',':
- case '<':
- return 'Comma';
- case '0':
- case ')':
- return 'Digit0';
- case '1':
- case '!':
- return 'Digit1';
- case '2':
- case '@':
- return 'Digit2';
- case '3':
- case '#':
- return 'Digit3';
- case '4':
- case '$':
- return 'Digit4';
- case '5':
- case '%':
- return 'Digit5';
- case '6':
- case '^':
- return 'Digit6';
- case '7':
- case '&':
- return 'Digit7';
- case '8':
- case '*':
- return 'Digit8';
- case '9':
- case '(':
- return 'Digit9';
- case '=':
- case '+':
- return 'Equal';
- case 'a':
- case 'A':
- return 'KeyA';
- case 'b':
- case 'B':
- return 'KeyB';
- case 'c':
- case 'C':
- return 'KeyC';
- case 'd':
- case 'D':
- return 'KeyD';
- case 'e':
- case 'E':
- return 'KeyE';
- case 'f':
- case 'F':
- return 'KeyF';
- case 'g':
- case 'G':
- return 'KeyG';
- case 'h':
- case 'H':
- return 'KeyH';
- case 'i':
- case 'I':
- return 'KeyI';
- case 'j':
- case 'J':
- return 'KeyJ';
- case 'k':
- case 'K':
- return 'KeyK';
- case 'l':
- case 'L':
- return 'KeyL';
- case 'm':
- case 'M':
- return 'KeyM';
- case 'n':
- case 'N':
- return 'KeyN';
- case 'o':
- case 'O':
- return 'KeyO';
- case 'p':
- case 'P':
- return 'KeyP';
- case 'q':
- case 'Q':
- return 'KeyQ';
- case 'r':
- case 'R':
- return 'KeyR';
- case 's':
- case 'S':
- return 'KeyS';
- case 't':
- case 'T':
- return 'KeyT';
- case 'u':
- case 'U':
- return 'KeyU';
- case 'v':
- case 'V':
- return 'KeyV';
- case 'w':
- case 'W':
- return 'KeyW';
- case 'x':
- case 'X':
- return 'KeyX';
- case 'y':
- case 'Y':
- return 'KeyY';
- case 'z':
- case 'Z':
- return 'KeyZ';
- case '-':
- case '_':
- return 'Minus';
- case '.':
- return 'Period';
- case "'":
- case '"':
- return 'Quote';
- case ';':
- case ':':
- return 'Semicolon';
- case '/':
- case '?':
- return 'Slash';
- case '\uE00A':
- return 'AltLeft';
- case '\uE052':
- return 'AltRight';
- case '\uE009':
- return 'ControlLeft';
- case '\uE051':
- return 'ControlRight';
- case '\uE006':
- return 'Enter';
- case '\uE03D':
- return 'MetaLeft';
- case '\uE053':
- return 'MetaRight';
- case '\uE008':
- return 'ShiftLeft';
- case '\uE050':
- return 'ShiftRight';
- case ' ':
- case '\uE00D':
- return 'Space';
- case '\uE004':
- return 'Tab';
- case '\uE017':
- return 'Delete';
- case '\uE010':
- return 'End';
- case '\uE002':
- return 'Help';
- case '\uE011':
- return 'Home';
- case '\uE016':
- return 'Insert';
- case '\uE00F':
- return 'PageDown';
- case '\uE00E':
- return 'PageUp';
- case '\uE015':
- return 'ArrowDown';
- case '\uE012':
- return 'ArrowLeft';
- case '\uE014':
- return 'ArrowRight';
- case '\uE013':
- return 'ArrowUp';
- case '\uE00C':
- return 'Escape';
- case '\uE031':
- return 'F1';
- case '\uE032':
- return 'F2';
- case '\uE033':
- return 'F3';
- case '\uE034':
- return 'F4';
- case '\uE035':
- return 'F5';
- case '\uE036':
- return 'F6';
- case '\uE037':
- return 'F7';
- case '\uE038':
- return 'F8';
- case '\uE039':
- return 'F9';
- case '\uE03A':
- return 'F10';
- case '\uE03B':
- return 'F11';
- case '\uE03C':
- return 'F12';
- case '\uE01A':
- case '\uE05C':
- return 'Numpad0';
- case '\uE01B':
- case '\uE056':
- return 'Numpad1';
- case '\uE01C':
- case '\uE05B':
- return 'Numpad2';
- case '\uE01D':
- case '\uE055':
- return 'Numpad3';
- case '\uE01E':
- case '\uE058':
- return 'Numpad4';
- case '\uE01F':
- return 'Numpad5';
- case '\uE020':
- case '\uE05A':
- return 'Numpad6';
- case '\uE021':
- case '\uE057':
- return 'Numpad7';
- case '\uE022':
- case '\uE059':
- return 'Numpad8';
- case '\uE023':
- case '\uE054':
- return 'Numpad9';
- case '\uE025':
- return 'NumpadAdd';
- case '\uE026':
- return 'NumpadComma';
- case '\uE028':
- case '\uE05D':
- return 'NumpadDecimal';
- case '\uE029':
- return 'NumpadDivide';
- case '\uE007':
- return 'NumpadEnter';
- case '\uE024':
- return 'NumpadMultiply';
- case '\uE027':
- return 'NumpadSubtract';
- default:
- return;
- }
-}
-keyUtils.getKeyCode = getKeyCode;
-function getKeyLocation(key) {
- switch (key) {
- case '\uE007':
- case '\uE008':
- case '\uE009':
- case '\uE00A':
- case '\uE03D':
- return 1;
- case '\uE01A':
- case '\uE01B':
- case '\uE01C':
- case '\uE01D':
- case '\uE01E':
- case '\uE01F':
- case '\uE020':
- case '\uE021':
- case '\uE022':
- case '\uE023':
- case '\uE024':
- case '\uE025':
- case '\uE026':
- case '\uE027':
- case '\uE028':
- case '\uE029':
- case '\uE054':
- case '\uE055':
- case '\uE056':
- case '\uE057':
- case '\uE058':
- case '\uE059':
- case '\uE05A':
- case '\uE05B':
- case '\uE05C':
- case '\uE05D':
- return 3;
- case '\uE050':
- case '\uE051':
- case '\uE052':
- case '\uE053':
- return 2;
- default:
- return 0;
- }
-}
-keyUtils.getKeyLocation = getKeyLocation;
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(ActionDispatcher$1, "__esModule", { value: true });
-ActionDispatcher$1.ActionDispatcher = void 0;
-const protocol_js_1$a = protocol;
-const assert_js_1 = assert$2;
-const USKeyboardLayout_js_1 = USKeyboardLayout;
-const keyUtils_js_1 = keyUtils;
-/** https://w3c.github.io/webdriver/#dfn-center-point */
-const CALCULATE_IN_VIEW_CENTER_PT_DECL = ((i) => {
- const t = i.getClientRects()[0], e = Math.max(0, Math.min(t.x, t.x + t.width)), n = Math.min(window.innerWidth, Math.max(t.x, t.x + t.width)), h = Math.max(0, Math.min(t.y, t.y + t.height)), m = Math.min(window.innerHeight, Math.max(t.y, t.y + t.height));
- return [e + ((n - e) >> 1), h + ((m - h) >> 1)];
-}).toString();
-async function getElementCenter(context, element) {
- const { result } = await (await context.getOrCreateSandbox(undefined)).callFunction(CALCULATE_IN_VIEW_CENTER_PT_DECL, { type: 'undefined' }, [element], false, 'none', {});
- if (result.type === 'exception') {
- throw new protocol_js_1$a.Message.NoSuchNodeException(`Origin element ${element.sharedId} was not found`);
- }
- (0, assert_js_1.assert)(result.result.type === 'array');
- (0, assert_js_1.assert)(result.result.value?.[0]?.type === 'number');
- (0, assert_js_1.assert)(result.result.value?.[1]?.type === 'number');
- const { result: { value: [{ value: x }, { value: y }], }, } = result;
- return { x: x, y: y };
-}
-class ActionDispatcher {
- #tickStart = 0;
- #tickDuration = 0;
- #inputState;
- #context;
- constructor(inputState, context) {
- this.#inputState = inputState;
- this.#context = context;
- }
- async dispatchActions(optionsByTick) {
- await this.#inputState.queue.run(async () => {
- for (const options of optionsByTick) {
- await this.dispatchTickActions(options);
- }
- });
- }
- async dispatchTickActions(options) {
- this.#tickStart = performance.now();
- this.#tickDuration = 0;
- for (const { action } of options) {
- if ('duration' in action && action.duration !== undefined) {
- this.#tickDuration = Math.max(this.#tickDuration, action.duration);
- }
- }
- const promises = [
- new Promise((resolve) => setTimeout(resolve, this.#tickDuration)),
- ];
- for (const option of options) {
- promises.push(this.#dispatchAction(option));
- }
- await Promise.all(promises);
- }
- async #dispatchAction({ id, action }) {
- const source = this.#inputState.get(id);
- const keyState = this.#inputState.getGlobalKeyState();
- switch (action.type) {
- case protocol_js_1$a.Input.ActionType.KeyDown: {
- // SAFETY: The source is validated before.
- await this.#dispatchKeyDownAction(source, action);
- this.#inputState.cancelList.push({
- id,
- action: {
- ...action,
- type: protocol_js_1$a.Input.ActionType.KeyUp,
- },
- });
- break;
- }
- case protocol_js_1$a.Input.ActionType.KeyUp: {
- // SAFETY: The source is validated before.
- await this.#dispatchKeyUpAction(source, action);
- break;
- }
- case protocol_js_1$a.Input.ActionType.Pause: {
- // TODO: Implement waiting on the input source.
- break;
- }
- case protocol_js_1$a.Input.ActionType.PointerDown: {
- // SAFETY: The source is validated before.
- await this.#dispatchPointerDownAction(source, keyState, action);
- this.#inputState.cancelList.push({
- id,
- action: {
- ...action,
- type: protocol_js_1$a.Input.ActionType.PointerUp,
- },
- });
- break;
- }
- case protocol_js_1$a.Input.ActionType.PointerMove: {
- // SAFETY: The source is validated before.
- await this.#dispatchPointerMoveAction(source, keyState, action);
- break;
- }
- case protocol_js_1$a.Input.ActionType.PointerUp: {
- // SAFETY: The source is validated before.
- await this.#dispatchPointerUpAction(source, keyState, action);
- break;
- }
- case protocol_js_1$a.Input.ActionType.Scroll: {
- // SAFETY: The source is validated before.
- await this.#dispatchScrollAction(source, keyState, action);
- break;
- }
- }
- }
- #dispatchPointerDownAction(source, keyState, action) {
- const { button } = action;
- if (source.pressed.has(button)) {
- return;
- }
- source.pressed.add(button);
- const { x, y, subtype: pointerType } = source;
- const { width, height, pressure, twist, tangentialPressure } = action;
- const { tiltX, tiltY } = 'tiltX' in action ? action : {};
- // TODO: Implement azimuth/altitude angle.
- // --- Platform-specific code begins here ---
- const { modifiers } = keyState;
- switch (pointerType) {
- case protocol_js_1$a.Input.PointerType.Mouse:
- case protocol_js_1$a.Input.PointerType.Pen:
- source.setClickCount({ x, y, timeStamp: performance.now() });
- // TODO: Implement width and height when available.
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
- type: 'mousePressed',
- x,
- y,
- modifiers,
- button: (() => {
- switch (button) {
- case 0:
- return 'left';
- case 1:
- return 'middle';
- case 2:
- return 'right';
- case 3:
- return 'back';
- case 4:
- return 'forward';
- default:
- return 'none';
- }
- })(),
- buttons: source.buttons,
- clickCount: source.clickCount,
- pointerType,
- tangentialPressure,
- tiltX,
- tiltY,
- twist,
- force: pressure,
- });
- case protocol_js_1$a.Input.PointerType.Touch:
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
- type: 'touchStart',
- touchPoints: [
- {
- x,
- y,
- radiusX: width,
- radiusY: height,
- tangentialPressure,
- tiltX,
- tiltY,
- twist,
- force: pressure,
- id: source.pointerId,
- },
- ],
- modifiers,
- });
- }
- // --- Platform-specific code ends here ---
- }
- #dispatchPointerUpAction(source, keyState, action) {
- const { button } = action;
- if (!source.pressed.has(button)) {
- return;
- }
- source.pressed.delete(button);
- const { x, y, subtype: pointerType } = source;
- // --- Platform-specific code begins here ---
- const { modifiers } = keyState;
- switch (pointerType) {
- case protocol_js_1$a.Input.PointerType.Mouse:
- case protocol_js_1$a.Input.PointerType.Pen:
- // TODO: Implement width and height when available.
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
- type: 'mouseReleased',
- x,
- y,
- modifiers,
- button: (() => {
- switch (button) {
- case 0:
- return 'left';
- case 1:
- return 'middle';
- case 2:
- return 'right';
- case 3:
- return 'back';
- case 4:
- return 'forward';
- default:
- return 'none';
- }
- })(),
- buttons: source.buttons,
- clickCount: source.clickCount,
- pointerType,
- });
- case protocol_js_1$a.Input.PointerType.Touch:
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
- type: 'touchEnd',
- touchPoints: [
- {
- x,
- y,
- id: source.pointerId,
- },
- ],
- modifiers,
- });
- }
- // --- Platform-specific code ends here ---
- }
- async #dispatchPointerMoveAction(source, keyState, action) {
- const { x: startX, y: startY, subtype: pointerType } = source;
- const { width, height, pressure, twist, tangentialPressure, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
- const { tiltX, tiltY } = 'tiltX' in action ? action : {};
- // TODO: Implement azimuth/altitude angle.
- const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY);
- if (targetX < 0 || targetY < 0) {
- throw new protocol_js_1$a.Message.MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
- }
- let last;
- do {
- const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
- last = ratio >= 1;
- let x;
- let y;
- if (last) {
- x = targetX;
- y = targetY;
- }
- else {
- x = Math.round(ratio * (targetX - startX) + startX);
- y = Math.round(ratio * (targetY - startY) + startY);
- }
- if (source.x !== x || source.y !== y) {
- // --- Platform-specific code begins here ---
- const { modifiers } = keyState;
- switch (pointerType) {
- case protocol_js_1$a.Input.PointerType.Mouse:
- case protocol_js_1$a.Input.PointerType.Pen:
- // TODO: Implement width and height when available.
- await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
- type: 'mouseMoved',
- x,
- y,
- modifiers,
- clickCount: 0,
- buttons: source.buttons,
- pointerType,
- tangentialPressure,
- tiltX,
- tiltY,
- twist,
- force: pressure,
- });
- break;
- case protocol_js_1$a.Input.PointerType.Touch:
- await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchTouchEvent', {
- type: 'touchMove',
- touchPoints: [
- {
- x,
- y,
- radiusX: width,
- radiusY: height,
- tangentialPressure,
- tiltX,
- tiltY,
- twist,
- force: pressure,
- id: source.pointerId,
- },
- ],
- modifiers,
- });
- break;
- }
- // --- Platform-specific code ends here ---
- source.x = x;
- source.y = y;
- }
- } while (!last);
- }
- async #getCoordinateFromOrigin(origin, offsetX, offsetY, startX, startY) {
- let targetX;
- let targetY;
- switch (origin) {
- case 'viewport':
- targetX = offsetX;
- targetY = offsetY;
- break;
- case 'pointer':
- targetX = startX + offsetX;
- targetY = startY + offsetY;
- break;
- default: {
- const { x: posX, y: posY } = await getElementCenter(this.#context, origin.element);
- // SAFETY: These can never be special numbers.
- targetX = posX + offsetX;
- targetY = posY + offsetY;
- break;
- }
- }
- return { targetX, targetY };
- }
- async #dispatchScrollAction(_source, keyState, action) {
- const { deltaX: targetDeltaX, deltaY: targetDeltaY, x: offsetX, y: offsetY, origin = 'viewport', duration = this.#tickDuration, } = action;
- if (origin === 'pointer') {
- throw new protocol_js_1$a.Message.InvalidArgumentException('"pointer" origin is invalid for scrolling.');
- }
- const { targetX, targetY } = await this.#getCoordinateFromOrigin(origin, offsetX, offsetY, 0, 0);
- if (targetX < 0 || targetY < 0) {
- throw new protocol_js_1$a.Message.MoveTargetOutOfBoundsException(`Cannot move beyond viewport (x: ${targetX}, y: ${targetY})`);
- }
- let currentDeltaX = 0;
- let currentDeltaY = 0;
- let last;
- do {
- const ratio = duration > 0 ? (performance.now() - this.#tickStart) / duration : 1;
- last = ratio >= 1;
- let deltaX;
- let deltaY;
- if (last) {
- deltaX = targetDeltaX - currentDeltaX;
- deltaY = targetDeltaY - currentDeltaY;
- }
- else {
- deltaX = Math.round(ratio * targetDeltaX - currentDeltaX);
- deltaY = Math.round(ratio * targetDeltaY - currentDeltaY);
- }
- if (deltaX !== 0 || deltaY !== 0) {
- // --- Platform-specific code begins here ---
- const { modifiers } = keyState;
- await this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchMouseEvent', {
- type: 'mouseWheel',
- deltaX,
- deltaY,
- x: targetX,
- y: targetY,
- modifiers,
- });
- // --- Platform-specific code ends here ---
- currentDeltaX += deltaX;
- currentDeltaY += deltaY;
- }
- } while (!last);
- }
- #dispatchKeyDownAction(source, action) {
- const rawKey = action.value;
- const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);
- const repeat = source.pressed.has(key);
- const code = (0, keyUtils_js_1.getKeyCode)(rawKey);
- const location = (0, keyUtils_js_1.getKeyLocation)(rawKey);
- switch (key) {
- case 'Alt':
- source.alt = true;
- break;
- case 'Shift':
- source.shift = true;
- break;
- case 'Control':
- source.ctrl = true;
- break;
- case 'Meta':
- source.meta = true;
- break;
- }
- source.pressed.add(key);
- const { modifiers } = source;
- // --- Platform-specific code begins here ---
- // The spread is a little hack so JS gives us an array of unicode characters
- // to measure.
- const text = [...key].length === 1 ? key : undefined;
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
- type: text ? 'keyDown' : 'rawKeyDown',
- windowsVirtualKeyCode: USKeyboardLayout_js_1.KeyToKeyCode[key],
- key,
- code,
- text,
- unmodifiedText: text,
- autoRepeat: repeat,
- isSystemKey: source.alt || undefined,
- location: location < 2 ? location : undefined,
- isKeypad: location === 3,
- modifiers,
- });
- // --- Platform-specific code ends here ---
- }
- #dispatchKeyUpAction(source, action) {
- const rawKey = action.value;
- const key = (0, keyUtils_js_1.getNormalizedKey)(rawKey);
- if (!source.pressed.has(key)) {
- return;
- }
- const code = (0, keyUtils_js_1.getKeyCode)(rawKey);
- const location = (0, keyUtils_js_1.getKeyLocation)(rawKey);
- switch (key) {
- case 'Alt':
- source.alt = false;
- break;
- case 'Shift':
- source.shift = false;
- break;
- case 'Control':
- source.ctrl = false;
- break;
- case 'Meta':
- source.meta = false;
- break;
- }
- source.pressed.delete(key);
- const { modifiers } = source;
- // --- Platform-specific code begins here ---
- // The spread is a little hack so JS gives us an array of unicode characters
- // to measure.
- const text = [...key].length === 1 ? key : undefined;
- return this.#context.cdpTarget.cdpClient.sendCommand('Input.dispatchKeyEvent', {
- type: 'keyUp',
- windowsVirtualKeyCode: USKeyboardLayout_js_1.KeyToKeyCode[key],
- key,
- code,
- text,
- unmodifiedText: text,
- location: location < 2 ? location : undefined,
- isSystemKey: source.alt || undefined,
- isKeypad: location === 3,
- modifiers,
- });
- // --- Platform-specific code ends here ---
- }
-}
-ActionDispatcher$1.ActionDispatcher = ActionDispatcher;
-
-var PreloadScriptStorage$1 = {};
-
-var uuid = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(uuid, "__esModule", { value: true });
-uuid.uuidv4 = void 0;
-/**
- * Generates a random v4 UUID, as specified in RFC4122.
- *
- * Uses the native Web Crypto API if available, otherwise falls back to a
- * polyfill.
- *
- * Example: '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
- */
-function uuidv4() {
- // Available only in secure contexts
- // https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
- if ('crypto' in globalThis && 'randomUUID' in globalThis.crypto) {
- // Node with
- // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1 or
- // secure browser context.
- return globalThis.crypto.randomUUID();
- }
- const randomValues = new Uint8Array(16);
- if ('crypto' in globalThis && 'getRandomValues' in globalThis.crypto) {
- // Node with
- // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1 or
- // browser.
- globalThis.crypto.getRandomValues(randomValues);
- }
- else {
- // Node without
- // https://nodejs.org/dist/latest-v20.x/docs/api/globals.html#crypto_1.
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- require$$5.webcrypto.getRandomValues(randomValues);
- }
- // Set version (4) and variant (RFC4122) bits.
- randomValues[6] = (randomValues[6] & 0x0f) | 0x40;
- randomValues[8] = (randomValues[8] & 0x3f) | 0x80;
- const bytesToHex = (bytes) => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
- return [
- bytesToHex(randomValues.subarray(0, 4)),
- bytesToHex(randomValues.subarray(4, 6)),
- bytesToHex(randomValues.subarray(6, 8)),
- bytesToHex(randomValues.subarray(8, 10)),
- bytesToHex(randomValues.subarray(10, 16)),
- ].join('-');
-}
-uuid.uuidv4 = uuidv4;
-
-Object.defineProperty(PreloadScriptStorage$1, "__esModule", { value: true });
-PreloadScriptStorage$1.PreloadScriptStorage = void 0;
-/*
- * Copyright 2023 Google LLC.
- * 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.
- */
-const uuid_js_1 = uuid;
-/**
- * Container class for preload scripts.
- *
- * BiDi IDs are generated by the server and are unique within the context.
- *
- * CDP preload script IDs are generated by the client and are unique
- * within the session.
- *
- * The mapping between BiDi and CDP preload script IDs is 1:many.
- * BiDi IDs are needed by the mapper to keep track of potential multiple CDP IDs
- * in the client.
- *
- * This class does not concern itself with the validity of the IDs.
- */
-class PreloadScriptStorage {
- /** Tracks all BiDi preload scripts. */
- #scripts = new Set();
- /** Finds all entries that match the given filter. */
- findPreloadScripts(filter) {
- if (!filter) {
- return [...this.#scripts];
- }
- return [...this.#scripts].filter((script) => {
- if (filter.id !== undefined && filter.id !== script.id) {
- return false;
- }
- if (filter.contextId !== undefined &&
- filter.contextId !== script.contextId) {
- return false;
- }
- if (filter.contextIds !== undefined &&
- !filter.contextIds.includes(script.contextId)) {
- return false;
- }
- return true;
- });
- }
- /**
- * Keeps track of the given CDP preload scripts associated with the given
- * browsing context ID.
- *
- * @param contextId Browsing context ID, or null for global context.
- * @param cdpPreloadScripts CDP preload scripts.
- * @param functionDeclaration The script itself, in a format expected by the spec
- * i.e. a function.
- */
- addPreloadScripts(contextId, cdpPreloadScripts, functionDeclaration, sandbox) {
- // Generate a random ID.
- const bidiId = (0, uuid_js_1.uuidv4)();
- const preloadScript = {
- id: bidiId,
- contextId,
- cdpPreloadScripts,
- functionDeclaration,
- sandbox,
- };
- this.#scripts.add(preloadScript);
- return preloadScript;
- }
- /**
- * Keeps track of the given CDP preload script in the given BiDi preload
- * script.
- */
- appendCdpPreloadScript(script, cdpPreloadScript) {
- script.cdpPreloadScripts.push(cdpPreloadScript);
- }
- /** Deletes all BiDi preload script entries that match the given filter. */
- removeBiDiPreloadScripts(filter) {
- for (const preloadScript of this.findPreloadScripts(filter)) {
- this.#scripts.delete(preloadScript);
- }
- }
- /** Deletes all CDP preload script entries that match the given filter. */
- removeCdpPreloadScripts(filter) {
- for (const preloadScript of this.#scripts) {
- preloadScript.cdpPreloadScripts = preloadScript.cdpPreloadScripts.filter((cdpPreloadScript) => {
- if (filter?.targetId !== undefined &&
- filter.targetId !== cdpPreloadScript.target.targetId) {
- return true;
- }
- if (filter?.sessionId !== undefined &&
- filter.sessionId !== cdpPreloadScript.target.cdpSessionId) {
- return true;
- }
- return false;
- });
- }
- }
-}
-PreloadScriptStorage$1.PreloadScriptStorage = PreloadScriptStorage;
-
-var browsingContextImpl = {};
-
-var unitConversions = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(unitConversions, "__esModule", { value: true });
-unitConversions.inchesFromCm = void 0;
-/** @return Given an input in cm, convert it to inches. */
-function inchesFromCm(cm) {
- return cm / 2.54;
-}
-unitConversions.inchesFromCm = inchesFromCm;
-
-var deferred = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(deferred, "__esModule", { value: true });
-deferred.Deferred = void 0;
-class Deferred {
- #isFinished = false;
- #promise;
- #resolve;
- #reject;
- get isFinished() {
- return this.#isFinished;
- }
- constructor() {
- this.#promise = new Promise((resolve, reject) => {
- this.#resolve = resolve;
- this.#reject = reject;
- });
- // Needed to avoid `Uncaught (in promise)`. The promises returned by `then`
- // and `catch` will be rejected anyway.
- this.#promise.catch((_error) => {
- // Intentionally empty.
- });
- }
- then(onFulfilled, onRejected) {
- return this.#promise.then(onFulfilled, onRejected);
- }
- catch(onRejected) {
- return this.#promise.catch(onRejected);
- }
- resolve(value) {
- this.#isFinished = true;
- this.#resolve?.(value);
- }
- reject(reason) {
- this.#isFinished = true;
- this.#reject?.(reason);
- }
- finally(onFinally) {
- return this.#promise.finally(onFinally);
- }
- [Symbol.toStringTag] = 'Promise';
-}
-deferred.Deferred = Deferred;
-
-var realm = {};
-
-var scriptEvaluator = {};
-
-(function (exports) {
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.ScriptEvaluator = exports.SHARED_ID_DIVIDER = void 0;
- const protocol_js_1 = protocol;
- // As `script.evaluate` wraps call into serialization script, `lineNumber`
- // should be adjusted.
- const CALL_FUNCTION_STACKTRACE_LINE_OFFSET = 1;
- const EVALUATE_STACKTRACE_LINE_OFFSET = 0;
- exports.SHARED_ID_DIVIDER = '_element_';
- class ScriptEvaluator {
- #eventManager;
- constructor(eventManager) {
- this.#eventManager = eventManager;
- }
- /**
- * Gets the string representation of an object. This is equivalent to
- * calling toString() on the object value.
- * @param cdpObject CDP remote object representing an object.
- * @param realm
- * @return string The stringified object.
- */
- static async stringifyObject(cdpObject, realm) {
- const stringifyResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((obj) => {
- return String(obj);
- }),
- awaitPromise: false,
- arguments: [cdpObject],
- returnByValue: true,
- executionContextId: realm.executionContextId,
- });
- return stringifyResult.result.value;
- }
- /**
- * Serializes a given CDP object into BiDi, keeping references in the
- * target's `globalThis`.
- * @param cdpRemoteObject CDP remote object to be serialized.
- * @param resultOwnership Indicates desired ResultOwnership.
- * @param realm
- */
- async serializeCdpObject(cdpRemoteObject, resultOwnership, realm) {
- const arg = ScriptEvaluator.#cdpRemoteObjectToCallArgument(cdpRemoteObject);
- const cdpWebDriverValue = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((obj) => obj),
- awaitPromise: false,
- arguments: [arg],
- serializationOptions: {
- serialization: 'deep',
- },
- executionContextId: realm.executionContextId,
- });
- return realm.cdpToBidiValue(cdpWebDriverValue, resultOwnership);
- }
- async scriptEvaluate(realm, expression, awaitPromise, resultOwnership, serializationOptions) {
- if (![0, null, undefined].includes(serializationOptions.maxDomDepth))
- throw new Error('serializationOptions.maxDomDepth other than 0 or null is not supported');
- const cdpEvaluateResult = await realm.cdpClient.sendCommand('Runtime.evaluate', {
- contextId: realm.executionContextId,
- expression,
- awaitPromise,
- serializationOptions: {
- serialization: 'deep',
- ...(serializationOptions.maxObjectDepth === undefined ||
- serializationOptions.maxObjectDepth === null
- ? {}
- : { maxDepth: serializationOptions.maxObjectDepth }),
- },
- });
- if (cdpEvaluateResult.exceptionDetails) {
- // Serialize exception details.
- return {
- exceptionDetails: await this.#serializeCdpExceptionDetails(cdpEvaluateResult.exceptionDetails, EVALUATE_STACKTRACE_LINE_OFFSET, resultOwnership, realm),
- type: 'exception',
- realm: realm.realmId,
- };
- }
- return {
- type: 'success',
- result: realm.cdpToBidiValue(cdpEvaluateResult, resultOwnership),
- realm: realm.realmId,
- };
- }
- async callFunction(realm, functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions) {
- if (![0, null, undefined].includes(serializationOptions.maxDomDepth))
- throw new Error('serializationOptions.maxDomDepth other than 0 or null is not supported');
- const callFunctionAndSerializeScript = `(...args)=>{ return _callFunction((\n${functionDeclaration}\n), args);
- function _callFunction(f, args) {
- const deserializedThis = args.shift();
- const deserializedArgs = args;
- return f.apply(deserializedThis, deserializedArgs);
- }}`;
- const thisAndArgumentsList = [
- await this.#deserializeToCdpArg(_this, realm),
- ];
- thisAndArgumentsList.push(...(await Promise.all(_arguments.map(async (a) => {
- return this.#deserializeToCdpArg(a, realm);
- }))));
- let cdpCallFunctionResult;
- try {
- cdpCallFunctionResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: callFunctionAndSerializeScript,
- awaitPromise,
- arguments: thisAndArgumentsList,
- serializationOptions: {
- serialization: 'deep',
- ...(serializationOptions.maxObjectDepth === undefined ||
- serializationOptions.maxObjectDepth === null
- ? {}
- : { maxDepth: serializationOptions.maxObjectDepth }),
- },
- executionContextId: realm.executionContextId,
- });
- }
- catch (e) {
- // Heuristic to determine if the problem is in the argument.
- // The check can be done on the `deserialization` step, but this approach
- // helps to save round-trips.
- if (e.code === -32000 &&
- [
- 'Could not find object with given id',
- 'Argument should belong to the same JavaScript world as target object',
- 'Invalid remote object id',
- ].includes(e.message)) {
- throw new protocol_js_1.Message.NoSuchHandleException('Handle was not found.');
- }
- throw e;
- }
- if (cdpCallFunctionResult.exceptionDetails) {
- // Serialize exception details.
- return {
- exceptionDetails: await this.#serializeCdpExceptionDetails(cdpCallFunctionResult.exceptionDetails, CALL_FUNCTION_STACKTRACE_LINE_OFFSET, resultOwnership, realm),
- type: 'exception',
- realm: realm.realmId,
- };
- }
- return {
- type: 'success',
- result: realm.cdpToBidiValue(cdpCallFunctionResult, resultOwnership),
- realm: realm.realmId,
- };
- }
- static #cdpRemoteObjectToCallArgument(cdpRemoteObject) {
- if (cdpRemoteObject.objectId !== undefined) {
- return { objectId: cdpRemoteObject.objectId };
- }
- if (cdpRemoteObject.unserializableValue !== undefined) {
- return { unserializableValue: cdpRemoteObject.unserializableValue };
- }
- return { value: cdpRemoteObject.value };
- }
- async #deserializeToCdpArg(argumentValue, realm) {
- if ('sharedId' in argumentValue) {
- const [navigableId, rawBackendNodeId] = argumentValue.sharedId.split(exports.SHARED_ID_DIVIDER);
- const backendNodeId = parseInt(rawBackendNodeId ?? '');
- if (isNaN(backendNodeId) ||
- backendNodeId === undefined ||
- navigableId === undefined) {
- throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" was not found.`);
- }
- if (realm.navigableId !== navigableId) {
- throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" belongs to different document. Current document is ${realm.navigableId}.`);
- }
- try {
- const obj = await realm.cdpClient.sendCommand('DOM.resolveNode', {
- backendNodeId,
- executionContextId: realm.executionContextId,
- });
- // TODO(#375): Release `obj.object.objectId` after using.
- return { objectId: obj.object.objectId };
- }
- catch (e) {
- // Heuristic to detect "no such node" exception. Based on the specific
- // CDP implementation.
- if (e.code === -32000 && e.message === 'No node with given id found') {
- throw new protocol_js_1.Message.NoSuchNodeException(`SharedId "${argumentValue.sharedId}" was not found.`);
- }
- throw e;
- }
- }
- if ('handle' in argumentValue) {
- return { objectId: argumentValue.handle };
- }
- switch (argumentValue.type) {
- // Primitive Protocol Value
- // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue
- case 'undefined':
- return { unserializableValue: 'undefined' };
- case 'null':
- return { unserializableValue: 'null' };
- case 'string':
- return { value: argumentValue.value };
- case 'number':
- if (argumentValue.value === 'NaN') {
- return { unserializableValue: 'NaN' };
- }
- else if (argumentValue.value === '-0') {
- return { unserializableValue: '-0' };
- }
- else if (argumentValue.value === 'Infinity') {
- return { unserializableValue: 'Infinity' };
- }
- else if (argumentValue.value === '-Infinity') {
- return { unserializableValue: '-Infinity' };
- }
- return {
- value: argumentValue.value,
- };
- case 'boolean':
- return { value: Boolean(argumentValue.value) };
- case 'bigint':
- return {
- unserializableValue: `BigInt(${JSON.stringify(argumentValue.value)})`,
- };
- case 'date':
- return {
- unserializableValue: `new Date(Date.parse(${JSON.stringify(argumentValue.value)}))`,
- };
- case 'regexp':
- return {
- unserializableValue: `new RegExp(${JSON.stringify(argumentValue.value.pattern)}, ${JSON.stringify(argumentValue.value.flags)})`,
- };
- case 'map': {
- // TODO: If none of the nested keys and values has a remote
- // reference, serialize to `unserializableValue` without CDP roundtrip.
- const keyValueArray = await this.#flattenKeyValuePairs(argumentValue.value, realm);
- const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((...args) => {
- const result = new Map();
- for (let i = 0; i < args.length; i += 2) {
- result.set(args[i], args[i + 1]);
- }
- return result;
- }),
- awaitPromise: false,
- arguments: keyValueArray,
- returnByValue: false,
- executionContextId: realm.executionContextId,
- });
- // TODO(#375): Release `argEvalResult.result.objectId` after using.
- return { objectId: argEvalResult.result.objectId };
- }
- case 'object': {
- // TODO: If none of the nested keys and values has a remote
- // reference, serialize to `unserializableValue` without CDP roundtrip.
- const keyValueArray = await this.#flattenKeyValuePairs(argumentValue.value, realm);
- const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((...args) => {
- const result = {};
- for (let i = 0; i < args.length; i += 2) {
- // Key should be either `string`, `number`, or `symbol`.
- const key = args[i];
- result[key] = args[i + 1];
- }
- return result;
- }),
- awaitPromise: false,
- arguments: keyValueArray,
- returnByValue: false,
- executionContextId: realm.executionContextId,
- });
- // TODO(#375): Release `argEvalResult.result.objectId` after using.
- return { objectId: argEvalResult.result.objectId };
- }
- case 'array': {
- // TODO: If none of the nested items has a remote reference,
- // serialize to `unserializableValue` without CDP roundtrip.
- const args = await this.#flattenValueList(argumentValue.value, realm);
- const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((...args) => {
- return args;
- }),
- awaitPromise: false,
- arguments: args,
- returnByValue: false,
- executionContextId: realm.executionContextId,
- });
- // TODO(#375): Release `argEvalResult.result.objectId` after using.
- return { objectId: argEvalResult.result.objectId };
- }
- case 'set': {
- // TODO: if none of the nested items has a remote reference,
- // serialize to `unserializableValue` without CDP roundtrip.
- const args = await this.#flattenValueList(argumentValue.value, realm);
- const argEvalResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((...args) => {
- return new Set(args);
- }),
- awaitPromise: false,
- arguments: args,
- returnByValue: false,
- executionContextId: realm.executionContextId,
- });
- // TODO(#375): Release `argEvalResult.result.objectId` after using.
- return { objectId: argEvalResult.result.objectId };
- }
- case 'channel': {
- const createChannelHandleResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String(() => {
- const queue = [];
- let queueNonEmptyResolver = null;
- return {
- /**
- * Gets a promise, which is resolved as soon as a message occurs
- * in the queue.
- */
- async getMessage() {
- const onMessage = queue.length > 0
- ? Promise.resolve()
- : new Promise((resolve) => {
- queueNonEmptyResolver = resolve;
- });
- await onMessage;
- return queue.shift();
- },
- /**
- * Adds a message to the queue.
- * Resolves the pending promise if needed.
- */
- sendMessage(message) {
- queue.push(message);
- if (queueNonEmptyResolver !== null) {
- queueNonEmptyResolver();
- queueNonEmptyResolver = null;
- }
- },
- };
- }),
- returnByValue: false,
- executionContextId: realm.executionContextId,
- serializationOptions: {
- serialization: 'deep',
- },
- });
- const channelHandle = createChannelHandleResult.result.objectId;
- // Long-poll the message queue asynchronously.
- void this.#initChannelListener(argumentValue, channelHandle, realm);
- const sendMessageArgResult = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String((channelHandle) => {
- return channelHandle.sendMessage;
- }),
- arguments: [
- {
- objectId: channelHandle,
- },
- ],
- returnByValue: false,
- executionContextId: realm.executionContextId,
- serializationOptions: {
- serialization: 'deep',
- },
- });
- return { objectId: sendMessageArgResult.result.objectId };
- }
- // TODO(#375): Dispose of nested objects.
- default:
- throw new Error(`Value ${JSON.stringify(argumentValue)} is not deserializable.`);
- }
- }
- async #flattenKeyValuePairs(mapping, realm) {
- const keyValueArray = [];
- for (const [key, value] of mapping) {
- let keyArg;
- if (typeof key === 'string') {
- // Key is a string.
- keyArg = { value: key };
- }
- else {
- // Key is a serialized value.
- keyArg = await this.#deserializeToCdpArg(key, realm);
- }
- const valueArg = await this.#deserializeToCdpArg(value, realm);
- keyValueArray.push(keyArg);
- keyValueArray.push(valueArg);
- }
- return keyValueArray;
- }
- async #flattenValueList(list, realm) {
- return Promise.all(list.map((value) => this.#deserializeToCdpArg(value, realm)));
- }
- async #initChannelListener(channel, channelHandle, realm) {
- const channelId = channel.value.channel;
- // TODO(#294): Remove this loop after the realm is destroyed.
- // Rely on the CDP throwing exception in such a case.
- for (;;) {
- const message = await realm.cdpClient.sendCommand('Runtime.callFunctionOn', {
- functionDeclaration: String(async (channelHandle) => channelHandle.getMessage()),
- arguments: [
- {
- objectId: channelHandle,
- },
- ],
- awaitPromise: true,
- executionContextId: realm.executionContextId,
- serializationOptions: {
- serialization: 'deep',
- },
- });
- this.#eventManager.registerEvent({
- method: protocol_js_1.Script.EventNames.MessageEvent,
- params: {
- channel: channelId,
- data: realm.cdpToBidiValue(message, channel.value.ownership ?? 'none'),
- source: {
- realm: realm.realmId,
- context: realm.browsingContextId,
- },
- },
- }, realm.browsingContextId);
- }
- }
- async #serializeCdpExceptionDetails(cdpExceptionDetails, lineOffset, resultOwnership, realm) {
- const callFrames = cdpExceptionDetails.stackTrace?.callFrames.map((frame) => ({
- url: frame.url,
- functionName: frame.functionName,
- // As `script.evaluate` wraps call into serialization script, so
- // `lineNumber` should be adjusted.
- lineNumber: frame.lineNumber - lineOffset,
- columnNumber: frame.columnNumber,
- }));
- const exception = await this.serializeCdpObject(
- // Exception should always be there.
- cdpExceptionDetails.exception, resultOwnership, realm);
- const text = await ScriptEvaluator.stringifyObject(cdpExceptionDetails.exception, realm);
- return {
- exception,
- columnNumber: cdpExceptionDetails.columnNumber,
- // As `script.evaluate` wraps call into serialization script, so
- // `lineNumber` should be adjusted.
- lineNumber: cdpExceptionDetails.lineNumber - lineOffset,
- stackTrace: {
- callFrames: callFrames || [],
- },
- text: text || cdpExceptionDetails.text,
- };
- }
- }
- exports.ScriptEvaluator = ScriptEvaluator;
-
-} (scriptEvaluator));
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(realm, "__esModule", { value: true });
-realm.Realm = void 0;
-const log_js_1$5 = log;
-const scriptEvaluator_js_1 = scriptEvaluator;
-class Realm {
- #realmStorage;
- #browsingContextStorage;
- #realmId;
- #browsingContextId;
- #executionContextId;
- #origin;
- #type;
- #cdpClient;
- #eventManager;
- #scriptEvaluator;
- sandbox;
- cdpSessionId;
- #logger;
- constructor(realmStorage, browsingContextStorage, realmId, browsingContextId, executionContextId, origin, type, sandbox, cdpSessionId, cdpClient, eventManager, logger) {
- this.#realmId = realmId;
- this.#browsingContextId = browsingContextId;
- this.#executionContextId = executionContextId;
- this.sandbox = sandbox;
- this.#origin = origin;
- this.#type = type;
- this.cdpSessionId = cdpSessionId;
- this.#cdpClient = cdpClient;
- this.#realmStorage = realmStorage;
- this.#browsingContextStorage = browsingContextStorage;
- this.#eventManager = eventManager;
- this.#scriptEvaluator = new scriptEvaluator_js_1.ScriptEvaluator(this.#eventManager);
- this.#realmStorage.realmMap.set(this.#realmId, this);
- this.#logger = logger;
- }
- async #releaseObject(handle) {
- try {
- await this.cdpClient.sendCommand('Runtime.releaseObject', {
- objectId: handle,
- });
- }
- catch (e) {
- // Heuristic to determine if the problem is in the unknown handler.
- // Ignore the error if so.
- if (!(e.code === -32000 && e.message === 'Invalid remote object id')) {
- throw e;
- }
- }
- }
- async disown(handle) {
- // Disowning an object from different realm does nothing.
- if (this.#realmStorage.knownHandlesToRealm.get(handle) !== this.realmId) {
- return;
- }
- await this.#releaseObject(handle);
- this.#realmStorage.knownHandlesToRealm.delete(handle);
- }
- cdpToBidiValue(cdpValue, resultOwnership) {
- const deepSerializedValue = cdpValue.result.deepSerializedValue;
- const bidiValue = this.deepSerializedToBiDi(deepSerializedValue);
- if (cdpValue.result.objectId) {
- const objectId = cdpValue.result.objectId;
- if (resultOwnership === 'root') {
- // Extend BiDi value with `handle` based on required `resultOwnership`
- // and CDP response but not on the actual BiDi type.
- bidiValue.handle = objectId;
- // Remember all the handles sent to client.
- this.#realmStorage.knownHandlesToRealm.set(objectId, this.realmId);
- }
- else {
- // No need in awaiting for the object to be released.
- void this.#releaseObject(objectId).catch((error) => this.#logger?.(log_js_1$5.LogType.system, error));
- }
- }
- return bidiValue;
- }
- deepSerializedToBiDi(webDriverValue) {
- // This relies on the CDP to implement proper BiDi serialization, except
- // backendNodeId/sharedId and `platformobject`.
- const result = webDriverValue;
- if (Object.hasOwn(result, 'weakLocalObjectReference')) {
- result.internalId = `${result.weakLocalObjectReference}`;
- delete result['weakLocalObjectReference'];
- }
- // Platform object is a special case. It should have only `{type: object}`
- // without `value` field.
- if (result.type === 'platformobject') {
- return { type: 'object' };
- }
- const bidiValue = result.value;
- if (bidiValue === undefined) {
- return result;
- }
- if (result.type === 'node') {
- if (Object.hasOwn(bidiValue, 'backendNodeId')) {
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- result.sharedId = `${this.navigableId}${scriptEvaluator_js_1.SHARED_ID_DIVIDER}${bidiValue.backendNodeId}`;
- delete bidiValue['backendNodeId'];
- }
- if (Object.hasOwn(bidiValue, 'children')) {
- for (const i in bidiValue.children) {
- bidiValue.children[i] = this.deepSerializedToBiDi(bidiValue.children[i]);
- }
- }
- }
- // Recursively update the nested values.
- if (['array', 'set'].includes(webDriverValue.type)) {
- for (const i in bidiValue) {
- bidiValue[i] = this.deepSerializedToBiDi(bidiValue[i]);
- }
- }
- if (['object', 'map'].includes(webDriverValue.type)) {
- for (const i in bidiValue) {
- bidiValue[i] = [
- this.deepSerializedToBiDi(bidiValue[i][0]),
- this.deepSerializedToBiDi(bidiValue[i][1]),
- ];
- }
- }
- return result;
- }
- toBiDi() {
- return {
- realm: this.realmId,
- origin: this.origin,
- type: this.type,
- context: this.browsingContextId,
- ...(this.sandbox === undefined ? {} : { sandbox: this.sandbox }),
- };
- }
- get realmId() {
- return this.#realmId;
- }
- get navigableId() {
- return (this.#browsingContextStorage.findContext(this.#browsingContextId)
- ?.navigableId ?? 'UNKNOWN');
- }
- get browsingContextId() {
- return this.#browsingContextId;
- }
- get executionContextId() {
- return this.#executionContextId;
- }
- get origin() {
- return this.#origin;
- }
- get type() {
- return this.#type;
- }
- get cdpClient() {
- return this.#cdpClient;
- }
- async callFunction(functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions) {
- const context = this.#browsingContextStorage.getContext(this.browsingContextId);
- await context.awaitUnblocked();
- return {
- result: await this.#scriptEvaluator.callFunction(this, functionDeclaration, _this, _arguments, awaitPromise, resultOwnership, serializationOptions),
- };
- }
- async scriptEvaluate(expression, awaitPromise, resultOwnership, serializationOptions) {
- const context = this.#browsingContextStorage.getContext(this.browsingContextId);
- await context.awaitUnblocked();
- return {
- result: await this.#scriptEvaluator.scriptEvaluate(this, expression, awaitPromise, resultOwnership, serializationOptions),
- };
- }
- /**
- * Serializes a given CDP object into BiDi, keeping references in the
- * target's `globalThis`.
- * @param cdpObject CDP remote object to be serialized.
- * @param resultOwnership Indicates desired ResultOwnership.
- */
- async serializeCdpObject(cdpObject, resultOwnership) {
- return this.#scriptEvaluator.serializeCdpObject(cdpObject, resultOwnership, this);
- }
- /**
- * Gets the string representation of an object. This is equivalent to
- * calling toString() on the object value.
- * @param cdpObject CDP remote object representing an object.
- * @return string The stringified object.
- */
- async stringifyObject(cdpObject) {
- return scriptEvaluator_js_1.ScriptEvaluator.stringifyObject(cdpObject, this);
- }
-}
-realm.Realm = Realm;
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(browsingContextImpl, "__esModule", { value: true });
-browsingContextImpl.BrowsingContextImpl = void 0;
-const unitConversions_js_1 = unitConversions;
-const protocol_js_1$9 = protocol;
-const log_js_1$4 = log;
-const deferred_js_1$2 = deferred;
-const realm_js_1 = realm;
-class BrowsingContextImpl {
- /** The ID of this browsing context. */
- #id;
- /**
- * The ID of the parent browsing context.
- * If null, this is a top-level context.
- */
- #parentId;
- /** Direct children browsing contexts. */
- #children = new Set();
- #browsingContextStorage;
- #deferreds = {
- documentInitialized: new deferred_js_1$2.Deferred(),
- Page: {
- navigatedWithinDocument: new deferred_js_1$2.Deferred(),
- lifecycleEvent: {
- DOMContentLoaded: new deferred_js_1$2.Deferred(),
- load: new deferred_js_1$2.Deferred(),
- },
- },
- };
- #url = 'about:blank';
- #eventManager;
- #realmStorage;
- #loaderId;
- #cdpTarget;
- #maybeDefaultRealm;
- #logger;
- constructor(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger) {
- this.#cdpTarget = cdpTarget;
- this.#realmStorage = realmStorage;
- this.#id = id;
- this.#parentId = parentId;
- this.#eventManager = eventManager;
- this.#browsingContextStorage = browsingContextStorage;
- this.#logger = logger;
- }
- static create(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger) {
- const context = new BrowsingContextImpl(cdpTarget, realmStorage, id, parentId, eventManager, browsingContextStorage, logger);
- context.#initListeners();
- browsingContextStorage.addContext(context);
- if (!context.isTopLevelContext()) {
- context.parent.addChild(context.id);
- }
- eventManager.registerEvent({
- method: protocol_js_1$9.BrowsingContext.EventNames.ContextCreatedEvent,
- params: context.serializeToBidiValue(),
- }, context.id);
- return context;
- }
- /**
- * @see https://html.spec.whatwg.org/multipage/document-sequences.html#navigable
- */
- get navigableId() {
- return this.#loaderId;
- }
- delete() {
- this.#deleteAllChildren();
- this.#realmStorage.deleteRealms({
- browsingContextId: this.id,
- });
- // Remove context from the parent.
- if (!this.isTopLevelContext()) {
- this.parent.#children.delete(this.id);
- }
- this.#eventManager.registerEvent({
- method: protocol_js_1$9.BrowsingContext.EventNames.ContextDestroyedEvent,
- params: this.serializeToBidiValue(),
- }, this.id);
- this.#browsingContextStorage.deleteContextById(this.id);
- }
- /** Returns the ID of this context. */
- get id() {
- return this.#id;
- }
- /** Returns the parent context ID. */
- get parentId() {
- return this.#parentId;
- }
- /** Returns the parent context. */
- get parent() {
- if (this.parentId === null) {
- return null;
- }
- return this.#browsingContextStorage.getContext(this.parentId);
- }
- /** Returns all direct children contexts. */
- get directChildren() {
- return [...this.#children].map((id) => this.#browsingContextStorage.getContext(id));
- }
- /** Returns all children contexts, flattened. */
- get allChildren() {
- const children = this.directChildren;
- return children.concat(...children.map((child) => child.allChildren));
- }
- /**
- * Returns true if this is a top-level context.
- * This is the case whenever the parent context ID is null.
- */
- isTopLevelContext() {
- return this.#parentId === null;
- }
- get top() {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- let topContext = this;
- let parent = topContext.parent;
- while (parent) {
- topContext = parent;
- parent = topContext.parent;
- }
- return topContext;
- }
- addChild(childId) {
- this.#children.add(childId);
- }
- #deleteAllChildren() {
- this.directChildren.map((child) => child.delete());
- }
- get #defaultRealm() {
- if (this.#maybeDefaultRealm === undefined) {
- throw new Error(`No default realm for browsing context ${this.#id}`);
- }
- return this.#maybeDefaultRealm;
- }
- get cdpTarget() {
- return this.#cdpTarget;
- }
- updateCdpTarget(cdpTarget) {
- this.#cdpTarget = cdpTarget;
- this.#initListeners();
- }
- get url() {
- return this.#url;
- }
- async awaitLoaded() {
- await this.#deferreds.Page.lifecycleEvent.load;
- }
- awaitUnblocked() {
- return this.#cdpTarget.targetUnblocked;
- }
- async getOrCreateSandbox(sandbox) {
- if (sandbox === undefined || sandbox === '') {
- return this.#defaultRealm;
- }
- let maybeSandboxes = this.#realmStorage.findRealms({
- browsingContextId: this.id,
- sandbox,
- });
- if (maybeSandboxes.length === 0) {
- await this.#cdpTarget.cdpClient.sendCommand('Page.createIsolatedWorld', {
- frameId: this.id,
- worldName: sandbox,
- });
- // `Runtime.executionContextCreated` should be emitted by the time the
- // previous command is done.
- maybeSandboxes = this.#realmStorage.findRealms({
- browsingContextId: this.id,
- sandbox,
- });
- }
- if (maybeSandboxes.length !== 1) {
- throw Error(`Sandbox ${sandbox} wasn't created.`);
- }
- return maybeSandboxes[0];
- }
- serializeToBidiValue(maxDepth = 0, addParentField = true) {
- return {
- context: this.#id,
- url: this.url,
- children: maxDepth > 0
- ? this.directChildren.map((c) => c.serializeToBidiValue(maxDepth - 1, false))
- : null,
- ...(addParentField ? { parent: this.#parentId } : {}),
- };
- }
- #initListeners() {
- this.#cdpTarget.cdpClient.on('Target.targetInfoChanged', (params) => {
- if (this.id !== params.targetInfo.targetId) {
- return;
- }
- this.#url = params.targetInfo.url;
- });
- this.#cdpTarget.cdpClient.on('Page.frameNavigated', (params) => {
- if (this.id !== params.frame.id) {
- return;
- }
- this.#url = params.frame.url + (params.frame.urlFragment ?? '');
- // At the point the page is initialized, all the nested iframes from the
- // previous page are detached and realms are destroyed.
- // Remove children from context.
- this.#deleteAllChildren();
- });
- this.#cdpTarget.cdpClient.on('Page.navigatedWithinDocument', (params) => {
- if (this.id !== params.frameId) {
- return;
- }
- this.#url = params.url;
- this.#deferreds.Page.navigatedWithinDocument.resolve(params);
- });
- this.#cdpTarget.cdpClient.on('Page.lifecycleEvent', (params) => {
- if (this.id !== params.frameId) {
- return;
- }
- // `timestamp` from the event is MonotonicTime, not real time, so
- // the best Mapper can do is to set the timestamp to the epoch time
- // of the event arrived.
- // https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-MonotonicTime
- const timestamp = new Date().getTime();
- switch (params.name) {
- case 'init':
- this.#documentChanged(params.loaderId);
- this.#deferreds.documentInitialized.resolve();
- break;
- case 'commit':
- this.#loaderId = params.loaderId;
- break;
- case 'DOMContentLoaded':
- this.#deferreds.Page.lifecycleEvent.DOMContentLoaded.resolve(params);
- this.#eventManager.registerEvent({
- method: protocol_js_1$9.BrowsingContext.EventNames.DomContentLoadedEvent,
- params: {
- context: this.id,
- navigation: this.#loaderId ?? null,
- timestamp,
- url: this.#url,
- },
- }, this.id);
- break;
- case 'load':
- this.#deferreds.Page.lifecycleEvent.load.resolve(params);
- this.#eventManager.registerEvent({
- method: protocol_js_1$9.BrowsingContext.EventNames.LoadEvent,
- params: {
- context: this.id,
- navigation: this.#loaderId ?? null,
- timestamp,
- url: this.#url,
- },
- }, this.id);
- break;
- }
- if (params.loaderId !== this.#loaderId) {
- return;
- }
- });
- this.#cdpTarget.cdpClient.on('Runtime.executionContextCreated', (params) => {
- if (params.context.auxData.frameId !== this.id) {
- return;
- }
- // Only this execution contexts are supported for now.
- if (!['default', 'isolated'].includes(params.context.auxData.type)) {
- return;
- }
- const realm = new realm_js_1.Realm(this.#realmStorage, this.#browsingContextStorage, params.context.uniqueId, this.id, params.context.id, this.#getOrigin(params),
- // XXX: differentiate types.
- 'window',
- // Sandbox name for isolated world.
- params.context.auxData.type === 'isolated'
- ? params.context.name
- : undefined, this.#cdpTarget.cdpSessionId, this.#cdpTarget.cdpClient, this.#eventManager, this.#logger);
- if (params.context.auxData.isDefault) {
- this.#maybeDefaultRealm = realm;
- }
- });
- this.#cdpTarget.cdpClient.on('Runtime.executionContextDestroyed', (params) => {
- this.#realmStorage.deleteRealms({
- cdpSessionId: this.#cdpTarget.cdpSessionId,
- executionContextId: params.executionContextId,
- });
- });
- this.#cdpTarget.cdpClient.on('Runtime.executionContextsCleared', () => {
- this.#realmStorage.deleteRealms({
- cdpSessionId: this.#cdpTarget.cdpSessionId,
- });
- });
- }
- #getOrigin(params) {
- if (params.context.auxData.type === 'isolated') {
- // Sandbox should have the same origin as the context itself, but in CDP
- // it has an empty one.
- return this.#defaultRealm.origin;
- }
- // https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin
- return ['://', ''].includes(params.context.origin)
- ? 'null'
- : params.context.origin;
- }
- #documentChanged(loaderId) {
- // Same document navigation.
- if (loaderId === undefined || this.#loaderId === loaderId) {
- if (this.#deferreds.Page.navigatedWithinDocument.isFinished) {
- this.#deferreds.Page.navigatedWithinDocument =
- new deferred_js_1$2.Deferred();
- }
- else {
- this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (navigatedWithinDocument)');
- }
- return;
- }
- this.#resetDeferredsIfFinished();
- this.#loaderId = loaderId;
- }
- #resetDeferredsIfFinished() {
- if (this.#deferreds.documentInitialized.isFinished) {
- this.#deferreds.documentInitialized = new deferred_js_1$2.Deferred();
- }
- else {
- this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (document initialized)');
- }
- if (this.#deferreds.Page.lifecycleEvent.DOMContentLoaded.isFinished) {
- this.#deferreds.Page.lifecycleEvent.DOMContentLoaded =
- new deferred_js_1$2.Deferred();
- }
- else {
- this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (DOMContentLoaded)');
- }
- if (this.#deferreds.Page.lifecycleEvent.load.isFinished) {
- this.#deferreds.Page.lifecycleEvent.load =
- new deferred_js_1$2.Deferred();
- }
- else {
- this.#logger?.(log_js_1$4.LogType.browsingContexts, 'Document changed (load)');
- }
- }
- async navigate(url, wait) {
- await this.awaitUnblocked();
- // TODO: handle loading errors.
- const cdpNavigateResult = await this.#cdpTarget.cdpClient.sendCommand('Page.navigate', {
- url,
- frameId: this.id,
- });
- if (cdpNavigateResult.errorText) {
- throw new protocol_js_1$9.Message.UnknownErrorException(cdpNavigateResult.errorText);
- }
- this.#documentChanged(cdpNavigateResult.loaderId);
- switch (wait) {
- case 'none':
- break;
- case 'interactive':
- // No `loaderId` means same-document navigation.
- if (cdpNavigateResult.loaderId === undefined) {
- await this.#deferreds.Page.navigatedWithinDocument;
- }
- else {
- await this.#deferreds.Page.lifecycleEvent.DOMContentLoaded;
- }
- break;
- case 'complete':
- // No `loaderId` means same-document navigation.
- if (cdpNavigateResult.loaderId === undefined) {
- await this.#deferreds.Page.navigatedWithinDocument;
- }
- else {
- await this.awaitLoaded();
- }
- break;
- }
- return {
- result: {
- navigation: cdpNavigateResult.loaderId ?? null,
- url,
- },
- };
- }
- async reload(ignoreCache, wait) {
- await this.awaitUnblocked();
- await this.#cdpTarget.cdpClient.sendCommand('Page.reload', {
- ignoreCache,
- });
- this.#resetDeferredsIfFinished();
- switch (wait) {
- case 'none':
- break;
- case 'interactive':
- await this.#deferreds.Page.lifecycleEvent.DOMContentLoaded;
- break;
- case 'complete':
- await this.awaitLoaded();
- break;
- }
- return { result: {} };
- }
- async captureScreenshot() {
- const [, result] = await Promise.all([
- // XXX: Either make this a proposal in the BiDi spec, or focus the
- // original tab right after the screenshot is taken.
- // The screenshot command gets blocked until we focus the active tab.
- this.#cdpTarget.cdpClient.sendCommand('Page.bringToFront'),
- this.#cdpTarget.cdpClient.sendCommand('Page.captureScreenshot', {}),
- ]);
- return {
- result: {
- data: result.data,
- },
- };
- }
- async print(params) {
- const printToPdfCdpParams = {
- printBackground: params.background,
- landscape: params.orientation === 'landscape',
- pageRanges: params.pageRanges?.join(',') ?? '',
- scale: params.scale,
- preferCSSPageSize: !params.shrinkToFit,
- };
- if (params.margin?.bottom) {
- printToPdfCdpParams.marginBottom = (0, unitConversions_js_1.inchesFromCm)(params.margin.bottom);
- }
- if (params.margin?.left) {
- printToPdfCdpParams.marginLeft = (0, unitConversions_js_1.inchesFromCm)(params.margin.left);
- }
- if (params.margin?.right) {
- printToPdfCdpParams.marginRight = (0, unitConversions_js_1.inchesFromCm)(params.margin.right);
- }
- if (params.margin?.top) {
- printToPdfCdpParams.marginTop = (0, unitConversions_js_1.inchesFromCm)(params.margin.top);
- }
- if (params.page?.height) {
- printToPdfCdpParams.paperHeight = (0, unitConversions_js_1.inchesFromCm)(params.page.height);
- }
- if (params.page?.width) {
- printToPdfCdpParams.paperWidth = (0, unitConversions_js_1.inchesFromCm)(params.page.width);
- }
- const result = await this.#cdpTarget.cdpClient.sendCommand('Page.printToPDF', printToPdfCdpParams);
- return {
- result: {
- data: result.data,
- },
- };
- }
-}
-browsingContextImpl.BrowsingContextImpl = BrowsingContextImpl;
-
-var cdpTarget = {};
-
-var logManager = {};
-
-var logHelper = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(logHelper, "__esModule", { value: true });
-logHelper.getRemoteValuesText = logHelper.logMessageFormatter = void 0;
-const specifiers = ['%s', '%d', '%i', '%f', '%o', '%O', '%c'];
-function isFormmatSpecifier(str) {
- return specifiers.some((spec) => str.includes(spec));
-}
-/**
- * @param args input remote values to be format printed
- * @return parsed text of the remote values in specific format
- */
-function logMessageFormatter(args) {
- let output = '';
- const argFormat = args[0].value.toString();
- const argValues = args.slice(1, undefined);
- const tokens = argFormat.split(new RegExp(specifiers.map((spec) => `(${spec})`).join('|'), 'g'));
- for (const token of tokens) {
- if (token === undefined || token === '') {
- continue;
- }
- if (isFormmatSpecifier(token)) {
- const arg = argValues.shift();
- // raise an exception when less value is provided
- if (arg === undefined) {
- throw new Error(`Less value is provided: "${getRemoteValuesText(args, false)}"`);
- }
- if (token === '%s') {
- output += stringFromArg(arg);
- }
- else if (token === '%d' || token === '%i') {
- if (arg.type === 'bigint' ||
- arg.type === 'number' ||
- arg.type === 'string') {
- output += parseInt(arg.value.toString(), 10);
- }
- else {
- output += 'NaN';
- }
- }
- else if (token === '%f') {
- if (arg.type === 'bigint' ||
- arg.type === 'number' ||
- arg.type === 'string') {
- output += parseFloat(arg.value.toString());
- }
- else {
- output += 'NaN';
- }
- }
- else {
- // %o, %O, %c
- output += toJson(arg);
- }
- }
- else {
- output += token;
- }
- }
- // raise an exception when more value is provided
- if (argValues.length > 0) {
- throw new Error(`More value is provided: "${getRemoteValuesText(args, false)}"`);
- }
- return output;
-}
-logHelper.logMessageFormatter = logMessageFormatter;
-/**
- * @param arg input remote value to be parsed
- * @return parsed text of the remote value
- *
- * input: {"type": "number", "value": 1}
- * output: 1
- *
- * input: {"type": "string", "value": "abc"}
- * output: "abc"
- *
- * input: {"type": "object", "value": [["id", {"type": "number", "value": 1}]]}
- * output: '{"id": 1}'
- *
- * input: {"type": "object", "value": [["font-size", {"type": "string", "value": "20px"}]]}
- * output: '{"font-size": "20px"}'
- */
-function toJson(arg) {
- // arg type validation
- if (arg.type !== 'array' &&
- arg.type !== 'bigint' &&
- arg.type !== 'date' &&
- arg.type !== 'number' &&
- arg.type !== 'object' &&
- arg.type !== 'string') {
- return stringFromArg(arg);
- }
- if (arg.type === 'bigint') {
- return `${arg.value.toString()}n`;
- }
- if (arg.type === 'number') {
- return arg.value.toString();
- }
- if (['date', 'string'].includes(arg.type)) {
- return JSON.stringify(arg.value);
- }
- if (arg.type === 'object') {
- return `{${arg.value
- .map((pair) => {
- return `${JSON.stringify(pair[0])}:${toJson(pair[1])}`;
- })
- .join(',')}}`;
- }
- if (arg.type === 'array') {
- return `[${arg.value?.map((val) => toJson(val)).join(',') ?? ''}]`;
- }
- throw Error(`Invalid value type: ${arg.toString()}`);
-}
-function stringFromArg(arg) {
- if (!Object.hasOwn(arg, 'value')) {
- return arg.type;
- }
- switch (arg.type) {
- case 'string':
- case 'number':
- case 'boolean':
- case 'bigint':
- return String(arg.value);
- case 'regexp':
- return `/${arg.value.pattern}/${arg.value.flags ?? ''}`;
- case 'date':
- return new Date(arg.value).toString();
- case 'object':
- return `Object(${arg.value?.length ?? ''})`;
- case 'array':
- return `Array(${arg.value?.length ?? ''})`;
- case 'map':
- return `Map(${arg.value.length})`;
- case 'set':
- return `Set(${arg.value.length})`;
- case 'node':
- return 'node';
- default:
- return arg.type;
- }
-}
-function getRemoteValuesText(args, formatText) {
- const arg = args[0];
- if (!arg) {
- return '';
- }
- // if args[0] is a format specifier, format the args as output
- if (arg.type === 'string' &&
- isFormmatSpecifier(arg.value.toString()) &&
- formatText) {
- return logMessageFormatter(args);
- }
- // if args[0] is not a format specifier, just join the args with \u0020 (unicode 'SPACE')
- return args
- .map((arg) => {
- return stringFromArg(arg);
- })
- .join('\u0020');
-}
-logHelper.getRemoteValuesText = getRemoteValuesText;
-
-Object.defineProperty(logManager, "__esModule", { value: true });
-logManager.LogManager = void 0;
-const protocol_js_1$8 = protocol;
-const logHelper_js_1 = logHelper;
-/** Converts CDP StackTrace object to BiDi StackTrace object. */
-function getBidiStackTrace(cdpStackTrace) {
- const stackFrames = cdpStackTrace?.callFrames.map((callFrame) => {
- return {
- columnNumber: callFrame.columnNumber,
- functionName: callFrame.functionName,
- lineNumber: callFrame.lineNumber,
- url: callFrame.url,
- };
- });
- return stackFrames ? { callFrames: stackFrames } : undefined;
-}
-function getLogLevel(consoleApiType) {
- if (['assert', 'error'].includes(consoleApiType)) {
- return 'error';
- }
- if (['debug', 'trace'].includes(consoleApiType)) {
- return 'debug';
- }
- if (['warn', 'warning'].includes(consoleApiType)) {
- return 'warn';
- }
- return 'info';
-}
-class LogManager {
- #eventManager;
- #realmStorage;
- #cdpTarget;
- constructor(cdpTarget, realmStorage, eventManager) {
- this.#cdpTarget = cdpTarget;
- this.#realmStorage = realmStorage;
- this.#eventManager = eventManager;
- }
- static create(cdpTarget, realmStorage, eventManager) {
- const logManager = new LogManager(cdpTarget, realmStorage, eventManager);
- logManager.#initialize();
- return logManager;
- }
- #initialize() {
- this.#initializeLogEntryAddedEventListener();
- }
- #initializeLogEntryAddedEventListener() {
- this.#cdpTarget.cdpClient.on('Runtime.consoleAPICalled', (params) => {
- // Try to find realm by `cdpSessionId` and `executionContextId`,
- // if provided.
- const realm = this.#realmStorage.findRealm({
- cdpSessionId: this.#cdpTarget.cdpSessionId,
- executionContextId: params.executionContextId,
- });
- const argsPromise = realm === undefined
- ? Promise.resolve(params.args)
- : // Properly serialize arguments if possible.
- Promise.all(params.args.map((arg) => {
- return realm.serializeCdpObject(arg, 'none');
- }));
- this.#eventManager.registerPromiseEvent(argsPromise.then((args) => ({
- method: protocol_js_1$8.Log.EventNames.LogEntryAddedEvent,
- params: {
- level: getLogLevel(params.type),
- source: {
- realm: realm?.realmId ?? 'UNKNOWN',
- context: realm?.browsingContextId ?? 'UNKNOWN',
- },
- text: (0, logHelper_js_1.getRemoteValuesText)(args, true),
- timestamp: Math.round(params.timestamp),
- stackTrace: getBidiStackTrace(params.stackTrace),
- type: 'console',
- // Console method is `warn`, not `warning`.
- method: params.type === 'warning' ? 'warn' : params.type,
- args,
- },
- })), realm?.browsingContextId ?? 'UNKNOWN', protocol_js_1$8.Log.EventNames.LogEntryAddedEvent);
- });
- this.#cdpTarget.cdpClient.on('Runtime.exceptionThrown', (params) => {
- // Try to find realm by `cdpSessionId` and `executionContextId`,
- // if provided.
- const realm = this.#realmStorage.findRealm({
- cdpSessionId: this.#cdpTarget.cdpSessionId,
- executionContextId: params.exceptionDetails.executionContextId,
- });
- // Try all the best to get the exception text.
- const textPromise = (async () => {
- if (!params.exceptionDetails.exception) {
- return params.exceptionDetails.text;
- }
- if (realm === undefined) {
- return JSON.stringify(params.exceptionDetails.exception);
- }
- return realm.stringifyObject(params.exceptionDetails.exception);
- })();
- this.#eventManager.registerPromiseEvent(textPromise.then((text) => ({
- method: protocol_js_1$8.Log.EventNames.LogEntryAddedEvent,
- params: {
- level: 'error',
- source: {
- realm: realm?.realmId ?? 'UNKNOWN',
- context: realm?.browsingContextId ?? 'UNKNOWN',
- },
- text,
- timestamp: Math.round(params.timestamp),
- stackTrace: getBidiStackTrace(params.exceptionDetails.stackTrace),
- type: 'javascript',
- },
- })), realm?.browsingContextId ?? 'UNKNOWN', protocol_js_1$8.Log.EventNames.LogEntryAddedEvent);
- });
- }
-}
-logManager.LogManager = LogManager;
-
-var networkProcessor = {};
-
-var DefaultMap$1 = {};
-
-/**
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(DefaultMap$1, "__esModule", { value: true });
-DefaultMap$1.DefaultMap = void 0;
-/**
- * A subclass of Map whose functionality is almost the same as its parent
- * except for the fact that DefaultMap never returns undefined. It provides a
- * default value for keys that do not exist.
- */
-class DefaultMap extends Map {
- /** The default value to return whenever a key is not present in the map. */
- #getDefaultValue;
- constructor(getDefaultValue, entries) {
- super(entries);
- this.#getDefaultValue = getDefaultValue;
- }
- get(key) {
- if (!this.has(key)) {
- this.set(key, this.#getDefaultValue(key));
- }
- return super.get(key);
- }
-}
-DefaultMap$1.DefaultMap = DefaultMap;
-
-var networkRequest = {};
-
-/*
- * Copyright 2023 Google LLC.
- * 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.
- *
- */
-Object.defineProperty(networkRequest, "__esModule", { value: true });
-networkRequest.NetworkRequest = void 0;
-const deferred_js_1$1 = deferred;
-const protocol_js_1$7 = protocol;
-class NetworkRequest {
- static #unknown = 'UNKNOWN';
- /**
- * Each network request has an associated request id, which is a string
- * uniquely identifying that request.
- *
- * The identifier for a request resulting from a redirect matches that of the
- * request that initiated it.
- */
- requestId;
- #servedFromCache = false;
- #redirectCount;
- #eventManager;
- #requestWillBeSentEvent;
- #requestWillBeSentExtraInfoEvent;
- #responseReceivedEvent;
- #responseReceivedExtraInfoEvent;
- #beforeRequestSentDeferred;
- #responseReceivedDeferred;
- constructor(requestId, eventManager) {
- this.requestId = requestId;
- this.#redirectCount = 0;
- this.#eventManager = eventManager;
- this.#beforeRequestSentDeferred = new deferred_js_1$1.Deferred();
- this.#responseReceivedDeferred = new deferred_js_1$1.Deferred();
- }
- onRequestWillBeSentEvent(event) {
- if (this.#requestWillBeSentEvent !== undefined) {
- // TODO: Handle redirect event, requestId is same for the redirect chain
- return;
- }
- this.#requestWillBeSentEvent = event;
- if (this.#requestWillBeSentExtraInfoEvent !== undefined) {
- this.#beforeRequestSentDeferred.resolve();
- }
- this.#sendBeforeRequestEvent();
- }
- onRequestWillBeSentExtraInfoEvent(event) {
- if (this.#requestWillBeSentExtraInfoEvent !== undefined) {
- // TODO: Handle redirect event, requestId is same for the redirect chain
- return;
- }
- this.#requestWillBeSentExtraInfoEvent = event;
- if (this.#requestWillBeSentEvent !== undefined) {
- this.#beforeRequestSentDeferred.resolve();
- }
- }
- onResponseReceivedEventExtraInfo(event) {
- if (this.#responseReceivedExtraInfoEvent !== undefined) {
- // TODO: Handle redirect event, requestId is same for the redirect chain
- return;
- }
- this.#responseReceivedExtraInfoEvent = event;
- if (this.#responseReceivedEvent !== undefined) {
- this.#responseReceivedDeferred.resolve();
- }
- }
- onResponseReceivedEvent(responseReceivedEvent) {
- if (this.#responseReceivedEvent !== undefined) {
- // TODO: Handle redirect event, requestId is same for the redirect chain
- return;
- }
- this.#responseReceivedEvent = responseReceivedEvent;
- if (!responseReceivedEvent.hasExtraInfo &&
- !this.#beforeRequestSentDeferred.isFinished) {
- this.#beforeRequestSentDeferred.resolve();
- }
- if (!responseReceivedEvent.hasExtraInfo ||
- this.#responseReceivedExtraInfoEvent !== undefined ||
- this.#servedFromCache) {
- this.#responseReceivedDeferred.resolve();
- }
- this.#sendResponseReceivedEvent();
- }
- onServedFromCache() {
- if (this.#requestWillBeSentEvent !== undefined) {
- this.#beforeRequestSentDeferred.resolve();
- }
- if (this.#responseReceivedEvent !== undefined) {
- this.#responseReceivedDeferred.resolve();
- }
- this.#servedFromCache = true;
- }
- onLoadingFailedEvent(event) {
- this.#beforeRequestSentDeferred.resolve();
- this.#responseReceivedDeferred.reject(event);
- this.#eventManager.registerEvent({
- method: protocol_js_1$7.Network.EventNames.FetchErrorEvent,
- params: {
- ...this.#getBaseEventParams(),
- errorText: event.errorText,
- },
- }, this.#requestWillBeSentEvent?.frameId ?? null);
- }
- #getBaseEventParams() {
- return {
- context: this.#requestWillBeSentEvent?.frameId ?? null,
- navigation: this.#requestWillBeSentEvent?.loaderId ?? null,
- // TODO: implement.
- redirectCount: this.#redirectCount,
- request: this.#getRequestData(),
- // Timestamp should be in milliseconds, while CDP provides it in seconds.
- timestamp: Math.round((this.#requestWillBeSentEvent?.wallTime ?? 0) * 1000),
- };
- }
- #getRequestData() {
- const cookies = this.#requestWillBeSentExtraInfoEvent
- ? NetworkRequest.#getCookies(this.#requestWillBeSentExtraInfoEvent.associatedCookies)
- : [];
- return {
- request: this.#requestWillBeSentEvent?.requestId ?? NetworkRequest.#unknown,
- url: this.#requestWillBeSentEvent?.request.url ?? NetworkRequest.#unknown,
- method: this.#requestWillBeSentEvent?.request.method ?? NetworkRequest.#unknown,
- headers: Object.keys(this.#requestWillBeSentEvent?.request.headers ?? []).map((key) => ({
- name: key,
- value: this.#requestWillBeSentEvent?.request.headers[key],
- })),
- cookies,
- // TODO: implement.
- headersSize: -1,
- // TODO: implement.
- bodySize: 0,
- timings: {
- // TODO: implement.
- timeOrigin: 0,
- // TODO: implement.
- requestTime: 0,
- // TODO: implement.
- redirectStart: 0,
- // TODO: implement.
- redirectEnd: 0,
- // TODO: implement.
- fetchStart: 0,
- // TODO: implement.
- dnsStart: 0,
- // TODO: implement.
- dnsEnd: 0,
- // TODO: implement.
- connectStart: 0,
- // TODO: implement.
- connectEnd: 0,
- // TODO: implement.
- tlsStart: 0,
- // TODO: implement.
- tlsEnd: 0,
- // TODO: implement.
- requestStart: 0,
- // TODO: implement.
- responseStart: 0,
- // TODO: implement.
- responseEnd: 0,
- },
- };
- }
- #sendBeforeRequestEvent() {
- if (!this.#isIgnoredEvent()) {
- this.#eventManager.registerPromiseEvent(this.#beforeRequestSentDeferred.then(() => this.#getBeforeRequestEvent()), this.#requestWillBeSentEvent?.frameId ?? null, protocol_js_1$7.Network.EventNames.BeforeRequestSentEvent);
- }
- }
- #getBeforeRequestEvent() {
- if (this.#requestWillBeSentEvent === undefined) {
- throw new Error('RequestWillBeSentEvent is not set');
- }
- return {
- method: protocol_js_1$7.Network.EventNames.BeforeRequestSentEvent,
- params: {
- ...this.#getBaseEventParams(),
- initiator: {
- type: NetworkRequest.#getInitiatorType(this.#requestWillBeSentEvent.initiator.type),
- },
- },
- };
- }
- #sendResponseReceivedEvent() {
- if (!this.#isIgnoredEvent()) {
- this.#eventManager.registerPromiseEvent(this.#responseReceivedDeferred.then(() => this.#getResponseReceivedEvent()), this.#responseReceivedEvent?.frameId ?? null, protocol_js_1$7.Network.EventNames.ResponseCompletedEvent);
- }
- }
- #getResponseReceivedEvent() {
- if (this.#requestWillBeSentEvent === undefined) {
- throw new Error('RequestWillBeSentEvent is not set');
- }
- if (this.#responseReceivedEvent === undefined) {
- throw new Error('ResponseReceivedEvent is not set');
- }
- // Chromium sends wrong extraInfo events for responses served from cache.
- // See https://github.com/puppeteer/puppeteer/issues/9965 and
- // https://crbug.com/1340398.
- if (this.#responseReceivedEvent.response.fromDiskCache) {
- this.#responseReceivedExtraInfoEvent = undefined;
- }
- return {
- method: protocol_js_1$7.Network.EventNames.ResponseCompletedEvent,
- params: {
- ...this.#getBaseEventParams(),
- response: {
- url: this.#responseReceivedEvent.response.url,
- protocol: this.#responseReceivedEvent.response.protocol ?? '',
- status: this.#responseReceivedExtraInfoEvent?.statusCode ||
- this.#responseReceivedEvent.response.status,
- statusText: this.#responseReceivedEvent.response.statusText,
- fromCache: (this.#responseReceivedEvent.response.fromDiskCache ||
- this.#responseReceivedEvent.response.fromPrefetchCache) ??
- false,
- headers: NetworkRequest.#getHeaders(this.#responseReceivedEvent.response.headers),
- mimeType: this.#responseReceivedEvent.response.mimeType,
- bytesReceived: this.#responseReceivedEvent.response.encodedDataLength,
- headersSize: this.#responseReceivedExtraInfoEvent?.headersText?.length ?? 0,
- // TODO: consider removing from spec.
- bodySize: 0,
- content: {
- // TODO: consider removing from spec.
- size: 0,
- },
- },
- },
- };
- }
- #isIgnoredEvent() {
- return (this.#requestWillBeSentEvent?.request.url.endsWith('/favicon.ico') ??
- false);
- }
- static #getHeaders(headers) {
- return Object.keys(headers).map((key) => ({
- name: key,
- value: headers[key],
- }));
- }
- static #getInitiatorType(initiatorType) {
- switch (initiatorType) {
- case 'parser':
- case 'script':
- case 'preflight':
- return initiatorType;
- default:
- return 'other';
- }
- }
- static #getCookies(associatedCookies) {
- return associatedCookies.map((cookieInfo) => {
- return {
- name: cookieInfo.cookie.name,
- value: cookieInfo.cookie.value,
- domain: cookieInfo.cookie.domain,
- path: cookieInfo.cookie.path,
- expires: cookieInfo.cookie.expires,
- size: cookieInfo.cookie.size,
- httpOnly: cookieInfo.cookie.httpOnly,
- secure: cookieInfo.cookie.secure,
- sameSite: NetworkRequest.#getCookiesSameSite(cookieInfo.cookie.sameSite),
- };
- });
- }
- static #getCookiesSameSite(cdpSameSiteValue) {
- switch (cdpSameSiteValue) {
- case 'Strict':
- return 'strict';
- case 'Lax':
- return 'lax';
- default:
- return 'none';
- }
- }
-}
-networkRequest.NetworkRequest = NetworkRequest;
-
-/*
- * Copyright 2023 Google LLC.
- * 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.
- */
-Object.defineProperty(networkProcessor, "__esModule", { value: true });
-networkProcessor.NetworkProcessor = void 0;
-const DefaultMap_js_1$1 = DefaultMap$1;
-const networkRequest_js_1 = networkRequest;
-class NetworkProcessor {
- #eventManager;
- /**
- * Map of request ID to NetworkRequest objects. Needed as long as information
- * about requests comes from different events.
- */
- #requestMap;
- constructor(eventManager) {
- this.#eventManager = eventManager;
- this.#requestMap = new DefaultMap_js_1$1.DefaultMap((requestId) => new networkRequest_js_1.NetworkRequest(requestId, this.#eventManager));
- }
- static async create(cdpClient, eventManager) {
- const networkProcessor = new NetworkProcessor(eventManager);
- cdpClient.on('Network.requestWillBeSent', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onRequestWillBeSentEvent(params);
- });
- cdpClient.on('Network.requestWillBeSentExtraInfo', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onRequestWillBeSentExtraInfoEvent(params);
- });
- cdpClient.on('Network.responseReceived', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onResponseReceivedEvent(params);
- });
- cdpClient.on('Network.responseReceivedExtraInfo', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onResponseReceivedEventExtraInfo(params);
- });
- cdpClient.on('Network.loadingFailed', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onLoadingFailedEvent(params);
- });
- cdpClient.on('Network.requestServedFromCache', (params) => {
- networkProcessor
- .#getOrCreateNetworkRequest(params.requestId)
- .onServedFromCache();
- });
- await cdpClient.sendCommand('Network.enable');
- return networkProcessor;
- }
- #getOrCreateNetworkRequest(requestId) {
- return this.#requestMap.get(requestId);
- }
-}
-networkProcessor.NetworkProcessor = NetworkProcessor;
-
-Object.defineProperty(cdpTarget, "__esModule", { value: true });
-cdpTarget.CdpTarget = void 0;
-const logManager_js_1 = logManager;
-const protocol_js_1$6 = protocol;
-const deferred_js_1 = deferred;
-const networkProcessor_js_1 = networkProcessor;
-const log_js_1$3 = log;
-class CdpTarget {
- #targetId;
- #parentTargetId;
- #cdpClient;
- #cdpSessionId;
- #eventManager;
- #preloadScriptStorage;
- #logger;
- #targetUnblocked;
- #networkDomainActivated;
- #browsingContextStorage;
- static create(targetId, parentTargetId, cdpClient, cdpSessionId, realmStorage, eventManager, preloadScriptStorage, browsingContextStorage, logger) {
- const cdpTarget = new CdpTarget(targetId, parentTargetId, cdpClient, cdpSessionId, eventManager, preloadScriptStorage, browsingContextStorage, logger);
- logManager_js_1.LogManager.create(cdpTarget, realmStorage, eventManager);
- cdpTarget.#setEventListeners();
- // No need to await.
- // Deferred will be resolved when the target is unblocked.
- void cdpTarget.#unblock();
- return cdpTarget;
- }
- constructor(targetId, parentTargetId, cdpClient, cdpSessionId, eventManager, preloadScriptStorage, browsingContextStorage, logger) {
- this.#targetId = targetId;
- this.#parentTargetId = parentTargetId;
- this.#cdpClient = cdpClient;
- this.#cdpSessionId = cdpSessionId;
- this.#eventManager = eventManager;
- this.#preloadScriptStorage = preloadScriptStorage;
- this.#browsingContextStorage = browsingContextStorage;
- this.#logger = logger;
- this.#networkDomainActivated = false;
- this.#targetUnblocked = new deferred_js_1.Deferred();
- }
- /** Returns a promise that resolves when the target is unblocked. */
- get targetUnblocked() {
- return this.#targetUnblocked;
- }
- get targetId() {
- return this.#targetId;
- }
- get cdpClient() {
- return this.#cdpClient;
- }
- /**
- * Needed for CDP escape path.
- */
- get cdpSessionId() {
- return this.#cdpSessionId;
- }
- /**
- * Enables all the required CDP domains and unblocks the target.
- */
- async #unblock() {
- try {
- // Enable Network domain, if it is enabled globally.
- // TODO: enable Network domain for OOPiF targets.
- if (this.#eventManager.isNetworkDomainEnabled) {
- await this.enableNetworkDomain();
- }
- await this.#cdpClient.sendCommand('Runtime.enable');
- await this.#cdpClient.sendCommand('Page.enable');
- await this.#cdpClient.sendCommand('Page.setLifecycleEventsEnabled', {
- enabled: true,
- });
- await this.#cdpClient.sendCommand('Target.setAutoAttach', {
- autoAttach: true,
- waitForDebuggerOnStart: true,
- flatten: true,
- });
- await this.#loadPreloadScripts();
- await this.#cdpClient.sendCommand('Runtime.runIfWaitingForDebugger');
- }
- catch (error) {
- // The target might have been closed before the initialization finished.
- if (!this.#cdpClient.isCloseError(error)) {
- throw error;
- }
- }
- this.#targetUnblocked.resolve();
- }
- /**
- * Enables the Network domain (creates NetworkProcessor on the target's cdp
- * client) if it is not enabled yet.
- */
- async enableNetworkDomain() {
- if (!this.#networkDomainActivated) {
- this.#networkDomainActivated = true;
- await networkProcessor_js_1.NetworkProcessor.create(this.cdpClient, this.#eventManager);
- }
- }
- #setEventListeners() {
- this.#cdpClient.on('*', (cdpMethod, params) => {
- this.#eventManager.registerEvent({
- method: protocol_js_1$6.CDP.EventNames.EventReceivedEvent,
- params: {
- cdpMethod: cdpMethod,
- cdpParams: params ?? {},
- cdpSession: this.#cdpSessionId,
- },
- }, null);
- });
- }
- /** Loads all top-level and parent preload scripts. */
- async #loadPreloadScripts() {
- for (const script of this.#preloadScriptStorage.findPreloadScripts({
- contextIds: [null, this.#parentTargetId],
- })) {
- const { functionDeclaration, sandbox } = script;
- // The spec provides a function, and CDP expects an evaluation.
- const cdpPreloadScriptId = await this.addPreloadScript(`(${functionDeclaration})();`, sandbox);
- // Upon attaching to a new target, run preload scripts on each execution
- // context before `Runtime.runIfWaitingForDebugger`.
- //
- // Otherwise a browsing context might be created without the evaluation of
- // preload scripts.
- await Promise.all(this.#browsingContextStorage
- .getAllContexts()
- .filter((context) => context.cdpTarget === this)
- .map((context) => context
- .getOrCreateSandbox(sandbox)
- .then((realm) => this.cdpClient.sendCommand('Runtime.evaluate', {
- expression: `(${functionDeclaration})();`,
- contextId: realm.executionContextId,
- }))
- .catch((error) => {
- this.#logger?.(log_js_1$3.LogType.cdp, 'Could not evaluate preload script', error);
- })));
- this.#preloadScriptStorage.appendCdpPreloadScript(script, {
- target: this,
- preloadScriptId: cdpPreloadScriptId,
- });
- }
- }
- /**
- * Issues `Page.addScriptToEvaluateOnNewDocument` CDP command with the given
- * script source in evaluated form and world name / sandbox.
- *
- * @return The CDP preload script ID.
- */
- async addPreloadScript(scriptSource, sandbox) {
- const result = await this.cdpClient.sendCommand('Page.addScriptToEvaluateOnNewDocument', {
- source: scriptSource,
- worldName: sandbox,
- });
- return result.identifier;
- }
- /**
- * Issues `Page.removeScriptToEvaluateOnNewDocument` CDP command with the
- * given CDP preload script ID.
- */
- async removePreloadScript(cdpPreloadScriptId) {
- await this.cdpClient.sendCommand('Page.removeScriptToEvaluateOnNewDocument', {
- identifier: cdpPreloadScriptId,
- });
- }
-}
-cdpTarget.CdpTarget = CdpTarget;
-
-Object.defineProperty(browsingContextProcessor, "__esModule", { value: true });
-browsingContextProcessor.BrowsingContextProcessor = void 0;
-const protocol_js_1$5 = protocol;
-const log_js_1$2 = log;
-const InputStateManager_js_1 = InputStateManager$1;
-const ActionDispatcher_js_1 = ActionDispatcher$1;
-const PreloadScriptStorage_js_1 = PreloadScriptStorage$1;
-const browsingContextImpl_js_1 = browsingContextImpl;
-const cdpTarget_js_1 = cdpTarget;
-class BrowsingContextProcessor {
- #browsingContextStorage;
- #cdpConnection;
- #eventManager;
- #logger;
- #realmStorage;
- #selfTargetId;
- #preloadScriptStorage;
- #inputStateManager = new InputStateManager_js_1.InputStateManager();
- constructor(realmStorage, cdpConnection, selfTargetId, eventManager, browsingContextStorage, logger) {
- this.#browsingContextStorage = browsingContextStorage;
- this.#cdpConnection = cdpConnection;
- this.#eventManager = eventManager;
- this.#logger = logger;
- this.#realmStorage = realmStorage;
- this.#selfTargetId = selfTargetId;
- this.#preloadScriptStorage = new PreloadScriptStorage_js_1.PreloadScriptStorage();
- this.#setEventListeners(this.#cdpConnection.browserClient());
- }
- /**
- * This method is called for each CDP session, since this class is responsible
- * for creating and destroying all targets and browsing contexts.
- */
- #setEventListeners(cdpClient) {
- cdpClient.on('Target.attachedToTarget', (params) => {
- this.#handleAttachedToTargetEvent(params, cdpClient);
- });
- cdpClient.on('Target.detachedFromTarget', (params) => {
- this.#handleDetachedFromTargetEvent(params);
- });
- cdpClient.on('Page.frameAttached', (params) => {
- this.#handleFrameAttachedEvent(params);
- });
- cdpClient.on('Page.frameDetached', (params) => {
- this.#handleFrameDetachedEvent(params);
- });
- }
- #handleFrameAttachedEvent(params) {
- const parentBrowsingContext = this.#browsingContextStorage.findContext(params.parentFrameId);
- if (parentBrowsingContext !== undefined) {
- browsingContextImpl_js_1.BrowsingContextImpl.create(parentBrowsingContext.cdpTarget, this.#realmStorage, params.frameId, params.parentFrameId, this.#eventManager, this.#browsingContextStorage, this.#logger);
- }
- }
- #handleFrameDetachedEvent(params) {
- // In case of OOPiF no need in deleting BrowsingContext.
- if (params.reason === 'swap') {
- return;
- }
- this.#browsingContextStorage.findContext(params.frameId)?.delete();
- }
- #handleAttachedToTargetEvent(params, parentSessionCdpClient) {
- const { sessionId, targetInfo } = params;
- const targetCdpClient = this.#cdpConnection.getCdpClient(sessionId);
- if (!this.#isValidTarget(targetInfo)) {
- // DevTools or some other not supported by BiDi target. Just release
- // debugger and ignore them.
- targetCdpClient
- .sendCommand('Runtime.runIfWaitingForDebugger')
- .then(() => parentSessionCdpClient.sendCommand('Target.detachFromTarget', params))
- .catch((error) => this.#logger?.(log_js_1$2.LogType.system, error));
- return;
- }
- this.#logger?.(log_js_1$2.LogType.browsingContexts, 'AttachedToTarget event received:', JSON.stringify(params, null, 2));
- this.#setEventListeners(targetCdpClient);
- const maybeContext = this.#browsingContextStorage.findContext(targetInfo.targetId);
- const cdpTarget = cdpTarget_js_1.CdpTarget.create(targetInfo.targetId, maybeContext?.parentId ?? null, targetCdpClient, sessionId, this.#realmStorage, this.#eventManager, this.#preloadScriptStorage, this.#browsingContextStorage, this.#logger);
- if (maybeContext) {
- // OOPiF.
- maybeContext.updateCdpTarget(cdpTarget);
- }
- else {
- // New context.
- browsingContextImpl_js_1.BrowsingContextImpl.create(cdpTarget, this.#realmStorage, targetInfo.targetId, null, this.#eventManager, this.#browsingContextStorage, this.#logger);
- }
- }
- #handleDetachedFromTargetEvent(params) {
- // XXX: params.targetId is deprecated. Update this class to track using
- // params.sessionId instead.
- // https://github.com/GoogleChromeLabs/chromium-bidi/issues/60
- const contextId = params.targetId;
- this.#browsingContextStorage.findContext(contextId)?.delete();
- this.#preloadScriptStorage.removeCdpPreloadScripts({ targetId: contextId });
- }
- async #getRealm(target) {
- if ('realm' in target) {
- return this.#realmStorage.getRealm({
- realmId: target.realm,
- });
- }
- const context = this.#browsingContextStorage.getContext(target.context);
- return context.getOrCreateSandbox(target.sandbox);
- }
- process_browsingContext_getTree(params) {
- const resultContexts = params.root === undefined
- ? this.#browsingContextStorage.getTopLevelContexts()
- : [this.#browsingContextStorage.getContext(params.root)];
- return {
- result: {
- contexts: resultContexts.map((c) => c.serializeToBidiValue(params.maxDepth ?? Number.MAX_VALUE)),
- },
- };
- }
- async process_browsingContext_create(params) {
- const browserCdpClient = this.#cdpConnection.browserClient();
- let referenceContext;
- if (params.referenceContext !== undefined) {
- referenceContext = this.#browsingContextStorage.getContext(params.referenceContext);
- if (!referenceContext.isTopLevelContext()) {
- throw new protocol_js_1$5.Message.InvalidArgumentException(`referenceContext should be a top-level context`);
- }
- }
- let result;
- switch (params.type) {
- case 'tab':
- result = await browserCdpClient.sendCommand('Target.createTarget', {
- url: 'about:blank',
- newWindow: false,
- });
- break;
- case 'window':
- result = await browserCdpClient.sendCommand('Target.createTarget', {
- url: 'about:blank',
- newWindow: true,
- });
- break;
- }
- // Wait for the new tab to be loaded to avoid race conditions in the
- // `browsingContext` events, when the `browsingContext.domContentLoaded` and
- // `browsingContext.load` events from the initial `about:blank` navigation
- // are emitted after the next navigation is started.
- // Details: https://github.com/web-platform-tests/wpt/issues/35846
- const contextId = result.targetId;
- const context = this.#browsingContextStorage.getContext(contextId);
- await context.awaitLoaded();
- return {
- result: {
- context: context.id,
- },
- };
- }
- process_browsingContext_navigate(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- return context.navigate(params.url, params.wait ?? 'none');
- }
- process_browsingContext_reload(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- return context.reload(params.ignoreCache ?? false, params.wait ?? 'none');
- }
- async process_browsingContext_captureScreenshot(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- return context.captureScreenshot();
- }
- async process_browsingContext_print(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- return context.print(params);
- }
- async process_script_addPreloadScript(params) {
- if (params.arguments !== undefined && params.arguments.length > 0) {
- // TODO: Handle arguments.
- throw new Error('add preload script arguments are not supported');
- }
- const cdpTargets = new Set(
- // TODO: The unique target can be in a non-top-level browsing context.
- // We need all the targets.
- // To get them, we can walk through all the contexts and collect their targets into the set.
- params.context === undefined || params.context === null
- ? this.#browsingContextStorage
- .getTopLevelContexts()
- .map((context) => context.cdpTarget)
- : [this.#browsingContextStorage.getContext(params.context).cdpTarget]);
- const cdpPreloadScripts = [];
- for (const cdpTarget of cdpTargets) {
- const cdpPreloadScriptId = await cdpTarget.addPreloadScript(
- // The spec provides a function, and CDP expects an evaluation.
- `(${params.functionDeclaration})();`, params.sandbox);
- cdpPreloadScripts.push({
- target: cdpTarget,
- preloadScriptId: cdpPreloadScriptId,
- });
- }
- const preloadScript = this.#preloadScriptStorage.addPreloadScripts(params.context ?? null, cdpPreloadScripts, params.functionDeclaration, params.sandbox);
- return {
- result: {
- script: preloadScript.id,
- },
- };
- }
- async process_script_removePreloadScript(params) {
- const bidiId = params.script;
- const scripts = this.#preloadScriptStorage.findPreloadScripts({
- id: bidiId,
- });
- if (scripts.length === 0) {
- throw new protocol_js_1$5.Message.NoSuchScriptException(`No preload script with BiDi ID '${bidiId}'`);
- }
- for (const script of scripts) {
- for (const cdpPreloadScript of script.cdpPreloadScripts) {
- const cdpTarget = cdpPreloadScript.target;
- const cdpPreloadScriptId = cdpPreloadScript.preloadScriptId;
- await cdpTarget.removePreloadScript(cdpPreloadScriptId);
- }
- }
- this.#preloadScriptStorage.removeBiDiPreloadScripts({
- id: bidiId,
- });
- return { result: {} };
- }
- async process_script_evaluate(params) {
- const realm = await this.#getRealm(params.target);
- return realm.scriptEvaluate(params.expression, params.awaitPromise, params.resultOwnership ?? 'none', params.serializationOptions ?? {});
- }
- process_script_getRealms(params) {
- if (params.context !== undefined) {
- // Make sure the context is known.
- this.#browsingContextStorage.getContext(params.context);
- }
- const realms = this.#realmStorage
- .findRealms({
- browsingContextId: params.context,
- type: params.type,
- })
- .map((realm) => realm.toBiDi());
- return { result: { realms } };
- }
- async process_script_callFunction(params) {
- const realm = await this.#getRealm(params.target);
- return realm.callFunction(params.functionDeclaration, params.this || {
- type: 'undefined',
- }, // `this` is `undefined` by default.
- params.arguments || [], // `arguments` is `[]` by default.
- params.awaitPromise, params.resultOwnership ?? 'none', params.serializationOptions ?? {});
- }
- async process_script_disown(params) {
- const realm = await this.#getRealm(params.target);
- await Promise.all(params.handles.map(async (h) => realm.disown(h)));
- return { result: {} };
- }
- async process_input_performActions(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- const inputState = this.#inputStateManager.get(context.top);
- const actionsByTick = this.#getActionsByTick(params, inputState);
- const dispatcher = new ActionDispatcher_js_1.ActionDispatcher(inputState, context);
- await dispatcher.dispatchActions(actionsByTick);
- return { result: {} };
- }
- #getActionsByTick(params, inputState) {
- const actionsByTick = [];
- for (const action of params.actions) {
- switch (action.type) {
- case protocol_js_1$5.Input.SourceActionsType.Pointer: {
- action.parameters ??= { pointerType: protocol_js_1$5.Input.PointerType.Mouse };
- action.parameters.pointerType ??= protocol_js_1$5.Input.PointerType.Mouse;
- const source = inputState.getOrCreate(action.id, protocol_js_1$5.Input.SourceActionsType.Pointer, action.parameters.pointerType);
- if (source.subtype !== action.parameters.pointerType) {
- throw new protocol_js_1$5.Message.InvalidArgumentException(`Expected input source ${action.id} to be ${source.subtype}; got ${action.parameters.pointerType}.`);
- }
- break;
- }
- default:
- inputState.getOrCreate(action.id, action.type);
- }
- const actions = action.actions.map((item) => ({
- id: action.id,
- action: item,
- }));
- for (let i = 0; i < actions.length; i++) {
- if (actionsByTick.length === i) {
- actionsByTick.push([]);
- }
- actionsByTick[i].push(actions[i]);
- }
- }
- return actionsByTick;
- }
- async process_input_releaseActions(params) {
- const context = this.#browsingContextStorage.getContext(params.context);
- const topContext = context.top;
- const inputState = this.#inputStateManager.get(topContext);
- const dispatcher = new ActionDispatcher_js_1.ActionDispatcher(inputState, context);
- await dispatcher.dispatchTickActions(inputState.cancelList.reverse());
- this.#inputStateManager.delete(topContext);
- return { result: {} };
- }
- async process_browsingContext_close(commandParams) {
- const browserCdpClient = this.#cdpConnection.browserClient();
- const context = this.#browsingContextStorage.getContext(commandParams.context);
- if (!context.isTopLevelContext()) {
- throw new protocol_js_1$5.Message.InvalidArgumentException('A top-level browsing context cannot be closed.');
- }
- const detachedFromTargetPromise = new Promise((resolve) => {
- const onContextDestroyed = (eventParams) => {
- if (eventParams.targetId === commandParams.context) {
- browserCdpClient.off('Target.detachedFromTarget', onContextDestroyed);
- resolve();
- }
- };
- browserCdpClient.on('Target.detachedFromTarget', onContextDestroyed);
- });
- await browserCdpClient.sendCommand('Target.closeTarget', {
- targetId: commandParams.context,
- });
- // Sometimes CDP command finishes before `detachedFromTarget` event,
- // sometimes after. Wait for the CDP command to be finished, and then wait
- // for `detachedFromTarget` if it hasn't emitted.
- await detachedFromTargetPromise;
- return { result: {} };
- }
- #isValidTarget(target) {
- if (target.targetId === this.#selfTargetId) {
- return false;
- }
- return ['page', 'iframe'].includes(target.type);
- }
- async process_cdp_sendCommand(params) {
- const client = params.cdpSession
- ? this.#cdpConnection.getCdpClient(params.cdpSession)
- : this.#cdpConnection.browserClient();
- const sendCdpCommandResult = await client.sendCommand(params.cdpMethod, params.cdpParams);
- return {
- result: sendCdpCommandResult,
- cdpSession: params.cdpSession,
- };
- }
- process_cdp_getSession(params) {
- const context = params.context;
- const sessionId = this.#browsingContextStorage.getContext(context).cdpTarget.cdpSessionId;
- if (sessionId === undefined) {
- return { result: { cdpSession: null } };
- }
- return { result: { cdpSession: sessionId } };
- }
-}
-browsingContextProcessor.BrowsingContextProcessor = BrowsingContextProcessor;
-
-var OutgoingBidiMessage$1 = {};
-
-/**
- * Copyright 2021 Google LLC.
- * 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.
- */
-Object.defineProperty(OutgoingBidiMessage$1, "__esModule", { value: true });
-OutgoingBidiMessage$1.OutgoingBidiMessage = void 0;
-class OutgoingBidiMessage {
- #message;
- #channel;
- constructor(message, channel) {
- this.#message = message;
- this.#channel = channel;
- }
- static async createFromPromise(messagePromise, channel) {
- return messagePromise.then((message) => new OutgoingBidiMessage(message, channel));
- }
- static createResolved(message, channel) {
- return Promise.resolve(new OutgoingBidiMessage(message, channel));
- }
- get message() {
- return this.#message;
- }
- get channel() {
- return this.#channel;
- }
-}
-OutgoingBidiMessage$1.OutgoingBidiMessage = OutgoingBidiMessage;
-
-/**
- * Copyright 2021 Google LLC.
- * 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.
- */
-Object.defineProperty(CommandProcessor$1, "__esModule", { value: true });
-CommandProcessor$1.CommandProcessor = void 0;
-const protocol_js_1$4 = protocol;
-const log_js_1$1 = log;
-const EventEmitter_js_1$1 = EventEmitter$2;
-const browsingContextProcessor_js_1 = browsingContextProcessor;
-const OutgoingBidiMessage_js_1$1 = OutgoingBidiMessage$1;
-class BidiNoOpParser {
- parseAddPreloadScriptParams(params) {
- return params;
- }
- parseRemovePreloadScriptParams(params) {
- return params;
- }
- parseGetRealmsParams(params) {
- return params;
- }
- parseCallFunctionParams(params) {
- return params;
- }
- parseEvaluateParams(params) {
- return params;
- }
- parseDisownParams(params) {
- return params;
- }
- parseSendCommandParams(params) {
- return params;
- }
- parseGetSessionParams(params) {
- return params;
- }
- parseSubscribeParams(params) {
- return params;
- }
- parseNavigateParams(params) {
- return params;
- }
- parseReloadParams(params) {
- return params;
- }
- parseGetTreeParams(params) {
- return params;
- }
- parseCreateParams(params) {
- return params;
- }
- parseCloseParams(params) {
- return params;
- }
- parseCaptureScreenshotParams(params) {
- return params;
- }
- parsePrintParams(params) {
- return params;
- }
- parsePerformActionsParams(params) {
- return params;
- }
- parseReleaseActionsParams(params) {
- return params;
- }
-}
-class CommandProcessor extends EventEmitter_js_1$1.EventEmitter {
- #contextProcessor;
- #eventManager;
- #parser;
- #logger;
- constructor(realmStorage, cdpConnection, eventManager, selfTargetId, parser = new BidiNoOpParser(), browsingContextStorage, logger) {
- super();
- this.#eventManager = eventManager;
- this.#logger = logger;
- this.#contextProcessor = new browsingContextProcessor_js_1.BrowsingContextProcessor(realmStorage, cdpConnection, selfTargetId, eventManager, browsingContextStorage, logger);
- this.#parser = parser;
- }
- static #process_session_status() {
- return { result: { ready: false, message: 'already connected' } };
- }
- async #process_session_subscribe(params, channel) {
- await this.#eventManager.subscribe(params.events, params.contexts ?? [null], channel);
- return { result: {} };
- }
- async #process_session_unsubscribe(params, channel) {
- await this.#eventManager.unsubscribe(params.events, params.contexts ?? [null], channel);
- return { result: {} };
- }
- async #processCommand(commandData) {
- switch (commandData.method) {
- case 'session.status':
- return CommandProcessor.#process_session_status();
- case 'session.subscribe':
- return this.#process_session_subscribe(this.#parser.parseSubscribeParams(commandData.params), commandData.channel ?? null);
- case 'session.unsubscribe':
- return this.#process_session_unsubscribe(this.#parser.parseSubscribeParams(commandData.params), commandData.channel ?? null);
- case 'browsingContext.create':
- return this.#contextProcessor.process_browsingContext_create(this.#parser.parseCreateParams(commandData.params));
- case 'browsingContext.close':
- return this.#contextProcessor.process_browsingContext_close(this.#parser.parseCloseParams(commandData.params));
- case 'browsingContext.getTree':
- return this.#contextProcessor.process_browsingContext_getTree(this.#parser.parseGetTreeParams(commandData.params));
- case 'browsingContext.navigate':
- return this.#contextProcessor.process_browsingContext_navigate(this.#parser.parseNavigateParams(commandData.params));
- case 'browsingContext.captureScreenshot':
- return this.#contextProcessor.process_browsingContext_captureScreenshot(this.#parser.parseCaptureScreenshotParams(commandData.params));
- case 'browsingContext.print':
- return this.#contextProcessor.process_browsingContext_print(this.#parser.parsePrintParams(commandData.params));
- case 'browsingContext.reload':
- return this.#contextProcessor.process_browsingContext_reload(this.#parser.parseReloadParams(commandData.params));
- case 'script.addPreloadScript':
- return this.#contextProcessor.process_script_addPreloadScript(this.#parser.parseAddPreloadScriptParams(commandData.params));
- case 'script.removePreloadScript':
- return this.#contextProcessor.process_script_removePreloadScript(this.#parser.parseRemovePreloadScriptParams(commandData.params));
- case 'script.getRealms':
- return this.#contextProcessor.process_script_getRealms(this.#parser.parseGetRealmsParams(commandData.params));
- case 'script.callFunction':
- return this.#contextProcessor.process_script_callFunction(this.#parser.parseCallFunctionParams(commandData.params));
- case 'script.evaluate':
- return this.#contextProcessor.process_script_evaluate(this.#parser.parseEvaluateParams(commandData.params));
- case 'script.disown':
- return this.#contextProcessor.process_script_disown(this.#parser.parseDisownParams(commandData.params));
- case 'input.performActions':
- return this.#contextProcessor.process_input_performActions(this.#parser.parsePerformActionsParams(commandData.params));
- case 'input.releaseActions':
- return this.#contextProcessor.process_input_releaseActions(this.#parser.parseReleaseActionsParams(commandData.params));
- case 'cdp.sendCommand':
- return this.#contextProcessor.process_cdp_sendCommand(this.#parser.parseSendCommandParams(commandData.params));
- case 'cdp.getSession':
- return this.#contextProcessor.process_cdp_getSession(this.#parser.parseGetSessionParams(commandData.params));
- }
- // Intentionally kept outside of the switch statement to ensure that
- // ESLint @typescript-eslint/switch-exhaustiveness-check triggers if a new
- // command is added.
- throw new protocol_js_1$4.Message.UnknownCommandException(`Unknown command '${commandData.method}'.`);
- }
- async processCommand(command) {
- try {
- const result = await this.#processCommand(command);
- const response = {
- id: command.id,
- ...result,
- };
- this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(response, command.channel ?? null));
- }
- catch (e) {
- if (e instanceof protocol_js_1$4.Message.ErrorResponse) {
- const errorResponse = e;
- this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(errorResponse.toErrorResponse(command.id), command.channel ?? null));
- }
- else {
- const error = e;
- this.#logger?.(log_js_1$1.LogType.bidi, error);
- this.emit('response', OutgoingBidiMessage_js_1$1.OutgoingBidiMessage.createResolved(new protocol_js_1$4.Message.UnknownErrorException(error.message).toErrorResponse(command.id), command.channel ?? null));
- }
- }
- }
-}
-CommandProcessor$1.CommandProcessor = CommandProcessor;
-
-var browsingContextStorage = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(browsingContextStorage, "__esModule", { value: true });
-browsingContextStorage.BrowsingContextStorage = void 0;
-const protocol_js_1$3 = protocol;
-/** Container class for browsing contexts. */
-class BrowsingContextStorage {
- /** Map from context ID to context implementation. */
- #contexts = new Map();
- /** Gets all top-level contexts, i.e. those with no parent. */
- getTopLevelContexts() {
- return this.getAllContexts().filter((context) => context.isTopLevelContext());
- }
- /** Gets all contexts. */
- getAllContexts() {
- return Array.from(this.#contexts.values());
- }
- /** Deletes the context with the given ID. */
- deleteContextById(id) {
- this.#contexts.delete(id);
- }
- /** Deletes the given context. */
- deleteContext(context) {
- this.#contexts.delete(context.id);
- }
- /** Tracks the given context. */
- addContext(context) {
- this.#contexts.set(context.id, context);
- }
- /** Returns true whether there is an existing context with the given ID. */
- hasContext(id) {
- return this.#contexts.has(id);
- }
- /** Gets the context with the given ID, if any. */
- findContext(id) {
- return this.#contexts.get(id);
- }
- /** Returns the top-level context ID of the given context, if any. */
- findTopLevelContextId(id) {
- if (id === null) {
- return null;
- }
- const maybeContext = this.findContext(id);
- const parentId = maybeContext?.parentId ?? null;
- if (parentId === null) {
- return id;
- }
- return this.findTopLevelContextId(parentId);
- }
- /** Gets the context with the given ID, if any, otherwise throws. */
- getContext(id) {
- const result = this.findContext(id);
- if (result === undefined) {
- throw new protocol_js_1$3.Message.NoSuchFrameException(`Context ${id} not found`);
- }
- return result;
- }
-}
-browsingContextStorage.BrowsingContextStorage = BrowsingContextStorage;
-
-var EventManager$1 = {};
-
-var buffer = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(buffer, "__esModule", { value: true });
-buffer.Buffer = void 0;
-/**
- * Implements a FIFO buffer with a fixed size.
- */
-let Buffer$1 = class Buffer {
- #capacity;
- #entries = [];
- #onItemRemoved;
- /**
- * @param capacity
- * @param onItemRemoved optional delegate called for each removed element.
- */
- constructor(capacity, onItemRemoved) {
- this.#capacity = capacity;
- this.#onItemRemoved = onItemRemoved;
- }
- get() {
- return this.#entries;
- }
- add(value) {
- this.#entries.push(value);
- while (this.#entries.length > this.#capacity) {
- const item = this.#entries.shift();
- if (item !== undefined) {
- this.#onItemRemoved?.(item);
- }
- }
- }
-};
-buffer.Buffer = Buffer$1;
-
-var idWrapper = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(idWrapper, "__esModule", { value: true });
-idWrapper.IdWrapper = void 0;
-/**
- * Creates an object with a positive unique incrementing id.
- */
-class IdWrapper {
- static #counter = 0;
- #id;
- constructor() {
- this.#id = ++IdWrapper.#counter;
- }
- get id() {
- return this.#id;
- }
-}
-idWrapper.IdWrapper = IdWrapper;
-
-var SubscriptionManager$1 = {};
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(SubscriptionManager$1, "__esModule", { value: true });
-SubscriptionManager$1.SubscriptionManager = SubscriptionManager$1.unrollEvents = SubscriptionManager$1.cartesianProduct = void 0;
-const protocol_js_1$2 = protocol;
-/**
- * Returns the cartesian product of the given arrays.
- *
- * Example:
- * cartesian([1, 2], ['a', 'b']); => [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
- */
-function cartesianProduct(...a) {
- return a.reduce((a, b) => a.flatMap((d) => b.map((e) => [d, e].flat())));
-}
-SubscriptionManager$1.cartesianProduct = cartesianProduct;
-/** Expands "AllEvents" events into atomic events. */
-function unrollEvents(events) {
- const allEvents = [];
- for (const event of events) {
- switch (event) {
- case protocol_js_1$2.BrowsingContext.AllEvents:
- allEvents.push(...Object.values(protocol_js_1$2.BrowsingContext.EventNames));
- break;
- case protocol_js_1$2.CDP.AllEvents:
- allEvents.push(...Object.values(protocol_js_1$2.CDP.EventNames));
- break;
- case protocol_js_1$2.Log.AllEvents:
- allEvents.push(...Object.values(protocol_js_1$2.Log.EventNames));
- break;
- case protocol_js_1$2.Network.AllEvents:
- allEvents.push(...Object.values(protocol_js_1$2.Network.EventNames));
- break;
- case protocol_js_1$2.Script.AllEvents:
- allEvents.push(...Object.values(protocol_js_1$2.Script.EventNames));
- break;
- default:
- allEvents.push(event);
- }
- }
- return allEvents;
-}
-SubscriptionManager$1.unrollEvents = unrollEvents;
-class SubscriptionManager {
- #subscriptionPriority = 0;
- // BrowsingContext `null` means the event has subscription across all the
- // browsing contexts.
- // Channel `null` means no `channel` should be added.
- #channelToContextToEventMap = new Map();
- #browsingContextStorage;
- constructor(browsingContextStorage) {
- this.#browsingContextStorage = browsingContextStorage;
- }
- getChannelsSubscribedToEvent(eventMethod, contextId) {
- const prioritiesAndChannels = Array.from(this.#channelToContextToEventMap.keys())
- .map((channel) => ({
- priority: this.#getEventSubscriptionPriorityForChannel(eventMethod, contextId, channel),
- channel,
- }))
- .filter(({ priority }) => priority !== null);
- // Sort channels by priority.
- return prioritiesAndChannels
- .sort((a, b) => a.priority - b.priority)
- .map(({ channel }) => channel);
- }
- #getEventSubscriptionPriorityForChannel(eventMethod, contextId, channel) {
- const contextToEventMap = this.#channelToContextToEventMap.get(channel);
- if (contextToEventMap === undefined) {
- return null;
- }
- const maybeTopLevelContextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
- // `null` covers global subscription.
- const relevantContexts = [...new Set([null, maybeTopLevelContextId])];
- // Get all the subscription priorities.
- const priorities = relevantContexts
- .map((c) => contextToEventMap.get(c)?.get(eventMethod))
- .filter((p) => p !== undefined);
- if (priorities.length === 0) {
- // Not subscribed, return null.
- return null;
- }
- // Return minimal priority.
- return Math.min(...priorities);
- }
- subscribe(event, contextId, channel) {
- // All the subscriptions are handled on the top-level contexts.
- contextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
- if (event === protocol_js_1$2.BrowsingContext.AllEvents) {
- Object.values(protocol_js_1$2.BrowsingContext.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
- return;
- }
- if (event === protocol_js_1$2.CDP.AllEvents) {
- Object.values(protocol_js_1$2.CDP.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
- return;
- }
- if (event === protocol_js_1$2.Log.AllEvents) {
- Object.values(protocol_js_1$2.Log.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
- return;
- }
- if (event === protocol_js_1$2.Network.AllEvents) {
- Object.values(protocol_js_1$2.Network.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
- return;
- }
- if (event === protocol_js_1$2.Script.AllEvents) {
- Object.values(protocol_js_1$2.Script.EventNames).map((specificEvent) => this.subscribe(specificEvent, contextId, channel));
- return;
- }
- if (!this.#channelToContextToEventMap.has(channel)) {
- this.#channelToContextToEventMap.set(channel, new Map());
- }
- const contextToEventMap = this.#channelToContextToEventMap.get(channel);
- if (!contextToEventMap.has(contextId)) {
- contextToEventMap.set(contextId, new Map());
- }
- const eventMap = contextToEventMap.get(contextId);
- // Do not re-subscribe to events to keep the priority.
- if (eventMap.has(event)) {
- return;
- }
- eventMap.set(event, this.#subscriptionPriority++);
- }
- /**
- * Unsubscribes atomically from all events in the given contexts and channel.
- */
- unsubscribeAll(events, contextIds, channel) {
- // Assert all contexts are known.
- for (const contextId of contextIds) {
- if (contextId !== null) {
- this.#browsingContextStorage.getContext(contextId);
- }
- }
- const eventContextPairs = cartesianProduct(unrollEvents(events), contextIds);
- // Assert all unsubscriptions are valid.
- // If any of the unsubscriptions are invalid, do not unsubscribe from anything.
- eventContextPairs
- .map(([event, contextId]) => this.#checkUnsubscribe(event, contextId, channel))
- .forEach((unsubscribe) => unsubscribe());
- }
- /**
- * Unsubscribes from the event in the given context and channel.
- * Syntactic sugar for "unsubscribeAll".
- */
- unsubscribe(eventName, contextId, channel) {
- this.unsubscribeAll([eventName], [contextId], channel);
- }
- #checkUnsubscribe(event, contextId, channel) {
- // All the subscriptions are handled on the top-level contexts.
- contextId = this.#browsingContextStorage.findTopLevelContextId(contextId);
- if (!this.#channelToContextToEventMap.has(channel)) {
- throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
- }
- const contextToEventMap = this.#channelToContextToEventMap.get(channel);
- if (!contextToEventMap.has(contextId)) {
- throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
- }
- const eventMap = contextToEventMap.get(contextId);
- if (!eventMap.has(event)) {
- throw new protocol_js_1$2.Message.InvalidArgumentException(`Cannot unsubscribe from ${event}, ${contextId === null ? 'null' : contextId}. No subscription found.`);
- }
- return () => {
- eventMap.delete(event);
- // Clean up maps if empty.
- if (eventMap.size === 0) {
- contextToEventMap.delete(event);
- }
- if (contextToEventMap.size === 0) {
- this.#channelToContextToEventMap.delete(channel);
- }
- };
- }
-}
-SubscriptionManager$1.SubscriptionManager = SubscriptionManager;
-
-/**
- * Copyright 2022 Google LLC.
- * 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.
- */
-Object.defineProperty(EventManager$1, "__esModule", { value: true });
-EventManager$1.EventManager = void 0;
-const protocol_js_1$1 = protocol;
-const buffer_js_1 = buffer;
-const idWrapper_js_1 = idWrapper;
-const OutgoingBidiMessage_js_1 = OutgoingBidiMessage$1;
-const DefaultMap_js_1 = DefaultMap$1;
-const SubscriptionManager_js_1 = SubscriptionManager$1;
-class EventWrapper {
- #idWrapper;
- #contextId;
- #event;
- constructor(event, contextId) {
- this.#idWrapper = new idWrapper_js_1.IdWrapper();
- this.#contextId = contextId;
- this.#event = event;
- }
- get id() {
- return this.#idWrapper.id;
- }
- get contextId() {
- return this.#contextId;
- }
- get event() {
- return this.#event;
- }
-}
-/**
- * Maps event name to a desired buffer length.
- */
-const eventBufferLength = new Map([
- [protocol_js_1$1.Log.EventNames.LogEntryAddedEvent, 100],
-]);
-class EventManager {
- static #NETWORK_DOMAIN_PREFIX = 'network';
- /**
- * Maps event name to a set of contexts where this event already happened.
- * Needed for getting buffered events from all the contexts in case of
- * subscripting to all contexts.
- */
- #eventToContextsMap = new DefaultMap_js_1.DefaultMap(() => new Set());
- /**
- * Maps `eventName` + `browsingContext` to buffer. Used to get buffered events
- * during subscription. Channel-agnostic.
- */
- #eventBuffers = new Map();
- /**
- * Maps `eventName` + `browsingContext` + `channel` to last sent event id.
- * Used to avoid sending duplicated events when user
- * subscribes -> unsubscribes -> subscribes.
- */
- #lastMessageSent = new Map();
- #subscriptionManager;
- #bidiServer;
- #isNetworkDomainEnabled;
- constructor(bidiServer) {
- this.#bidiServer = bidiServer;
- this.#subscriptionManager = new SubscriptionManager_js_1.SubscriptionManager(bidiServer.getBrowsingContextStorage());
- this.#isNetworkDomainEnabled = false;
- }
- get isNetworkDomainEnabled() {
- return this.#isNetworkDomainEnabled;
- }
- /**
- * Returns consistent key to be used to access value maps.
- */
- static #getMapKey(eventName, browsingContext, channel) {
- return JSON.stringify({ eventName, browsingContext, channel });
- }
- registerEvent(event, contextId) {
- this.registerPromiseEvent(Promise.resolve(event), contextId, event.method);
- }
- registerPromiseEvent(event, contextId, eventName) {
- const eventWrapper = new EventWrapper(event, contextId);
- const sortedChannels = this.#subscriptionManager.getChannelsSubscribedToEvent(eventName, contextId);
- this.#bufferEvent(eventWrapper, eventName);
- // Send events to channels in the subscription priority.
- for (const channel of sortedChannels) {
- this.#bidiServer.emitOutgoingMessage(OutgoingBidiMessage_js_1.OutgoingBidiMessage.createFromPromise(event, channel));
- this.#markEventSent(eventWrapper, channel, eventName);
- }
- }
- async subscribe(eventNames, contextIds, channel) {
- // First check if all the contexts are known.
- for (const contextId of contextIds) {
- if (contextId !== null) {
- // Assert the context is known. Throw exception otherwise.
- this.#bidiServer.getBrowsingContextStorage().getContext(contextId);
- }
- }
- for (const eventName of eventNames) {
- for (const contextId of contextIds) {
- await this.#handleDomains(eventName, contextId);
- this.#subscriptionManager.subscribe(eventName, contextId, channel);
- for (const eventWrapper of this.#getBufferedEvents(eventName, contextId, channel)) {
- // The order of the events is important.
- this.#bidiServer.emitOutgoingMessage(OutgoingBidiMessage_js_1.OutgoingBidiMessage.createFromPromise(eventWrapper.event, channel));
- this.#markEventSent(eventWrapper, channel, eventName);
- }
- }
- }
- }
- /**
- * Enables domains for the subscribed event in the required contexts or
- * globally.
- */
- async #handleDomains(eventName, contextId) {
- // Enable network domain if user subscribed to any of network events.
- if (eventName.startsWith(EventManager.#NETWORK_DOMAIN_PREFIX)) {
- // Enable for all the contexts.
- if (contextId === null) {
- this.#isNetworkDomainEnabled = true;
- await Promise.all(this.#bidiServer
- .getBrowsingContextStorage()
- .getAllContexts()
- .map((context) => context.cdpTarget.enableNetworkDomain()));
- }
- else {
- await this.#bidiServer
- .getBrowsingContextStorage()
- .getContext(contextId)
- .cdpTarget.enableNetworkDomain();
- }
- }
- }
- unsubscribe(eventNames, contextIds, channel) {
- this.#subscriptionManager.unsubscribeAll(eventNames, contextIds, channel);
- }
- /**
- * If the event is buffer-able, put it in the buffer.
- */
- #bufferEvent(eventWrapper, eventName) {
- if (!eventBufferLength.has(eventName)) {
- // Do nothing if the event is no buffer-able.
- return;
- }
- const bufferMapKey = EventManager.#getMapKey(eventName, eventWrapper.contextId);
- if (!this.#eventBuffers.has(bufferMapKey)) {
- this.#eventBuffers.set(bufferMapKey, new buffer_js_1.Buffer(eventBufferLength.get(eventName)));
- }
- this.#eventBuffers.get(bufferMapKey).add(eventWrapper);
- // Add the context to the list of contexts having `eventName` events.
- this.#eventToContextsMap.get(eventName).add(eventWrapper.contextId);
- }
- /**
- * If the event is buffer-able, mark it as sent to the given contextId and channel.
- */
- #markEventSent(eventWrapper, channel, eventName) {
- if (!eventBufferLength.has(eventName)) {
- // Do nothing if the event is no buffer-able.
- return;
- }
- const lastSentMapKey = EventManager.#getMapKey(eventName, eventWrapper.contextId, channel);
- this.#lastMessageSent.set(lastSentMapKey, Math.max(this.#lastMessageSent.get(lastSentMapKey) ?? 0, eventWrapper.id));
- }
- /**
- * Returns events which are buffered and not yet sent to the given channel events.
- */
- #getBufferedEvents(eventName, contextId, channel) {
- const bufferMapKey = EventManager.#getMapKey(eventName, contextId);
- const lastSentMapKey = EventManager.#getMapKey(eventName, contextId, channel);
- const lastSentMessageId = this.#lastMessageSent.get(lastSentMapKey) ?? -Infinity;
- const result = this.#eventBuffers
- .get(bufferMapKey)
- ?.get()
- .filter((wrapper) => wrapper.id > lastSentMessageId) ?? [];
- if (contextId === null) {
- // For global subscriptions, events buffered in each context should be sent back.
- Array.from(this.#eventToContextsMap.get(eventName).keys())
- .filter((_contextId) =>
- // Events without context are already in the result.
- _contextId !== null &&
- // Events from deleted contexts should not be sent.
- this.#bidiServer.getBrowsingContextStorage().hasContext(_contextId))
- .map((_contextId) => this.#getBufferedEvents(eventName, _contextId, channel))
- .forEach((events) => result.push(...events));
- }
- return result.sort((e1, e2) => e1.id - e2.id);
- }
-}
-EventManager$1.EventManager = EventManager;
-
-var realmStorage = {};
-
-Object.defineProperty(realmStorage, "__esModule", { value: true });
-realmStorage.RealmStorage = void 0;
-const protocol_js_1 = protocol;
-/** Container class for browsing realms. */
-class RealmStorage {
- /** Tracks handles and their realms sent to the client. */
- #knownHandlesToRealm = new Map();
- /** Map from realm ID to Realm. */
- #realmMap = new Map();
- get knownHandlesToRealm() {
- return this.#knownHandlesToRealm;
- }
- get realmMap() {
- return this.#realmMap;
- }
- /** Finds all realms that match the given filter. */
- findRealms(filter) {
- return Array.from(this.#realmMap.values()).filter((realm) => {
- if (filter.realmId !== undefined && filter.realmId !== realm.realmId) {
- return false;
- }
- if (filter.browsingContextId !== undefined &&
- filter.browsingContextId !== realm.browsingContextId) {
- return false;
- }
- if (filter.navigableId !== undefined &&
- filter.navigableId !== realm.navigableId) {
- return false;
- }
- if (filter.executionContextId !== undefined &&
- filter.executionContextId !== realm.executionContextId) {
- return false;
- }
- if (filter.origin !== undefined && filter.origin !== realm.origin) {
- return false;
- }
- if (filter.type !== undefined && filter.type !== realm.type) {
- return false;
- }
- if (filter.sandbox !== undefined && filter.sandbox !== realm.sandbox) {
- return false;
- }
- if (filter.cdpSessionId !== undefined &&
- filter.cdpSessionId !== realm.cdpSessionId) {
- return false;
- }
- return true;
- });
- }
- findRealm(filter) {
- const maybeRealms = this.findRealms(filter);
- if (maybeRealms.length !== 1) {
- return undefined;
- }
- return maybeRealms[0];
- }
- /** Gets the only realm that matches the given filter, if any, otherwise throws. */
- getRealm(filter) {
- const maybeRealm = this.findRealm(filter);
- if (maybeRealm === undefined) {
- throw new protocol_js_1.Message.NoSuchFrameException(`Realm ${JSON.stringify(filter)} not found`);
- }
- return maybeRealm;
- }
- /** Deletes all realms that match the given filter. */
- deleteRealms(filter) {
- this.findRealms(filter).map((realm) => {
- this.#realmMap.delete(realm.realmId);
- Array.from(this.#knownHandlesToRealm.entries())
- .filter(([, r]) => r === realm.realmId)
- .map(([handle]) => this.#knownHandlesToRealm.delete(handle));
- });
- }
-}
-realmStorage.RealmStorage = RealmStorage;
-
-/**
- * Copyright 2021 Google LLC.
- * 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.
- */
-Object.defineProperty(BidiServer$1, "__esModule", { value: true });
-BidiServer$1.BidiServer = void 0;
-const EventEmitter_js_1 = EventEmitter$2;
-const log_js_1 = log;
-const processingQueue_js_1 = processingQueue;
-const CommandProcessor_js_1 = CommandProcessor$1;
-const browsingContextStorage_js_1 = browsingContextStorage;
-const EventManager_js_1 = EventManager$1;
-const realmStorage_js_1 = realmStorage;
-class BidiServer extends EventEmitter_js_1.EventEmitter {
- #messageQueue;
- #transport;
- #commandProcessor;
- #browsingContextStorage;
- #realmStorage;
- #logger;
- #handleIncomingMessage = (message) => {
- void this.#commandProcessor.processCommand(message).catch((error) => {
- this.#logger?.(log_js_1.LogType.system, error);
- });
- };
- #processOutgoingMessage = async (messageEntry) => {
- const message = messageEntry.message;
- if (messageEntry.channel !== null) {
- message['channel'] = messageEntry.channel;
- }
- await this.#transport.sendMessage(message);
- };
- constructor(bidiTransport, cdpConnection, selfTargetId, parser, logger) {
- super();
- this.#logger = logger;
- this.#browsingContextStorage = new browsingContextStorage_js_1.BrowsingContextStorage();
- this.#realmStorage = new realmStorage_js_1.RealmStorage();
- this.#messageQueue = new processingQueue_js_1.ProcessingQueue(this.#processOutgoingMessage, this.#logger);
- this.#transport = bidiTransport;
- this.#transport.setOnMessage(this.#handleIncomingMessage);
- this.#commandProcessor = new CommandProcessor_js_1.CommandProcessor(this.#realmStorage, cdpConnection, new EventManager_js_1.EventManager(this), selfTargetId, parser, this.#browsingContextStorage, this.#logger);
- this.#commandProcessor.on('response', (response) => {
- this.emitOutgoingMessage(response);
- });
- }
- static async createAndStart(bidiTransport, cdpConnection, selfTargetId, parser, logger) {
- const server = new BidiServer(bidiTransport, cdpConnection, selfTargetId, parser, logger);
- const cdpClient = cdpConnection.browserClient();
- // Needed to get events about new targets.
- await cdpClient.sendCommand('Target.setDiscoverTargets', { discover: true });
- // Needed to automatically attach to new targets.
- await cdpClient.sendCommand('Target.setAutoAttach', {
- autoAttach: true,
- waitForDebuggerOnStart: true,
- flatten: true,
- });
- await server.topLevelContextsLoaded();
- return server;
- }
- async topLevelContextsLoaded() {
- await Promise.all(this.#browsingContextStorage
- .getTopLevelContexts()
- .map((c) => c.awaitLoaded()));
- }
- /**
- * Sends BiDi message.
- */
- emitOutgoingMessage(messageEntry) {
- this.#messageQueue.add(messageEntry);
- }
- close() {
- this.#transport.close();
- }
- getBrowsingContextStorage() {
- return this.#browsingContextStorage;
- }
-}
-BidiServer$1.BidiServer = BidiServer;
-
-(function (exports) {
- /**
- * Copyright 2022 Google LLC.
- * 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.
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.EventEmitter = exports.BidiServer = void 0;
- var BidiServer_js_1 = BidiServer$1;
- Object.defineProperty(exports, "BidiServer", { enumerable: true, get: function () { return BidiServer_js_1.BidiServer; } });
- var EventEmitter_js_1 = EventEmitter$2;
- Object.defineProperty(exports, "EventEmitter", { enumerable: true, get: function () { return EventEmitter_js_1.EventEmitter; } });
-
-} (bidiMapper));
-
-var cdpConnection = {};
-
-var cdpClient = {};
-
-var hasRequiredCdpClient;
-
-function requireCdpClient () {
- if (hasRequiredCdpClient) return cdpClient;
- hasRequiredCdpClient = 1;
- /**
- * Copyright 2021 Google LLC.
- * 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.
- */
- Object.defineProperty(cdpClient, "__esModule", { value: true });
- cdpClient.CdpClient = void 0;
- const EventEmitter_js_1 = EventEmitter$2;
- const cdpConnection_js_1 = requireCdpConnection();
- class CdpClient extends EventEmitter_js_1.EventEmitter {
- #cdpConnection;
- #sessionId;
- constructor(cdpConnection, sessionId) {
- super();
- this.#cdpConnection = cdpConnection;
- this.#sessionId = sessionId;
- }
- /**
- * Creates a new CDP client object that communicates with the browser using a
- * given transport mechanism.
- * @param transport A transport object that will be used to send and receive raw CDP messages.
- * @return A connected CDP client object.
- */
- static create(cdpConnection, sessionId) {
- return new CdpClient(cdpConnection, sessionId);
- }
- /**
- * Returns a command promise, which will be resolved with the command result
- * after receiving the result from CDP.
- * @param method Name of the CDP command to call.
- * @param params Parameters to pass to the CDP command.
- */
- sendCommand(method, ...params) {
- const param = params[0];
- return this.#cdpConnection.sendCommand(method, param, this.#sessionId);
- }
- isCloseError(error) {
- return error instanceof cdpConnection_js_1.CloseError;
- }
- }
- cdpClient.CdpClient = CdpClient;
-
- return cdpClient;
-}
-
-var hasRequiredCdpConnection;
-
-function requireCdpConnection () {
- if (hasRequiredCdpConnection) return cdpConnection;
- hasRequiredCdpConnection = 1;
- Object.defineProperty(cdpConnection, "__esModule", { value: true });
- cdpConnection.CdpConnection = cdpConnection.CloseError = void 0;
- const cdpClient_js_1 = requireCdpClient();
- /** A error that will be thrown if/when the connection is closed. */
- class CloseError extends Error {
- }
- cdpConnection.CloseError = CloseError;
- /**
- * Represents a high-level CDP connection to the browser backend.
- * Manages a CdpClient instance for each active CDP session.
- */
- class CdpConnection {
- #transport;
- #browserCdpClient;
- /** Map from session ID to CdpClient. */
- #sessionCdpClients = new Map();
- #commandCallbacks = new Map();
- #logger;
- #nextId = 0;
- constructor(transport, logger) {
- this.#transport = transport;
- this.#logger = logger;
- this.#transport.setOnMessage(this.#onMessage);
- this.#browserCdpClient = cdpClient_js_1.CdpClient.create(this, null);
- }
- /**
- * Closes the connection to the browser.
- */
- close() {
- this.#transport.close();
- for (const [, { reject, error }] of this.#commandCallbacks) {
- reject(error);
- }
- this.#commandCallbacks.clear();
- this.#sessionCdpClients.clear();
- }
- /**
- * @return The CdpClient object attached to the root browser session.
- */
- browserClient() {
- return this.#browserCdpClient;
- }
- /**
- * Gets a CdpClient instance by sessionId.
- * @param sessionId The sessionId of the CdpClient to retrieve.
- * @return The CdpClient object attached to the given session, or null if the session is not attached.
- */
- getCdpClient(sessionId) {
- const cdpClient = this.#sessionCdpClients.get(sessionId);
- if (!cdpClient) {
- throw new Error('Unknown CDP session ID');
- }
- return cdpClient;
- }
- sendCommand(method, params, sessionId) {
- return new Promise((resolve, reject) => {
- const id = this.#nextId++;
- this.#commandCallbacks.set(id, {
- resolve,
- reject,
- error: new CloseError(`${method} ${JSON.stringify(params)} ${sessionId ?? ''} call rejected because the connection has been closed.`),
- });
- const messageObj = { id, method, params };
- if (sessionId) {
- messageObj.sessionId = sessionId;
- }
- const messageStr = JSON.stringify(messageObj);
- const messagePretty = JSON.stringify(messageObj, null, 2);
- void this.#transport.sendMessage(messageStr)?.catch((error) => {
- this.#logger?.('error', error);
- this.#transport.close();
- });
- this.#logger?.('sent ▸', messagePretty);
- });
- }
- #onMessage = (message) => {
- const parsed = JSON.parse(message);
- const messagePretty = JSON.stringify(parsed, null, 2);
- this.#logger?.('received ◂', messagePretty);
- // Update client map if a session is attached or detached.
- // Listen for these events on every session.
- if (parsed.method === 'Target.attachedToTarget') {
- const { sessionId } = parsed.params;
- this.#sessionCdpClients.set(sessionId, cdpClient_js_1.CdpClient.create(this, sessionId));
- }
- else if (parsed.method === 'Target.detachedFromTarget') {
- const { sessionId } = parsed.params;
- const client = this.#sessionCdpClients.get(sessionId);
- if (client) {
- this.#sessionCdpClients.delete(sessionId);
- }
- }
- if (parsed.id !== undefined) {
- // Handle command response.
- const callbacks = this.#commandCallbacks.get(parsed.id);
- this.#commandCallbacks.delete(parsed.id);
- if (callbacks) {
- if (parsed.result) {
- callbacks.resolve(parsed.result);
- }
- else if (parsed.error) {
- callbacks.reject(parsed.error);
- }
- }
- }
- else if (parsed.method) {
- const client = parsed.sessionId
- ? this.#sessionCdpClients.get(parsed.sessionId)
- : this.#browserCdpClient;
- if (client) {
- client.emit(parsed.method, parsed.params || {});
- }
- }
- };
- }
- cdpConnection.CdpConnection = CdpConnection;
-
- return cdpConnection;
-}
-
var hasRequiredBidiOverCdp;
function requireBidiOverCdp () {
@@ -154716,8 +149053,8 @@ function requireBidiOverCdp () {
value: true
});
bidiOverCdp.connectBidiOverCdp = connectBidiOverCdp;
- var bidiMapper$1 = _interopRequireWildcard(bidiMapper);
- var bidiCdpConnection = _interopRequireWildcard(requireCdpConnection());
+ var bidiMapper = _interopRequireWildcard(require$$0$j);
+ var bidiCdpConnection = _interopRequireWildcard(require$$1$7);
var _debugLogger = debugLogger;
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -154754,7 +149091,7 @@ function requireBidiOverCdp () {
var _bidiConnection$onclo;
return (_bidiConnection$onclo = bidiConnection.onclose) === null || _bidiConnection$onclo === void 0 ? void 0 : _bidiConnection$onclo.call(bidiConnection);
};
- server = await bidiMapper$1.BidiServer.createAndStart(bidiTransport, cdpConnection, await cdpConnection.createBrowserSession(), /* selfTargetId= */'', undefined, bidiServerLogger);
+ server = await bidiMapper.BidiServer.createAndStart(bidiTransport, cdpConnection, await cdpConnection.createBrowserSession(), /* selfTargetId= */'', undefined, bidiServerLogger);
return bidiConnection;
}
class BidiTransportImpl {
@@ -169571,7 +163908,7 @@ class PlaywrightPage {
}
wait(param) {
return __awaiter$3(this, void 0, void 0, function* () {
- const p = deferred$1();
+ const p = deferred();
if (param === 'idle') {
yield this.page.waitForNavigation({ waitUntil: 'networkidle' });
p.resolve();
@@ -169604,7 +163941,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
class PlaywrightController {
constructor(configs, logger) {
this.getBrowserContext = () => __awaiter$2(this, void 0, void 0, function* () {
- const p = deferred$1();
+ const p = deferred();
if (this.context) {
p.resolve(this.context);
}
@@ -186774,7 +181111,7 @@ class LottoService {
return page.getCookies();
});
this.signIn = (id, password) => __awaiter(this, void 0, void 0, function* () {
- const p = deferred$1();
+ const p = deferred();
queueMicrotask(() => __awaiter(this, void 0, void 0, function* () {
// 페이지 이동
const page = yield this.browserController.focus(0);
@@ -187059,7 +181396,7 @@ exports.BrowserContext = BrowserContext$1;
exports.CallbackRegistry = CallbackRegistry;
exports.ConsoleMessage = ConsoleMessage$1;
exports.ElementHandle = ElementHandle$1;
-exports.EventEmitter = EventEmitter$6;
+exports.EventEmitter = EventEmitter$4;
exports.Frame = Frame$1;
exports.FrameManagerEmittedEvents = FrameManagerEmittedEvents;
exports.FrameTree = FrameTree;
@@ -187073,8 +181410,7 @@ exports.PuppeteerURL = PuppeteerURL;
exports.TargetCloseError = TargetCloseError;
exports.TimeoutError = TimeoutError$3;
exports.TimeoutSettings = TimeoutSettings$1;
-exports.assert = assert$5;
-exports.bidiMapper = bidiMapper;
+exports.assert = assert$3;
exports.createDeferred = createDeferred;
exports.debug = debug$e;
exports.debugError = debugError;
diff --git a/package.json b/package.json
index 4bb7b3b..9919291 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "lotto-archive",
"type": "module",
- "version": "0.0.1",
+ "version": "1.0.0",
"main": "dist/index.js",
"author": "bang9 ",
"license": "MIT",