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",