//# sourceURL=__InjectedScript_WebAutomationSessionProxy.js (function (sessionIdentifier, evaluate, createUUID, isValidNodeIdentifier) { const sessionNodePropertyName = "session-node-" + sessionIdentifier; let AutomationSessionProxy = class AutomationSessionProxy { constructor() { this._nodeToIdMap = new Map(); this._idToNodeMap = new Map(); } evaluateJavaScriptFunction( functionString, argumentStrings, expectsImplicitCallbackArgument, forceUserGesture, frameID, callbackID, resultCallback, callbackTimeout, ) { this._execute( functionString, argumentStrings, expectsImplicitCallbackArgument, callbackTimeout, ) .then((result) => { resultCallback(frameID, callbackID, this._jsonStringify(result)); }) .catch((error) => { resultCallback(frameID, callbackID, error); }); } evaluateBidiScript( expression, awaitPromise, maxObjectDepth, frameID, callbackID, resultCallback, callbackTimeout, ) { this._executeBidiScript( expression, awaitPromise, maxObjectDepth, callbackTimeout, ) .then((result) => { resultCallback(frameID, callbackID, JSON.stringify(result)); }) .catch((error) => { resultCallback(frameID, callbackID, error); }); } nodeForIdentifier(identifier) { this._clearStaleNodes(); try { return this._nodeForIdentifier(identifier); } catch (error) { return null; } } _execute( functionString, argumentStrings, expectsImplicitCallbackArgument, callbackTimeout, ) { let timeoutPromise; let timeoutIdentifier = 0; if (callbackTimeout >= 0) { timeoutPromise = new Promise((resolve, reject) => { timeoutIdentifier = setTimeout(() => { reject({ name: "JavaScriptTimeout", message: `script timed out after ${callbackTimeout}ms`, }); }, callbackTimeout); }); } let promise = new Promise((resolve, reject) => { let lines = functionString.split("\n"); let prefixLines = []; while (lines && lines[0].startsWith("//")) { prefixLines.push(lines.shift()); } functionString = lines.join("\n"); let prefix = prefixLines.join("\n"); if (prefix) prefix += "\n"; let functionValue = evaluate(prefix + "(async " + functionString + ")"); if (typeof functionValue !== "function") reject(new TypeError("Script did not evaluate to a function.")); this._clearStaleNodes(); let argumentValues = argumentStrings.map(this._jsonParse, this); if (expectsImplicitCallbackArgument) argumentValues.push(resolve); let resultPromise = functionValue.apply(null, argumentValues); let promises = [resultPromise]; if (timeoutPromise) promises.push(timeoutPromise); Promise.race(promises) .then((result) => { if (!expectsImplicitCallbackArgument) { resolve(result); } }) .catch((error) => { reject(error); }); }); let promises = [promise]; if (timeoutPromise) promises.push(timeoutPromise); return Promise.race(promises).finally(() => { if (timeoutIdentifier) { clearTimeout(timeoutIdentifier); } }); } _executeBidiScript( expression, awaitPromise, maxObjectDepth, callbackTimeout, ) { let timeoutPromise; let timeoutIdentifier = 0; if (callbackTimeout >= 0) { timeoutPromise = new Promise((resolve, reject) => { timeoutIdentifier = setTimeout(() => { reject({ name: "JavaScriptTimeout", message: `script timed out after ${callbackTimeout}ms`, }); }, callbackTimeout); }); } let promise = new Promise((resolve, reject) => { try { let result = globalThis.eval(expression); if (awaitPromise && result && typeof result.then === "function") { result.then( (value) => { let serializedValue = this.serializeBidiRemoteValue( value, maxObjectDepth, ); resolve({ success: true, result: serializedValue }); }, (error) => { reject({ success: false, error: { name: error.name, message: error.message, stack: error.stack, }, }); }, ); } else { let serializedValue = this.serializeBidiRemoteValue( result, maxObjectDepth, ); resolve({ success: true, result: serializedValue }); } } catch (error) { reject({ success: false, error: { name: error.name, message: error.message, stack: error.stack, }, }); } }); let promises = [promise]; if (timeoutPromise) promises.push(timeoutPromise); return Promise.race(promises).finally(() => { if (timeoutIdentifier) { clearTimeout(timeoutIdentifier); } }); } _jsonParse(string) { if (!string) return undefined; return JSON.parse(string, (key, value) => this._reviveJSONValue(key, value), ); } _jsonStringify(value) { return JSON.stringify(this._jsonClone(value)); } _reviveJSONValue(key, value) { if (value && typeof value === "object" && value[sessionNodePropertyName]) return this._nodeForIdentifier(value[sessionNodePropertyName]); return value; } _isCollection(value) { switch (Object.prototype.toString.call(value)) { case "[object Arguments]": case "[object Array]": case "[object FileList]": case "[object HTMLAllCollection]": case "[object HTMLCollection]": case "[object HTMLFormControlsCollection]": case "[object HTMLOptionsCollection]": case "[object NodeList]": return true; } return false; } _checkCyclic(value, stack = []) { function isCyclic(value, proxy, stack = []) { if (value === undefined || value === null) return false; if ( typeof value === "boolean" || typeof value === "number" || typeof value === "string" ) return false; if (value instanceof Node) return false; if (stack.includes(value)) return true; if (proxy._isCollection(value)) { stack.push(value); for (let i = 0; i < value.length; i++) { if (isCyclic(value[i], proxy, stack)) return true; } stack.pop(); return false; } stack.push(value); for (let property in value) { if (isCyclic(value[property], proxy, stack)) return true; } stack.pop(); return false; } if (isCyclic(value, this)) throw new TypeError("cannot serialize cyclic structures."); } _jsonClone(value) { if (value === undefined || value === null) return null; if ( typeof value === "boolean" || typeof value === "number" || typeof value === "string" ) return value; if (this._isCollection(value)) { this._checkCyclic(value); return [...value].map((item) => this._jsonClone(item)); } if (value instanceof Node) return this._createNodeHandle(value); if (typeof value.toJSON === "function") return value.toJSON(); let customObject = {}; for (let property in value) { this._checkCyclic(value); customObject[property] = this._jsonClone(value[property]); } return customObject; } _createNodeHandle(node) { if (node.ownerDocument !== window.document || !node.isConnected) throw { name: "NodeNotFound", message: "Stale element found when trying to create the node handle", }; return { [sessionNodePropertyName]: this._identifierForNode(node) }; } _nodeForIdentifier(identifier) { if (!isValidNodeIdentifier(identifier)) throw { name: "InvalidNodeIdentifier", message: "Node identifier '" + identifier + "' is invalid", }; let node = this._idToNodeMap.get(identifier); if (node) return node; throw { name: "NodeNotFound", message: "Node with identifier '" + identifier + "' was not found", }; } _identifierForNode(node) { let identifier = this._nodeToIdMap.get(node); if (identifier) return identifier; identifier = "node-" + createUUID(); this._nodeToIdMap.set(node, identifier); this._idToNodeMap.set(identifier, node); return identifier; } _clearStaleNodes() { for (var [node, identifier] of this._nodeToIdMap) { const rootNode = node.getRootNode({ composed: true }); if (rootNode !== document) { this._nodeToIdMap.delete(node); this._idToNodeMap.delete(identifier); } } } serializeBidiRemoteValue( value, maxObjectDepth = 1, depth = 0, visitedObjects = new Set(), ) { if (value === null) return { type: "null" }; if (value === undefined) return { type: "undefined" }; if (typeof value === "boolean") return { type: "boolean", value: value }; if (typeof value === "string") return { type: "string", value: value }; if (typeof value === "number") { if (isNaN(value)) return { type: "number", value: "NaN" }; if (value === Infinity) return { type: "number", value: "Infinity" }; if (value === -Infinity) return { type: "number", value: "-Infinity" }; if (Object.is(value, -0)) return { type: "number", value: "-0" }; return { type: "number", value: value }; } if (typeof value === "bigint") return { type: "bigint", value: value.toString() }; if (typeof value === "symbol") return { type: "symbol" }; if (typeof value === "function") return { type: "function" }; if (typeof value === "object" || typeof value === "function") { if (value === window) return { type: "window", value: { context: "context-id-placeholder" }, }; if (value instanceof Date) return { type: "date", value: value.toISOString() }; if (value instanceof RegExp) return { type: "regexp", value: { pattern: value.source, flags: value.flags }, }; if (value instanceof Error) return { type: "error" }; if (value instanceof Promise) return { type: "promise" }; if (value instanceof Map) { let entries = []; for (let [k, v] of value.entries()) { entries.push({ key: this.serializeBidiRemoteValue( k, maxObjectDepth, depth + 1, visitedObjects, ), value: this.serializeBidiRemoteValue( v, maxObjectDepth, depth + 1, visitedObjects, ), }); } return { type: "map", value: entries }; } if (value instanceof Set) { let items = []; for (let v of value.values()) items.push( this.serializeBidiRemoteValue( v, maxObjectDepth, depth + 1, visitedObjects, ), ); return { type: "set", value: items }; } if (value instanceof WeakMap) return { type: "weakmap" }; if (value instanceof WeakSet) return { type: "weakset" }; if (value instanceof ArrayBuffer) return { type: "arraybuffer" }; if (ArrayBuffer.isView(value)) return { type: "typedarray" }; if (visitedObjects.has(value)) return { type: "object", value: {} }; if (depth >= maxObjectDepth) return { type: "object", value: {} }; visitedObjects.add(value); try { if (Array.isArray(value)) { let serializedArray = []; for (let i = 0; i < value.length; i++) { serializedArray[i] = this.serializeBidiRemoteValue( value[i], maxObjectDepth, depth + 1, visitedObjects, ); } return { type: "array", value: serializedArray }; } else { let serializedObject = {}; let keys = Object.keys(value).sort(); for (let i = 0; i < keys.length; ++i) { let key = keys[i]; serializedObject[key] = this.serializeBidiRemoteValue( value[key], maxObjectDepth, depth + 1, visitedObjects, ); } return { type: "object", value: serializedObject }; } } finally { visitedObjects.delete(value); } } return { type: "undefined" }; } }; return new AutomationSessionProxy(); });