feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP
This MVP release provides a complete full-stack solution for managing action mappings in Geutebruck's GeViScope and GeViSoft video surveillance systems. ## Features ### Flutter Web Application (Port 8081) - Modern, responsive UI for managing action mappings - Action picker dialog with full parameter configuration - Support for both GSC (GeViScope) and G-Core server actions - Consistent UI for input and output actions with edit/delete capabilities - Real-time action mapping creation, editing, and deletion - Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers) ### FastAPI REST Backend (Port 8000) - RESTful API for action mapping CRUD operations - Action template service with comprehensive action catalog (247 actions) - Server management (G-Core and GeViScope servers) - Configuration tree reading and writing - JWT authentication with role-based access control - PostgreSQL database integration ### C# SDK Bridge (gRPC, Port 50051) - Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll) - Action mapping creation with correct binary format - Support for GSC and G-Core action types - Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug) - Action ID lookup table with server-specific action IDs - Configuration reading/writing via SetupClient ## Bug Fixes - **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet - Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)` - Proper filter flags and VideoInput=0 for action mappings - Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft) ## Technical Stack - **Frontend**: Flutter Web, Dart, Dio HTTP client - **Backend**: Python FastAPI, PostgreSQL, Redis - **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK - **Authentication**: JWT tokens - **Configuration**: GeViSoft .set files (binary format) ## Credentials - GeViSoft/GeViScope: username=sysadmin, password=masterkey - Default admin: username=admin, password=admin123 ## Deployment All services run on localhost: - Flutter Web: http://localhost:8081 - FastAPI: http://localhost:8000 - SDK Bridge gRPC: localhost:50051 - GeViServer: localhost (default port) Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
465
.playwright-mcp/node_modules/playwright-core/lib/server/android/android.js
generated
vendored
Normal file
465
.playwright-mcp/node_modules/playwright-core/lib/server/android/android.js
generated
vendored
Normal file
@@ -0,0 +1,465 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var android_exports = {};
|
||||
__export(android_exports, {
|
||||
Android: () => Android,
|
||||
AndroidDevice: () => AndroidDevice
|
||||
});
|
||||
module.exports = __toCommonJS(android_exports);
|
||||
var import_events = require("events");
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_pipeTransport = require("../utils/pipeTransport");
|
||||
var import_crypto = require("../utils/crypto");
|
||||
var import_debug = require("../utils/debug");
|
||||
var import_env = require("../utils/env");
|
||||
var import_task = require("../utils/task");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
var import_utilsBundle2 = require("../../utilsBundle");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_chromiumSwitches = require("../chromium/chromiumSwitches");
|
||||
var import_crBrowser = require("../chromium/crBrowser");
|
||||
var import_fileUtils = require("../utils/fileUtils");
|
||||
var import_helper = require("../helper");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var import_processLauncher = require("../utils/processLauncher");
|
||||
var import_progress = require("../progress");
|
||||
var import_registry = require("../registry");
|
||||
const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
|
||||
class Android extends import_instrumentation.SdkObject {
|
||||
constructor(parent, backend) {
|
||||
super(parent, "android");
|
||||
this._devices = /* @__PURE__ */ new Map();
|
||||
this._backend = backend;
|
||||
}
|
||||
async devices(progress, options) {
|
||||
const devices = (await progress.race(this._backend.devices(options))).filter((d) => d.status === "device");
|
||||
const newSerials = /* @__PURE__ */ new Set();
|
||||
for (const d of devices) {
|
||||
newSerials.add(d.serial);
|
||||
if (this._devices.has(d.serial))
|
||||
continue;
|
||||
await progress.race(AndroidDevice.create(this, d, options).then((device) => this._devices.set(d.serial, device)));
|
||||
}
|
||||
for (const d of this._devices.keys()) {
|
||||
if (!newSerials.has(d))
|
||||
this._devices.delete(d);
|
||||
}
|
||||
return [...this._devices.values()];
|
||||
}
|
||||
_deviceClosed(device) {
|
||||
this._devices.delete(device.serial);
|
||||
}
|
||||
}
|
||||
class AndroidDevice extends import_instrumentation.SdkObject {
|
||||
constructor(android, backend, model, options) {
|
||||
super(android, "android-device");
|
||||
this._lastId = 0;
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._webViews = /* @__PURE__ */ new Map();
|
||||
this._browserConnections = /* @__PURE__ */ new Set();
|
||||
this._isClosed = false;
|
||||
this._android = android;
|
||||
this._backend = backend;
|
||||
this.model = model;
|
||||
this.serial = backend.serial;
|
||||
this._options = options;
|
||||
this.logName = "browser";
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
WebViewAdded: "webViewAdded",
|
||||
WebViewRemoved: "webViewRemoved",
|
||||
Close: "close"
|
||||
};
|
||||
}
|
||||
static async create(android, backend, options) {
|
||||
await backend.init();
|
||||
const model = await backend.runCommand("shell:getprop ro.product.model");
|
||||
const device = new AndroidDevice(android, backend, model.toString().trim(), options);
|
||||
await device._init();
|
||||
return device;
|
||||
}
|
||||
async _init() {
|
||||
await this._refreshWebViews();
|
||||
const poll = () => {
|
||||
this._pollingWebViews = setTimeout(() => this._refreshWebViews().then(poll).catch(() => {
|
||||
this.close().catch(() => {
|
||||
});
|
||||
}), 500);
|
||||
};
|
||||
poll();
|
||||
}
|
||||
async shell(command) {
|
||||
const result = await this._backend.runCommand(`shell:${command}`);
|
||||
await this._refreshWebViews();
|
||||
return result;
|
||||
}
|
||||
async open(progress, command) {
|
||||
return await this._open(progress, command);
|
||||
}
|
||||
async screenshot() {
|
||||
return await this._backend.runCommand(`shell:screencap -p`);
|
||||
}
|
||||
async _driver() {
|
||||
if (this._isClosed)
|
||||
return;
|
||||
if (!this._driverPromise) {
|
||||
const controller = new import_progress.ProgressController();
|
||||
this._driverPromise = controller.run((progress) => this._installDriver(progress));
|
||||
}
|
||||
return this._driverPromise;
|
||||
}
|
||||
async _installDriver(progress) {
|
||||
(0, import_utilsBundle.debug)("pw:android")("Stopping the old driver");
|
||||
await progress.race(this.shell(`am force-stop com.microsoft.playwright.androiddriver`));
|
||||
if (!this._options.omitDriverInstall) {
|
||||
(0, import_utilsBundle.debug)("pw:android")("Uninstalling the old driver");
|
||||
await progress.race(this.shell(`cmd package uninstall com.microsoft.playwright.androiddriver`));
|
||||
await progress.race(this.shell(`cmd package uninstall com.microsoft.playwright.androiddriver.test`));
|
||||
(0, import_utilsBundle.debug)("pw:android")("Installing the new driver");
|
||||
const executable = import_registry.registry.findExecutable("android");
|
||||
const packageManagerCommand = (0, import_env.getPackageManagerExecCommand)();
|
||||
for (const file of ["android-driver.apk", "android-driver-target.apk"]) {
|
||||
const fullName = import_path.default.join(executable.directory, file);
|
||||
if (!import_fs.default.existsSync(fullName))
|
||||
throw new Error(`Please install Android driver apk using '${packageManagerCommand} playwright install android'`);
|
||||
await this.installApk(progress, await progress.race(import_fs.default.promises.readFile(fullName)));
|
||||
}
|
||||
} else {
|
||||
(0, import_utilsBundle.debug)("pw:android")("Skipping the driver installation");
|
||||
}
|
||||
(0, import_utilsBundle.debug)("pw:android")("Starting the new driver");
|
||||
this.shell("am instrument -w com.microsoft.playwright.androiddriver.test/androidx.test.runner.AndroidJUnitRunner").catch((e) => (0, import_utilsBundle.debug)("pw:android")(e));
|
||||
const socket = await this._waitForLocalAbstract(progress, "playwright_android_driver_socket");
|
||||
const transport = new import_pipeTransport.PipeTransport(socket, socket, socket, "be");
|
||||
transport.onmessage = (message) => {
|
||||
const response = JSON.parse(message);
|
||||
const { id, result, error } = response;
|
||||
const callback = this._callbacks.get(id);
|
||||
if (!callback)
|
||||
return;
|
||||
if (error)
|
||||
callback.reject(new Error(error));
|
||||
else
|
||||
callback.fulfill(result);
|
||||
this._callbacks.delete(id);
|
||||
};
|
||||
return transport;
|
||||
}
|
||||
async _waitForLocalAbstract(progress, socketName) {
|
||||
let socket;
|
||||
(0, import_utilsBundle.debug)("pw:android")(`Polling the socket localabstract:${socketName}`);
|
||||
while (!socket) {
|
||||
try {
|
||||
socket = await this._open(progress, `localabstract:${socketName}`);
|
||||
} catch (e) {
|
||||
if ((0, import_progress.isAbortError)(e))
|
||||
throw e;
|
||||
await progress.wait(250);
|
||||
}
|
||||
}
|
||||
(0, import_utilsBundle.debug)("pw:android")(`Connected to localabstract:${socketName}`);
|
||||
return socket;
|
||||
}
|
||||
async send(method, params = {}) {
|
||||
params = {
|
||||
...params,
|
||||
// Patch the timeout in, just in case it's missing in one of the commands.
|
||||
timeout: params.timeout || 0
|
||||
};
|
||||
if (params.androidSelector) {
|
||||
params.selector = params.androidSelector;
|
||||
delete params.androidSelector;
|
||||
}
|
||||
const driver = await this._driver();
|
||||
if (!driver)
|
||||
throw new Error("Device is closed");
|
||||
const id = ++this._lastId;
|
||||
const result = new Promise((fulfill, reject) => this._callbacks.set(id, { fulfill, reject }));
|
||||
driver.send(JSON.stringify({ id, method, params }));
|
||||
return result;
|
||||
}
|
||||
async close() {
|
||||
if (this._isClosed)
|
||||
return;
|
||||
this._isClosed = true;
|
||||
if (this._pollingWebViews)
|
||||
clearTimeout(this._pollingWebViews);
|
||||
for (const connection of this._browserConnections)
|
||||
await connection.close();
|
||||
if (this._driverPromise) {
|
||||
const driver = await this._driver();
|
||||
driver?.close();
|
||||
}
|
||||
await this._backend.close();
|
||||
this._android._deviceClosed(this);
|
||||
this.emit(AndroidDevice.Events.Close);
|
||||
}
|
||||
async launchBrowser(progress, pkg = "com.android.chrome", options) {
|
||||
(0, import_utilsBundle.debug)("pw:android")("Force-stopping", pkg);
|
||||
await this._backend.runCommand(`shell:am force-stop ${pkg}`);
|
||||
const socketName = (0, import_debug.isUnderTest)() ? "webview_devtools_remote_playwright_test" : "playwright_" + (0, import_crypto.createGuid)() + "_devtools_remote";
|
||||
const commandLine = this._defaultArgs(options, socketName).join(" ");
|
||||
(0, import_utilsBundle.debug)("pw:android")("Starting", pkg, commandLine);
|
||||
await progress.race(this._backend.runCommand(`shell:echo "${Buffer.from(commandLine).toString("base64")}" | base64 -d > /data/local/tmp/chrome-command-line`));
|
||||
await progress.race(this._backend.runCommand(`shell:am start -a android.intent.action.VIEW -d about:blank ${pkg}`));
|
||||
const browserContext = await this._connectToBrowser(progress, socketName, options);
|
||||
try {
|
||||
await progress.race(this._backend.runCommand(`shell:rm /data/local/tmp/chrome-command-line`));
|
||||
return browserContext;
|
||||
} catch (error) {
|
||||
await browserContext.close({ reason: "Failed to launch" }).catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
_defaultArgs(options, socketName) {
|
||||
const chromeArguments = [
|
||||
"_",
|
||||
"--disable-fre",
|
||||
"--no-default-browser-check",
|
||||
`--remote-debugging-socket-name=${socketName}`,
|
||||
...(0, import_chromiumSwitches.chromiumSwitches)(void 0, void 0, true),
|
||||
...this._innerDefaultArgs(options)
|
||||
];
|
||||
return chromeArguments;
|
||||
}
|
||||
_innerDefaultArgs(options) {
|
||||
const { args = [], proxy } = options;
|
||||
const chromeArguments = [];
|
||||
if (proxy) {
|
||||
chromeArguments.push(`--proxy-server=${proxy.server}`);
|
||||
const proxyBypassRules = [];
|
||||
if (proxy.bypass)
|
||||
proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
|
||||
if (!process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK && !proxyBypassRules.includes("<-loopback>"))
|
||||
proxyBypassRules.push("<-loopback>");
|
||||
if (proxyBypassRules.length > 0)
|
||||
chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(";")}`);
|
||||
}
|
||||
chromeArguments.push(...args);
|
||||
return chromeArguments;
|
||||
}
|
||||
async connectToWebView(progress, socketName) {
|
||||
const webView = this._webViews.get(socketName);
|
||||
if (!webView)
|
||||
throw new Error("WebView has been closed");
|
||||
return await this._connectToBrowser(progress, socketName);
|
||||
}
|
||||
async _connectToBrowser(progress, socketName, options = {}) {
|
||||
const socket = await this._waitForLocalAbstract(progress, socketName);
|
||||
try {
|
||||
const androidBrowser = new AndroidBrowser(this, socket);
|
||||
await progress.race(androidBrowser._init());
|
||||
this._browserConnections.add(androidBrowser);
|
||||
const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
|
||||
const cleanupArtifactsDir = async () => {
|
||||
const errors = (await (0, import_fileUtils.removeFolders)([artifactsDir])).filter(Boolean);
|
||||
for (let i = 0; i < (errors || []).length; ++i)
|
||||
(0, import_utilsBundle.debug)("pw:android")(`exception while removing ${artifactsDir}: ${errors[i]}`);
|
||||
};
|
||||
import_processLauncher.gracefullyCloseSet.add(cleanupArtifactsDir);
|
||||
socket.on("close", async () => {
|
||||
import_processLauncher.gracefullyCloseSet.delete(cleanupArtifactsDir);
|
||||
cleanupArtifactsDir().catch((e) => (0, import_utilsBundle.debug)("pw:android")(`could not cleanup artifacts dir: ${e}`));
|
||||
});
|
||||
const browserOptions = {
|
||||
name: "clank",
|
||||
isChromium: true,
|
||||
slowMo: 0,
|
||||
persistent: { ...options, noDefaultViewport: true },
|
||||
artifactsDir,
|
||||
downloadsPath: artifactsDir,
|
||||
tracesDir: artifactsDir,
|
||||
browserProcess: new ClankBrowserProcess(androidBrowser),
|
||||
proxy: options.proxy,
|
||||
protocolLogger: import_helper.helper.debugProtocolLogger(),
|
||||
browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
|
||||
originalLaunchOptions: {}
|
||||
};
|
||||
(0, import_browserContext.validateBrowserContextOptions)(options, browserOptions);
|
||||
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, androidBrowser, browserOptions));
|
||||
const defaultContext = browser._defaultContext;
|
||||
await defaultContext._loadDefaultContextAsIs(progress);
|
||||
return defaultContext;
|
||||
} catch (error) {
|
||||
socket.close();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
_open(progress, command) {
|
||||
return (0, import_progress.raceUncancellableOperationWithCleanup)(progress, () => this._backend.open(command), (socket) => socket.close());
|
||||
}
|
||||
webViews() {
|
||||
return [...this._webViews.values()];
|
||||
}
|
||||
async installApk(progress, content, options) {
|
||||
const args = options && options.args ? options.args : ["-r", "-t", "-S"];
|
||||
(0, import_utilsBundle.debug)("pw:android")("Opening install socket");
|
||||
const installSocket = await this._open(progress, `shell:cmd package install ${args.join(" ")} ${content.length}`);
|
||||
(0, import_utilsBundle.debug)("pw:android")("Writing driver bytes: " + content.length);
|
||||
await progress.race(installSocket.write(content));
|
||||
const success = await progress.race(new Promise((f) => installSocket.on("data", f)));
|
||||
(0, import_utilsBundle.debug)("pw:android")("Written driver bytes: " + success);
|
||||
installSocket.close();
|
||||
}
|
||||
async push(progress, content, path2, mode = 420) {
|
||||
const socket = await this._open(progress, `sync:`);
|
||||
const sendHeader = async (command, length) => {
|
||||
const buffer = Buffer.alloc(command.length + 4);
|
||||
buffer.write(command, 0);
|
||||
buffer.writeUInt32LE(length, command.length);
|
||||
await progress.race(socket.write(buffer));
|
||||
};
|
||||
const send = async (command, data) => {
|
||||
await sendHeader(command, data.length);
|
||||
await progress.race(socket.write(data));
|
||||
};
|
||||
await send("SEND", Buffer.from(`${path2},${mode}`));
|
||||
const maxChunk = 65535;
|
||||
for (let i = 0; i < content.length; i += maxChunk)
|
||||
await send("DATA", content.slice(i, i + maxChunk));
|
||||
await sendHeader("DONE", Date.now() / 1e3 | 0);
|
||||
const result = await progress.race(new Promise((f) => socket.once("data", f)));
|
||||
const code = result.slice(0, 4).toString();
|
||||
if (code !== "OKAY")
|
||||
throw new Error("Could not push: " + code);
|
||||
socket.close();
|
||||
}
|
||||
async _refreshWebViews() {
|
||||
const sockets = (await this._backend.runCommand(`shell:cat /proc/net/unix | grep webview_devtools_remote`)).toString().split("\n");
|
||||
if (this._isClosed)
|
||||
return;
|
||||
const socketNames = /* @__PURE__ */ new Set();
|
||||
for (const line of sockets) {
|
||||
const matchSocketName = line.match(/[^@]+@(.*?webview_devtools_remote_?.*)/);
|
||||
if (!matchSocketName)
|
||||
continue;
|
||||
const socketName = matchSocketName[1];
|
||||
socketNames.add(socketName);
|
||||
if (this._webViews.has(socketName))
|
||||
continue;
|
||||
const match = line.match(/[^@]+@.*?webview_devtools_remote_?(\d*)/);
|
||||
let pid = -1;
|
||||
if (match && match[1])
|
||||
pid = +match[1];
|
||||
const pkg = await this._extractPkg(pid);
|
||||
if (this._isClosed)
|
||||
return;
|
||||
const webView = { pid, pkg, socketName };
|
||||
this._webViews.set(socketName, webView);
|
||||
this.emit(AndroidDevice.Events.WebViewAdded, webView);
|
||||
}
|
||||
for (const p of this._webViews.keys()) {
|
||||
if (!socketNames.has(p)) {
|
||||
this._webViews.delete(p);
|
||||
this.emit(AndroidDevice.Events.WebViewRemoved, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
async _extractPkg(pid) {
|
||||
let pkg = "";
|
||||
if (pid === -1)
|
||||
return pkg;
|
||||
const procs = (await this._backend.runCommand(`shell:ps -A | grep ${pid}`)).toString().split("\n");
|
||||
for (const proc of procs) {
|
||||
const match = proc.match(/[^\s]+\s+(\d+).*$/);
|
||||
if (!match)
|
||||
continue;
|
||||
pkg = proc.substring(proc.lastIndexOf(" ") + 1);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
}
|
||||
class AndroidBrowser extends import_events.EventEmitter {
|
||||
constructor(device, socket) {
|
||||
super();
|
||||
this._waitForNextTask = (0, import_task.makeWaitForNextTask)();
|
||||
this.setMaxListeners(0);
|
||||
this.device = device;
|
||||
this._socket = socket;
|
||||
this._socket.on("close", () => {
|
||||
this._waitForNextTask(() => {
|
||||
if (this.onclose)
|
||||
this.onclose();
|
||||
});
|
||||
});
|
||||
this._receiver = new import_utilsBundle2.wsReceiver();
|
||||
this._receiver.on("message", (message) => {
|
||||
this._waitForNextTask(() => {
|
||||
if (this.onmessage)
|
||||
this.onmessage(JSON.parse(message));
|
||||
});
|
||||
});
|
||||
}
|
||||
async _init() {
|
||||
await this._socket.write(Buffer.from(`GET /devtools/browser HTTP/1.1\r
|
||||
Upgrade: WebSocket\r
|
||||
Connection: Upgrade\r
|
||||
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
|
||||
Sec-WebSocket-Version: 13\r
|
||||
\r
|
||||
`));
|
||||
await new Promise((f) => this._socket.once("data", f));
|
||||
this._socket.on("data", (data) => this._receiver._write(data, "binary", () => {
|
||||
}));
|
||||
}
|
||||
async send(s) {
|
||||
await this._socket.write(encodeWebFrame(JSON.stringify(s)));
|
||||
}
|
||||
async close() {
|
||||
this._socket.close();
|
||||
}
|
||||
}
|
||||
function encodeWebFrame(data) {
|
||||
return import_utilsBundle2.wsSender.frame(Buffer.from(data), {
|
||||
opcode: 1,
|
||||
mask: true,
|
||||
fin: true,
|
||||
readOnly: true
|
||||
})[0];
|
||||
}
|
||||
class ClankBrowserProcess {
|
||||
constructor(browser) {
|
||||
this._browser = browser;
|
||||
}
|
||||
async kill() {
|
||||
}
|
||||
async close() {
|
||||
await this._browser.close();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Android,
|
||||
AndroidDevice
|
||||
});
|
||||
177
.playwright-mcp/node_modules/playwright-core/lib/server/android/backendAdb.js
generated
vendored
Normal file
177
.playwright-mcp/node_modules/playwright-core/lib/server/android/backendAdb.js
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var backendAdb_exports = {};
|
||||
__export(backendAdb_exports, {
|
||||
AdbBackend: () => AdbBackend
|
||||
});
|
||||
module.exports = __toCommonJS(backendAdb_exports);
|
||||
var import_events = require("events");
|
||||
var import_net = __toESM(require("net"));
|
||||
var import_assert = require("../../utils/isomorphic/assert");
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
class AdbBackend {
|
||||
async devices(options = {}) {
|
||||
const result = await runCommand("host:devices", options.host, options.port);
|
||||
const lines = result.toString().trim().split("\n");
|
||||
return lines.map((line) => {
|
||||
const [serial, status] = line.trim().split(" ");
|
||||
return new AdbDevice(serial, status, options.host, options.port);
|
||||
});
|
||||
}
|
||||
}
|
||||
class AdbDevice {
|
||||
constructor(serial, status, host, port) {
|
||||
this._closed = false;
|
||||
this.serial = serial;
|
||||
this.status = status;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
async init() {
|
||||
}
|
||||
async close() {
|
||||
this._closed = true;
|
||||
}
|
||||
runCommand(command) {
|
||||
if (this._closed)
|
||||
throw new Error("Device is closed");
|
||||
return runCommand(command, this.host, this.port, this.serial);
|
||||
}
|
||||
async open(command) {
|
||||
if (this._closed)
|
||||
throw new Error("Device is closed");
|
||||
const result = await open(command, this.host, this.port, this.serial);
|
||||
result.becomeSocket();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
async function runCommand(command, host = "127.0.0.1", port = 5037, serial) {
|
||||
(0, import_utilsBundle.debug)("pw:adb:runCommand")(command, serial);
|
||||
const socket = new BufferedSocketWrapper(command, import_net.default.createConnection({ host, port }));
|
||||
try {
|
||||
if (serial) {
|
||||
await socket.write(encodeMessage(`host:transport:${serial}`));
|
||||
const status2 = await socket.read(4);
|
||||
(0, import_assert.assert)(status2.toString() === "OKAY", status2.toString());
|
||||
}
|
||||
await socket.write(encodeMessage(command));
|
||||
const status = await socket.read(4);
|
||||
(0, import_assert.assert)(status.toString() === "OKAY", status.toString());
|
||||
let commandOutput;
|
||||
if (!command.startsWith("shell:")) {
|
||||
const remainingLength = parseInt((await socket.read(4)).toString(), 16);
|
||||
commandOutput = await socket.read(remainingLength);
|
||||
} else {
|
||||
commandOutput = await socket.readAll();
|
||||
}
|
||||
return commandOutput;
|
||||
} finally {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
async function open(command, host = "127.0.0.1", port = 5037, serial) {
|
||||
const socket = new BufferedSocketWrapper(command, import_net.default.createConnection({ host, port }));
|
||||
if (serial) {
|
||||
await socket.write(encodeMessage(`host:transport:${serial}`));
|
||||
const status2 = await socket.read(4);
|
||||
(0, import_assert.assert)(status2.toString() === "OKAY", status2.toString());
|
||||
}
|
||||
await socket.write(encodeMessage(command));
|
||||
const status = await socket.read(4);
|
||||
(0, import_assert.assert)(status.toString() === "OKAY", status.toString());
|
||||
return socket;
|
||||
}
|
||||
function encodeMessage(message) {
|
||||
let lenHex = message.length.toString(16);
|
||||
lenHex = "0".repeat(4 - lenHex.length) + lenHex;
|
||||
return Buffer.from(lenHex + message);
|
||||
}
|
||||
class BufferedSocketWrapper extends import_events.EventEmitter {
|
||||
constructor(command, socket) {
|
||||
super();
|
||||
this._buffer = Buffer.from([]);
|
||||
this._isSocket = false;
|
||||
this._isClosed = false;
|
||||
this._command = command;
|
||||
this._socket = socket;
|
||||
this._connectPromise = new Promise((f) => this._socket.on("connect", f));
|
||||
this._socket.on("data", (data) => {
|
||||
(0, import_utilsBundle.debug)("pw:adb:data")(data.toString());
|
||||
if (this._isSocket) {
|
||||
this.emit("data", data);
|
||||
return;
|
||||
}
|
||||
this._buffer = Buffer.concat([this._buffer, data]);
|
||||
if (this._notifyReader)
|
||||
this._notifyReader();
|
||||
});
|
||||
this._socket.on("close", () => {
|
||||
this._isClosed = true;
|
||||
if (this._notifyReader)
|
||||
this._notifyReader();
|
||||
this.close();
|
||||
this.emit("close");
|
||||
});
|
||||
this._socket.on("error", (error) => this.emit("error", error));
|
||||
}
|
||||
async write(data) {
|
||||
(0, import_utilsBundle.debug)("pw:adb:send")(data.toString().substring(0, 100) + "...");
|
||||
await this._connectPromise;
|
||||
await new Promise((f) => this._socket.write(data, f));
|
||||
}
|
||||
close() {
|
||||
if (this._isClosed)
|
||||
return;
|
||||
(0, import_utilsBundle.debug)("pw:adb")("Close " + this._command);
|
||||
this._socket.destroy();
|
||||
}
|
||||
async read(length) {
|
||||
await this._connectPromise;
|
||||
(0, import_assert.assert)(!this._isSocket, "Can not read by length in socket mode");
|
||||
while (this._buffer.length < length)
|
||||
await new Promise((f) => this._notifyReader = f);
|
||||
const result = this._buffer.slice(0, length);
|
||||
this._buffer = this._buffer.slice(length);
|
||||
(0, import_utilsBundle.debug)("pw:adb:recv")(result.toString().substring(0, 100) + "...");
|
||||
return result;
|
||||
}
|
||||
async readAll() {
|
||||
while (!this._isClosed)
|
||||
await new Promise((f) => this._notifyReader = f);
|
||||
return this._buffer;
|
||||
}
|
||||
becomeSocket() {
|
||||
(0, import_assert.assert)(!this._buffer.length);
|
||||
this._isSocket = true;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
AdbBackend
|
||||
});
|
||||
127
.playwright-mcp/node_modules/playwright-core/lib/server/artifact.js
generated
vendored
Normal file
127
.playwright-mcp/node_modules/playwright-core/lib/server/artifact.js
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var artifact_exports = {};
|
||||
__export(artifact_exports, {
|
||||
Artifact: () => Artifact
|
||||
});
|
||||
module.exports = __toCommonJS(artifact_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_utils = require("../utils");
|
||||
var import_errors = require("./errors");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_manualPromise = require("../utils/isomorphic/manualPromise");
|
||||
class Artifact extends import_instrumentation.SdkObject {
|
||||
constructor(parent, localPath, unaccessibleErrorMessage, cancelCallback) {
|
||||
super(parent, "artifact");
|
||||
this._finishedPromise = new import_manualPromise.ManualPromise();
|
||||
this._saveCallbacks = [];
|
||||
this._finished = false;
|
||||
this._deleted = false;
|
||||
this._localPath = localPath;
|
||||
this._unaccessibleErrorMessage = unaccessibleErrorMessage;
|
||||
this._cancelCallback = cancelCallback;
|
||||
}
|
||||
finishedPromise() {
|
||||
return this._finishedPromise;
|
||||
}
|
||||
localPath() {
|
||||
return this._localPath;
|
||||
}
|
||||
async localPathAfterFinished() {
|
||||
if (this._unaccessibleErrorMessage)
|
||||
throw new Error(this._unaccessibleErrorMessage);
|
||||
await this._finishedPromise;
|
||||
if (this._failureError)
|
||||
throw this._failureError;
|
||||
return this._localPath;
|
||||
}
|
||||
saveAs(saveCallback) {
|
||||
if (this._unaccessibleErrorMessage)
|
||||
throw new Error(this._unaccessibleErrorMessage);
|
||||
if (this._deleted)
|
||||
throw new Error(`File already deleted. Save before deleting.`);
|
||||
if (this._failureError)
|
||||
throw this._failureError;
|
||||
if (this._finished) {
|
||||
saveCallback(this._localPath).catch(() => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._saveCallbacks.push(saveCallback);
|
||||
}
|
||||
async failureError() {
|
||||
if (this._unaccessibleErrorMessage)
|
||||
return this._unaccessibleErrorMessage;
|
||||
await this._finishedPromise;
|
||||
return this._failureError?.message || null;
|
||||
}
|
||||
async cancel() {
|
||||
(0, import_utils.assert)(this._cancelCallback !== void 0);
|
||||
return this._cancelCallback();
|
||||
}
|
||||
async delete() {
|
||||
if (this._unaccessibleErrorMessage)
|
||||
return;
|
||||
const fileName = await this.localPathAfterFinished();
|
||||
if (this._deleted)
|
||||
return;
|
||||
this._deleted = true;
|
||||
if (fileName)
|
||||
await import_fs.default.promises.unlink(fileName).catch((e) => {
|
||||
});
|
||||
}
|
||||
async deleteOnContextClose() {
|
||||
if (this._deleted)
|
||||
return;
|
||||
this._deleted = true;
|
||||
if (!this._unaccessibleErrorMessage)
|
||||
await import_fs.default.promises.unlink(this._localPath).catch((e) => {
|
||||
});
|
||||
await this.reportFinished(new import_errors.TargetClosedError());
|
||||
}
|
||||
async reportFinished(error) {
|
||||
if (this._finished)
|
||||
return;
|
||||
this._finished = true;
|
||||
this._failureError = error;
|
||||
if (error) {
|
||||
for (const callback of this._saveCallbacks)
|
||||
await callback("", error);
|
||||
} else {
|
||||
for (const callback of this._saveCallbacks)
|
||||
await callback(this._localPath);
|
||||
}
|
||||
this._saveCallbacks = [];
|
||||
this._finishedPromise.resolve();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Artifact
|
||||
});
|
||||
505
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiBrowser.js
generated
vendored
Normal file
505
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiBrowser.js
generated
vendored
Normal file
@@ -0,0 +1,505 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiBrowser_exports = {};
|
||||
__export(bidiBrowser_exports, {
|
||||
BidiBrowser: () => BidiBrowser,
|
||||
BidiBrowserContext: () => BidiBrowserContext,
|
||||
Network: () => Network,
|
||||
getScreenOrientation: () => getScreenOrientation
|
||||
});
|
||||
module.exports = __toCommonJS(bidiBrowser_exports);
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_browser = require("../browser");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var network = __toESM(require("../network"));
|
||||
var import_bidiConnection = require("./bidiConnection");
|
||||
var import_bidiNetworkManager = require("./bidiNetworkManager");
|
||||
var import_bidiPage = require("./bidiPage");
|
||||
var import_page = require("../page");
|
||||
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
||||
class BidiBrowser extends import_browser.Browser {
|
||||
constructor(parent, transport, options) {
|
||||
super(parent, options);
|
||||
this._contexts = /* @__PURE__ */ new Map();
|
||||
this._bidiPages = /* @__PURE__ */ new Map();
|
||||
this._connection = new import_bidiConnection.BidiConnection(transport, this._onDisconnect.bind(this), options.protocolLogger, options.browserLogsCollector);
|
||||
this._browserSession = this._connection.browserSession;
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._browserSession, "browsingContext.contextCreated", this._onBrowsingContextCreated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._browserSession, "script.realmDestroyed", this._onScriptRealmDestroyed.bind(this))
|
||||
];
|
||||
}
|
||||
static async connect(parent, transport, options) {
|
||||
const browser = new BidiBrowser(parent, transport, options);
|
||||
if (options.__testHookOnConnectToBrowser)
|
||||
await options.__testHookOnConnectToBrowser();
|
||||
browser._bidiSessionInfo = await browser._browserSession.send("session.new", {
|
||||
capabilities: {
|
||||
alwaysMatch: {
|
||||
"acceptInsecureCerts": options.persistent?.internalIgnoreHTTPSErrors || options.persistent?.ignoreHTTPSErrors,
|
||||
"proxy": getProxyConfiguration(options.originalLaunchOptions.proxyOverride ?? options.proxy),
|
||||
"unhandledPromptBehavior": {
|
||||
default: bidi.Session.UserPromptHandlerType.Ignore
|
||||
},
|
||||
"webSocketUrl": true,
|
||||
// Chrome with WebDriver BiDi does not support prerendering
|
||||
// yet because WebDriver BiDi behavior is not specified. See
|
||||
// https://github.com/w3c/webdriver-bidi/issues/321.
|
||||
"goog:prerenderingDisabled": true
|
||||
}
|
||||
}
|
||||
});
|
||||
await browser._browserSession.send("session.subscribe", {
|
||||
events: [
|
||||
"browsingContext",
|
||||
"network",
|
||||
"log",
|
||||
"script",
|
||||
"input"
|
||||
]
|
||||
});
|
||||
await browser._browserSession.send("network.addDataCollector", {
|
||||
dataTypes: [bidi.Network.DataType.Response],
|
||||
maxEncodedDataSize: 2e7
|
||||
// same default as in CDP: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/inspector/inspector_network_agent.cc;l=134;drc=4128411589187a396829a827f59a655bed876aa7
|
||||
});
|
||||
if (options.persistent) {
|
||||
const context = new BidiBrowserContext(browser, void 0, options.persistent);
|
||||
browser._defaultContext = context;
|
||||
await context._initialize();
|
||||
const page = await browser._defaultContext.doCreateNewPage();
|
||||
await page.waitForInitializedOrError();
|
||||
}
|
||||
return browser;
|
||||
}
|
||||
_onDisconnect() {
|
||||
this._didClose();
|
||||
}
|
||||
async doCreateNewContext(options) {
|
||||
const proxy = options.proxyOverride || options.proxy;
|
||||
const { userContext } = await this._browserSession.send("browser.createUserContext", {
|
||||
acceptInsecureCerts: options.internalIgnoreHTTPSErrors || options.ignoreHTTPSErrors,
|
||||
proxy: getProxyConfiguration(proxy)
|
||||
});
|
||||
const context = new BidiBrowserContext(this, userContext, options);
|
||||
await context._initialize();
|
||||
this._contexts.set(userContext, context);
|
||||
return context;
|
||||
}
|
||||
contexts() {
|
||||
return Array.from(this._contexts.values());
|
||||
}
|
||||
version() {
|
||||
return this._bidiSessionInfo.capabilities.browserVersion;
|
||||
}
|
||||
userAgent() {
|
||||
return this._bidiSessionInfo.capabilities.userAgent;
|
||||
}
|
||||
isConnected() {
|
||||
return !this._connection.isClosed();
|
||||
}
|
||||
_onBrowsingContextCreated(event) {
|
||||
if (event.parent) {
|
||||
const parentFrameId = event.parent;
|
||||
const page2 = this._findPageForFrame(parentFrameId);
|
||||
if (page2) {
|
||||
page2._session.addFrameBrowsingContext(event.context);
|
||||
page2._page.frameManager.frameAttached(event.context, parentFrameId);
|
||||
const frame = page2._page.frameManager.frame(event.context);
|
||||
if (frame)
|
||||
frame._url = event.url;
|
||||
}
|
||||
return;
|
||||
}
|
||||
let context = this._contexts.get(event.userContext);
|
||||
if (!context)
|
||||
context = this._defaultContext;
|
||||
if (!context)
|
||||
return;
|
||||
const session = this._connection.createMainFrameBrowsingContextSession(event.context);
|
||||
const opener = event.originalOpener && this._findPageForFrame(event.originalOpener);
|
||||
const page = new import_bidiPage.BidiPage(context, session, opener || null);
|
||||
page._page.mainFrame()._url = event.url;
|
||||
this._bidiPages.set(event.context, page);
|
||||
}
|
||||
_onBrowsingContextDestroyed(event) {
|
||||
if (event.parent) {
|
||||
this._browserSession.removeFrameBrowsingContext(event.context);
|
||||
const parentFrameId = event.parent;
|
||||
for (const page of this._bidiPages.values()) {
|
||||
const parentFrame = page._page.frameManager.frame(parentFrameId);
|
||||
if (!parentFrame)
|
||||
continue;
|
||||
page._page.frameManager.frameDetached(event.context);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const bidiPage = this._bidiPages.get(event.context);
|
||||
if (!bidiPage)
|
||||
return;
|
||||
bidiPage.didClose();
|
||||
this._bidiPages.delete(event.context);
|
||||
}
|
||||
_onScriptRealmDestroyed(event) {
|
||||
for (const page of this._bidiPages.values()) {
|
||||
if (page._onRealmDestroyed(event))
|
||||
return;
|
||||
}
|
||||
}
|
||||
_findPageForFrame(frameId) {
|
||||
for (const page of this._bidiPages.values()) {
|
||||
if (page._page.frameManager.frame(frameId))
|
||||
return page;
|
||||
}
|
||||
}
|
||||
}
|
||||
class BidiBrowserContext extends import_browserContext.BrowserContext {
|
||||
constructor(browser, browserContextId, options) {
|
||||
super(browser, options, browserContextId);
|
||||
this._originToPermissions = /* @__PURE__ */ new Map();
|
||||
this._initScriptIds = /* @__PURE__ */ new Map();
|
||||
this._authenticateProxyViaHeader();
|
||||
}
|
||||
_bidiPages() {
|
||||
return [...this._browser._bidiPages.values()].filter((bidiPage) => bidiPage._browserContext === this);
|
||||
}
|
||||
async _initialize() {
|
||||
const promises = [
|
||||
super._initialize()
|
||||
];
|
||||
promises.push(this.doUpdateDefaultViewport());
|
||||
if (this._options.geolocation)
|
||||
promises.push(this.setGeolocation(this._options.geolocation));
|
||||
if (this._options.locale) {
|
||||
promises.push(this._browser._browserSession.send("emulation.setLocaleOverride", {
|
||||
locale: this._options.locale,
|
||||
userContexts: [this._userContextId()]
|
||||
}));
|
||||
}
|
||||
if (this._options.timezoneId) {
|
||||
promises.push(this._browser._browserSession.send("emulation.setTimezoneOverride", {
|
||||
timezone: this._options.timezoneId,
|
||||
userContexts: [this._userContextId()]
|
||||
}));
|
||||
}
|
||||
if (this._options.userAgent) {
|
||||
promises.push(this._browser._browserSession.send("emulation.setUserAgentOverride", {
|
||||
userAgent: this._options.userAgent,
|
||||
userContexts: [this._userContextId()]
|
||||
}));
|
||||
}
|
||||
if (this._options.extraHTTPHeaders)
|
||||
promises.push(this.doUpdateExtraHTTPHeaders());
|
||||
await Promise.all(promises);
|
||||
}
|
||||
possiblyUninitializedPages() {
|
||||
return this._bidiPages().map((bidiPage) => bidiPage._page);
|
||||
}
|
||||
async doCreateNewPage() {
|
||||
const { context } = await this._browser._browserSession.send("browsingContext.create", {
|
||||
type: bidi.BrowsingContext.CreateType.Window,
|
||||
userContext: this._browserContextId
|
||||
});
|
||||
return this._browser._bidiPages.get(context)._page;
|
||||
}
|
||||
async doGetCookies(urls) {
|
||||
const { cookies } = await this._browser._browserSession.send(
|
||||
"storage.getCookies",
|
||||
{ partition: { type: "storageKey", userContext: this._browserContextId } }
|
||||
);
|
||||
return network.filterCookies(cookies.map((c) => {
|
||||
const copy = {
|
||||
name: c.name,
|
||||
value: (0, import_bidiNetworkManager.bidiBytesValueToString)(c.value),
|
||||
domain: c.domain,
|
||||
path: c.path,
|
||||
httpOnly: c.httpOnly,
|
||||
secure: c.secure,
|
||||
expires: c.expiry ?? -1,
|
||||
sameSite: c.sameSite ? fromBidiSameSite(c.sameSite) : "None"
|
||||
};
|
||||
return copy;
|
||||
}), urls);
|
||||
}
|
||||
async addCookies(cookies) {
|
||||
cookies = network.rewriteCookies(cookies);
|
||||
const promises = cookies.map((c) => {
|
||||
const cookie = {
|
||||
name: c.name,
|
||||
value: { type: "string", value: c.value },
|
||||
domain: c.domain,
|
||||
path: c.path,
|
||||
httpOnly: c.httpOnly,
|
||||
secure: c.secure,
|
||||
sameSite: c.sameSite && toBidiSameSite(c.sameSite),
|
||||
expiry: c.expires === -1 || c.expires === void 0 ? void 0 : Math.round(c.expires)
|
||||
};
|
||||
return this._browser._browserSession.send(
|
||||
"storage.setCookie",
|
||||
{ cookie, partition: { type: "storageKey", userContext: this._browserContextId } }
|
||||
);
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
async doClearCookies() {
|
||||
await this._browser._browserSession.send(
|
||||
"storage.deleteCookies",
|
||||
{ partition: { type: "storageKey", userContext: this._browserContextId } }
|
||||
);
|
||||
}
|
||||
async doGrantPermissions(origin, permissions) {
|
||||
const currentPermissions = this._originToPermissions.get(origin) || [];
|
||||
const toGrant = permissions.filter((permission) => !currentPermissions.includes(permission));
|
||||
this._originToPermissions.set(origin, [...currentPermissions, ...toGrant]);
|
||||
await Promise.all(toGrant.map((permission) => this._setPermission(origin, permission, bidi.Permissions.PermissionState.Granted)));
|
||||
}
|
||||
async doClearPermissions() {
|
||||
const currentPermissions = [...this._originToPermissions.entries()];
|
||||
this._originToPermissions = /* @__PURE__ */ new Map();
|
||||
await Promise.all(currentPermissions.map(([origin, permissions]) => permissions.map(
|
||||
(p) => this._setPermission(origin, p, bidi.Permissions.PermissionState.Prompt)
|
||||
)));
|
||||
}
|
||||
async _setPermission(origin, permission, state) {
|
||||
await this._browser._browserSession.send("permissions.setPermission", {
|
||||
descriptor: {
|
||||
name: permission
|
||||
},
|
||||
state,
|
||||
origin,
|
||||
userContext: this._userContextId()
|
||||
});
|
||||
}
|
||||
async setGeolocation(geolocation) {
|
||||
(0, import_browserContext.verifyGeolocation)(geolocation);
|
||||
this._options.geolocation = geolocation;
|
||||
await this._browser._browserSession.send("emulation.setGeolocationOverride", {
|
||||
coordinates: geolocation ? {
|
||||
latitude: geolocation.latitude,
|
||||
longitude: geolocation.longitude,
|
||||
accuracy: geolocation.accuracy
|
||||
} : null,
|
||||
userContexts: [this._userContextId()]
|
||||
});
|
||||
}
|
||||
async doUpdateExtraHTTPHeaders() {
|
||||
const allHeaders = this._options.extraHTTPHeaders || [];
|
||||
await this._browser._browserSession.send("network.setExtraHeaders", {
|
||||
headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
|
||||
userContexts: [this._userContextId()]
|
||||
});
|
||||
}
|
||||
async setUserAgent(userAgent) {
|
||||
this._options.userAgent = userAgent;
|
||||
await this._browser._browserSession.send("emulation.setUserAgentOverride", {
|
||||
userAgent: userAgent ?? null,
|
||||
userContexts: [this._userContextId()]
|
||||
});
|
||||
}
|
||||
async doUpdateOffline() {
|
||||
}
|
||||
async doSetHTTPCredentials(httpCredentials) {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateHttpCredentials();
|
||||
}
|
||||
async doAddInitScript(initScript) {
|
||||
const { script } = await this._browser._browserSession.send("script.addPreloadScript", {
|
||||
// TODO: remove function call from the source.
|
||||
functionDeclaration: `() => { return ${initScript.source} }`,
|
||||
userContexts: [this._userContextId()]
|
||||
});
|
||||
this._initScriptIds.set(initScript, script);
|
||||
}
|
||||
async doRemoveInitScripts(initScripts) {
|
||||
const ids = [];
|
||||
for (const script of initScripts) {
|
||||
const id = this._initScriptIds.get(script);
|
||||
if (id)
|
||||
ids.push(id);
|
||||
this._initScriptIds.delete(script);
|
||||
}
|
||||
await Promise.all(ids.map((script) => this._browser._browserSession.send("script.removePreloadScript", { script })));
|
||||
}
|
||||
async doUpdateRequestInterception() {
|
||||
}
|
||||
async doUpdateDefaultViewport() {
|
||||
if (!this._options.viewport)
|
||||
return;
|
||||
await Promise.all([
|
||||
this._browser._browserSession.send("browsingContext.setViewport", {
|
||||
viewport: {
|
||||
width: this._options.viewport.width,
|
||||
height: this._options.viewport.height
|
||||
},
|
||||
devicePixelRatio: this._options.deviceScaleFactor || 1,
|
||||
userContexts: [this._userContextId()]
|
||||
}),
|
||||
this._browser._browserSession.send("emulation.setScreenOrientationOverride", {
|
||||
screenOrientation: getScreenOrientation(!!this._options.isMobile, this._options.viewport),
|
||||
userContexts: [this._userContextId()]
|
||||
})
|
||||
]);
|
||||
}
|
||||
async doUpdateDefaultEmulatedMedia() {
|
||||
}
|
||||
async doExposePlaywrightBinding() {
|
||||
const args = [{
|
||||
type: "channel",
|
||||
value: {
|
||||
channel: import_bidiPage.kPlaywrightBindingChannel,
|
||||
ownership: bidi.Script.ResultOwnership.Root
|
||||
}
|
||||
}];
|
||||
const functionDeclaration = `function addMainBinding(callback) { globalThis['${import_page.PageBinding.kBindingName}'] = callback; }`;
|
||||
const promises = [];
|
||||
promises.push(this._browser._browserSession.send("script.addPreloadScript", {
|
||||
functionDeclaration,
|
||||
arguments: args,
|
||||
userContexts: [this._userContextId()]
|
||||
}));
|
||||
promises.push(...this._bidiPages().map((page) => {
|
||||
const realms = [...page._realmToContext].filter(([realm, context]) => context.world === "main").map(([realm, context]) => realm);
|
||||
return Promise.all(realms.map((realm) => {
|
||||
return page._session.send("script.callFunction", {
|
||||
functionDeclaration,
|
||||
arguments: args,
|
||||
target: { realm },
|
||||
awaitPromise: false,
|
||||
userActivation: false
|
||||
});
|
||||
}));
|
||||
}));
|
||||
await Promise.all(promises);
|
||||
}
|
||||
onClosePersistent() {
|
||||
}
|
||||
async clearCache() {
|
||||
}
|
||||
async doClose(reason) {
|
||||
if (!this._browserContextId) {
|
||||
await this._browser.close({ reason });
|
||||
return;
|
||||
}
|
||||
await this._browser._browserSession.send("browser.removeUserContext", {
|
||||
userContext: this._browserContextId
|
||||
});
|
||||
this._browser._contexts.delete(this._browserContextId);
|
||||
}
|
||||
async cancelDownload(uuid) {
|
||||
}
|
||||
_userContextId() {
|
||||
if (this._browserContextId)
|
||||
return this._browserContextId;
|
||||
return "default";
|
||||
}
|
||||
}
|
||||
function fromBidiSameSite(sameSite) {
|
||||
switch (sameSite) {
|
||||
case "strict":
|
||||
return "Strict";
|
||||
case "lax":
|
||||
return "Lax";
|
||||
case "none":
|
||||
return "None";
|
||||
case "default":
|
||||
return "Lax";
|
||||
}
|
||||
return "None";
|
||||
}
|
||||
function toBidiSameSite(sameSite) {
|
||||
switch (sameSite) {
|
||||
case "Strict":
|
||||
return bidi.Network.SameSite.Strict;
|
||||
case "Lax":
|
||||
return bidi.Network.SameSite.Lax;
|
||||
case "None":
|
||||
return bidi.Network.SameSite.None;
|
||||
}
|
||||
return bidi.Network.SameSite.None;
|
||||
}
|
||||
function getProxyConfiguration(proxySettings) {
|
||||
if (!proxySettings)
|
||||
return void 0;
|
||||
const proxy = {
|
||||
proxyType: "manual"
|
||||
};
|
||||
const url = new URL(proxySettings.server);
|
||||
switch (url.protocol) {
|
||||
case "http:":
|
||||
proxy.httpProxy = url.host;
|
||||
break;
|
||||
case "https:":
|
||||
proxy.sslProxy = url.host;
|
||||
break;
|
||||
case "socks4:":
|
||||
proxy.socksProxy = url.host;
|
||||
proxy.socksVersion = 4;
|
||||
break;
|
||||
case "socks5:":
|
||||
proxy.socksProxy = url.host;
|
||||
proxy.socksVersion = 5;
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid proxy server protocol: " + proxySettings.server);
|
||||
}
|
||||
const bypass = proxySettings.bypass ?? process.env.PLAYWRIGHT_PROXY_BYPASS_FOR_TESTING;
|
||||
if (bypass)
|
||||
proxy.noProxy = bypass.split(",");
|
||||
return proxy;
|
||||
}
|
||||
function getScreenOrientation(isMobile, viewportSize) {
|
||||
const screenOrientation = {
|
||||
type: "landscape-primary",
|
||||
natural: bidi.Emulation.ScreenOrientationNatural.Landscape
|
||||
};
|
||||
if (isMobile) {
|
||||
screenOrientation.natural = bidi.Emulation.ScreenOrientationNatural.Portrait;
|
||||
if (viewportSize.width <= viewportSize.height)
|
||||
screenOrientation.type = "portrait-primary";
|
||||
}
|
||||
return screenOrientation;
|
||||
}
|
||||
var Network;
|
||||
((Network2) => {
|
||||
let SameSite;
|
||||
((SameSite2) => {
|
||||
SameSite2["Strict"] = "strict";
|
||||
SameSite2["Lax"] = "lax";
|
||||
SameSite2["None"] = "none";
|
||||
})(SameSite = Network2.SameSite || (Network2.SameSite = {}));
|
||||
})(Network || (Network = {}));
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiBrowser,
|
||||
BidiBrowserContext,
|
||||
Network,
|
||||
getScreenOrientation
|
||||
});
|
||||
153
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiChromium.js
generated
vendored
Normal file
153
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiChromium.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiChromium_exports = {};
|
||||
__export(bidiChromium_exports, {
|
||||
BidiChromium: () => BidiChromium
|
||||
});
|
||||
module.exports = __toCommonJS(bidiChromium_exports);
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_ascii = require("../utils/ascii");
|
||||
var import_browserType = require("../browserType");
|
||||
var import_bidiBrowser = require("./bidiBrowser");
|
||||
var import_bidiConnection = require("./bidiConnection");
|
||||
var import_chromiumSwitches = require("../chromium/chromiumSwitches");
|
||||
var import_chromium = require("../chromium/chromium");
|
||||
class BidiChromium extends import_browserType.BrowserType {
|
||||
constructor(parent) {
|
||||
super(parent, "chromium");
|
||||
}
|
||||
async connectToTransport(transport, options, browserLogsCollector) {
|
||||
const bidiTransport = await require("./bidiOverCdp").connectBidiOverCdp(transport);
|
||||
transport[kBidiOverCdpWrapper] = bidiTransport;
|
||||
try {
|
||||
return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, bidiTransport, options);
|
||||
} catch (e) {
|
||||
if (browserLogsCollector.recentLogs().some((log) => log.includes("Failed to create a ProcessSingleton for your profile directory."))) {
|
||||
throw new Error(
|
||||
"Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."
|
||||
);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
doRewriteStartupLog(error) {
|
||||
if (!error.logs)
|
||||
return error;
|
||||
if (error.logs.includes("Missing X server"))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
||||
if (!error.logs.includes("crbug.com/357670") && !error.logs.includes("No usable sandbox!") && !error.logs.includes("crbug.com/638180"))
|
||||
return error;
|
||||
error.logs = [
|
||||
`Chromium sandboxing failed!`,
|
||||
`================================`,
|
||||
`To avoid the sandboxing issue, do either of the following:`,
|
||||
` - (preferred): Configure your environment to support sandboxing`,
|
||||
` - (alternative): Launch Chromium without sandbox using 'chromiumSandbox: false' option`,
|
||||
`================================`,
|
||||
``
|
||||
].join("\n");
|
||||
return error;
|
||||
}
|
||||
amendEnvironment(env) {
|
||||
return env;
|
||||
}
|
||||
attemptToGracefullyCloseBrowser(transport) {
|
||||
const bidiTransport = transport[kBidiOverCdpWrapper];
|
||||
if (bidiTransport)
|
||||
transport = bidiTransport;
|
||||
transport.send({ method: "browser.close", params: {}, id: import_bidiConnection.kBrowserCloseMessageId });
|
||||
}
|
||||
supportsPipeTransport() {
|
||||
return false;
|
||||
}
|
||||
async defaultArgs(options, isPersistent, userDataDir) {
|
||||
const chromeArguments = this._innerDefaultArgs(options);
|
||||
chromeArguments.push(`--user-data-dir=${userDataDir}`);
|
||||
chromeArguments.push("--remote-debugging-port=0");
|
||||
if (isPersistent)
|
||||
chromeArguments.push("about:blank");
|
||||
else
|
||||
chromeArguments.push("--no-startup-window");
|
||||
return chromeArguments;
|
||||
}
|
||||
async waitForReadyState(options, browserLogsCollector) {
|
||||
return (0, import_chromium.waitForReadyState)({ ...options, cdpPort: 0 }, browserLogsCollector);
|
||||
}
|
||||
_innerDefaultArgs(options) {
|
||||
const { args = [] } = options;
|
||||
const userDataDirArg = args.find((arg) => arg.startsWith("--user-data-dir"));
|
||||
if (userDataDirArg)
|
||||
throw this._createUserDataDirArgMisuseError("--user-data-dir");
|
||||
if (args.find((arg) => arg.startsWith("--remote-debugging-pipe")))
|
||||
throw new Error("Playwright manages remote debugging connection itself.");
|
||||
if (args.find((arg) => !arg.startsWith("-")))
|
||||
throw new Error("Arguments can not specify page to be opened");
|
||||
const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode)];
|
||||
if (import_os.default.platform() === "darwin") {
|
||||
chromeArguments.push("--enable-unsafe-swiftshader");
|
||||
}
|
||||
if (options.devtools)
|
||||
chromeArguments.push("--auto-open-devtools-for-tabs");
|
||||
if (options.headless) {
|
||||
chromeArguments.push("--headless");
|
||||
chromeArguments.push(
|
||||
"--hide-scrollbars",
|
||||
"--mute-audio",
|
||||
"--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4"
|
||||
);
|
||||
}
|
||||
if (options.chromiumSandbox !== true)
|
||||
chromeArguments.push("--no-sandbox");
|
||||
const proxy = options.proxyOverride || options.proxy;
|
||||
if (proxy) {
|
||||
const proxyURL = new URL(proxy.server);
|
||||
const isSocks = proxyURL.protocol === "socks5:";
|
||||
if (isSocks && !options.socksProxyPort) {
|
||||
chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
|
||||
}
|
||||
chromeArguments.push(`--proxy-server=${proxy.server}`);
|
||||
const proxyBypassRules = [];
|
||||
if (options.socksProxyPort)
|
||||
proxyBypassRules.push("<-loopback>");
|
||||
if (proxy.bypass)
|
||||
proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
|
||||
if (!process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK && !proxyBypassRules.includes("<-loopback>"))
|
||||
proxyBypassRules.push("<-loopback>");
|
||||
if (proxyBypassRules.length > 0)
|
||||
chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(";")}`);
|
||||
}
|
||||
chromeArguments.push(...args);
|
||||
return chromeArguments;
|
||||
}
|
||||
}
|
||||
const kBidiOverCdpWrapper = Symbol("kBidiConnectionWrapper");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiChromium
|
||||
});
|
||||
212
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiConnection.js
generated
vendored
Normal file
212
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiConnection.js
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiConnection_exports = {};
|
||||
__export(bidiConnection_exports, {
|
||||
BidiConnection: () => BidiConnection,
|
||||
BidiSession: () => BidiSession,
|
||||
kBrowserCloseMessageId: () => kBrowserCloseMessageId,
|
||||
kShutdownSessionNewMessageId: () => kShutdownSessionNewMessageId
|
||||
});
|
||||
module.exports = __toCommonJS(bidiConnection_exports);
|
||||
var import_events = require("events");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_helper = require("../helper");
|
||||
var import_protocolError = require("../protocolError");
|
||||
const kBrowserCloseMessageId = Number.MAX_SAFE_INTEGER - 1;
|
||||
const kShutdownSessionNewMessageId = kBrowserCloseMessageId - 1;
|
||||
class BidiConnection {
|
||||
constructor(transport, onDisconnect, protocolLogger, browserLogsCollector) {
|
||||
this._lastId = 0;
|
||||
this._closed = false;
|
||||
this._browsingContextToSession = /* @__PURE__ */ new Map();
|
||||
this._realmToBrowsingContext = /* @__PURE__ */ new Map();
|
||||
// TODO: shared/service workers might have multiple owner realms.
|
||||
this._realmToOwnerRealm = /* @__PURE__ */ new Map();
|
||||
this._transport = transport;
|
||||
this._onDisconnect = onDisconnect;
|
||||
this._protocolLogger = protocolLogger;
|
||||
this._browserLogsCollector = browserLogsCollector;
|
||||
this.browserSession = new BidiSession(this, "", (message) => {
|
||||
this.rawSend(message);
|
||||
});
|
||||
this._transport.onmessage = this._dispatchMessage.bind(this);
|
||||
this._transport.onclose = this._onClose.bind(this);
|
||||
}
|
||||
nextMessageId() {
|
||||
return ++this._lastId;
|
||||
}
|
||||
rawSend(message) {
|
||||
this._protocolLogger("send", message);
|
||||
this._transport.send(message);
|
||||
}
|
||||
_dispatchMessage(message) {
|
||||
this._protocolLogger("receive", message);
|
||||
const object = message;
|
||||
if (object.type === "event") {
|
||||
if (object.method === "script.realmCreated") {
|
||||
if ("context" in object.params)
|
||||
this._realmToBrowsingContext.set(object.params.realm, object.params.context);
|
||||
if (object.params.type === "dedicated-worker")
|
||||
this._realmToOwnerRealm.set(object.params.realm, object.params.owners[0]);
|
||||
} else if (object.method === "script.realmDestroyed") {
|
||||
this._realmToBrowsingContext.delete(object.params.realm);
|
||||
this._realmToOwnerRealm.delete(object.params.realm);
|
||||
}
|
||||
let context;
|
||||
let realm;
|
||||
if ("context" in object.params) {
|
||||
context = object.params.context;
|
||||
} else if (object.method === "log.entryAdded" || object.method === "script.message") {
|
||||
context = object.params.source?.context;
|
||||
realm = object.params.source?.realm;
|
||||
} else if (object.method === "script.realmCreated" && object.params.type === "dedicated-worker") {
|
||||
realm = object.params.owners[0];
|
||||
}
|
||||
if (!context && realm) {
|
||||
while (this._realmToOwnerRealm.get(realm))
|
||||
realm = this._realmToOwnerRealm.get(realm);
|
||||
context = this._realmToBrowsingContext.get(realm);
|
||||
}
|
||||
if (context) {
|
||||
const session = this._browsingContextToSession.get(context);
|
||||
if (session) {
|
||||
session.dispatchMessage(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (message.id) {
|
||||
for (const session of this._browsingContextToSession.values()) {
|
||||
if (session.hasCallback(message.id)) {
|
||||
session.dispatchMessage(message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.browserSession.dispatchMessage(message);
|
||||
}
|
||||
_onClose(reason) {
|
||||
this._closed = true;
|
||||
this._transport.onmessage = void 0;
|
||||
this._transport.onclose = void 0;
|
||||
this._browserDisconnectedLogs = import_helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs(), reason);
|
||||
this.browserSession.dispose();
|
||||
this._onDisconnect();
|
||||
}
|
||||
isClosed() {
|
||||
return this._closed;
|
||||
}
|
||||
close() {
|
||||
if (!this._closed)
|
||||
this._transport.close();
|
||||
}
|
||||
createMainFrameBrowsingContextSession(bowsingContextId) {
|
||||
const result = new BidiSession(this, bowsingContextId, (message) => this.rawSend(message));
|
||||
this._browsingContextToSession.set(bowsingContextId, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
class BidiSession extends import_events.EventEmitter {
|
||||
constructor(connection, sessionId, rawSend) {
|
||||
super();
|
||||
this._disposed = false;
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._crashed = false;
|
||||
this._browsingContexts = /* @__PURE__ */ new Set();
|
||||
this.setMaxListeners(0);
|
||||
this.connection = connection;
|
||||
this.sessionId = sessionId;
|
||||
this._rawSend = rawSend;
|
||||
this.on = super.on;
|
||||
this.off = super.removeListener;
|
||||
this.addListener = super.addListener;
|
||||
this.removeListener = super.removeListener;
|
||||
this.once = super.once;
|
||||
}
|
||||
addFrameBrowsingContext(context) {
|
||||
this._browsingContexts.add(context);
|
||||
this.connection._browsingContextToSession.set(context, this);
|
||||
}
|
||||
removeFrameBrowsingContext(context) {
|
||||
this._browsingContexts.delete(context);
|
||||
this.connection._browsingContextToSession.delete(context);
|
||||
}
|
||||
async send(method, params) {
|
||||
if (this._crashed || this._disposed || this.connection._browserDisconnectedLogs)
|
||||
throw new import_protocolError.ProtocolError(this._crashed ? "crashed" : "closed", void 0, this.connection._browserDisconnectedLogs);
|
||||
const id = this.connection.nextMessageId();
|
||||
const messageObj = { id, method, params };
|
||||
this._rawSend(messageObj);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject, error: new import_protocolError.ProtocolError("error", method) });
|
||||
});
|
||||
}
|
||||
sendMayFail(method, params) {
|
||||
return this.send(method, params).catch((error) => import_debugLogger.debugLogger.log("error", error));
|
||||
}
|
||||
markAsCrashed() {
|
||||
this._crashed = true;
|
||||
}
|
||||
isDisposed() {
|
||||
return this._disposed;
|
||||
}
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
this.connection._browsingContextToSession.delete(this.sessionId);
|
||||
for (const context of this._browsingContexts)
|
||||
this.connection._browsingContextToSession.delete(context);
|
||||
this._browsingContexts.clear();
|
||||
for (const callback of this._callbacks.values()) {
|
||||
callback.error.type = this._crashed ? "crashed" : "closed";
|
||||
callback.error.logs = this.connection._browserDisconnectedLogs;
|
||||
callback.reject(callback.error);
|
||||
}
|
||||
this._callbacks.clear();
|
||||
}
|
||||
hasCallback(id) {
|
||||
return this._callbacks.has(id);
|
||||
}
|
||||
dispatchMessage(message) {
|
||||
const object = message;
|
||||
if (object.id === kBrowserCloseMessageId || object.id === kShutdownSessionNewMessageId)
|
||||
return;
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.type === "error") {
|
||||
callback.error.setMessage(object.error + "\nMessage: " + object.message);
|
||||
callback.reject(callback.error);
|
||||
} else if (object.type === "success") {
|
||||
callback.resolve(object.result);
|
||||
} else {
|
||||
callback.error.setMessage("Internal error, unexpected response type: " + JSON.stringify(object));
|
||||
callback.reject(callback.error);
|
||||
}
|
||||
} else if (object.id) {
|
||||
} else {
|
||||
Promise.resolve().then(() => this.emit(object.method, object.params));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiConnection,
|
||||
BidiSession,
|
||||
kBrowserCloseMessageId,
|
||||
kShutdownSessionNewMessageId
|
||||
});
|
||||
221
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiExecutionContext.js
generated
vendored
Normal file
221
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiExecutionContext.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiExecutionContext_exports = {};
|
||||
__export(bidiExecutionContext_exports, {
|
||||
BidiExecutionContext: () => BidiExecutionContext,
|
||||
createHandle: () => createHandle
|
||||
});
|
||||
module.exports = __toCommonJS(bidiExecutionContext_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_utilityScriptSerializers = require("../../utils/isomorphic/utilityScriptSerializers");
|
||||
var js = __toESM(require("../javascript"));
|
||||
var dom = __toESM(require("../dom"));
|
||||
var import_bidiDeserializer = require("./third_party/bidiDeserializer");
|
||||
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
||||
var import_bidiSerializer = require("./third_party/bidiSerializer");
|
||||
class BidiExecutionContext {
|
||||
constructor(session, realmInfo) {
|
||||
this._session = session;
|
||||
if (realmInfo.type === "window") {
|
||||
this._target = {
|
||||
context: realmInfo.context,
|
||||
sandbox: realmInfo.sandbox
|
||||
};
|
||||
} else {
|
||||
this._target = {
|
||||
realm: realmInfo.realm
|
||||
};
|
||||
}
|
||||
}
|
||||
async rawEvaluateJSON(expression) {
|
||||
const response = await this._session.send("script.evaluate", {
|
||||
expression,
|
||||
target: this._target,
|
||||
serializationOptions: {
|
||||
maxObjectDepth: 10,
|
||||
maxDomDepth: 10
|
||||
},
|
||||
awaitPromise: true,
|
||||
userActivation: true
|
||||
});
|
||||
if (response.type === "success")
|
||||
return import_bidiDeserializer.BidiDeserializer.deserialize(response.result);
|
||||
if (response.type === "exception")
|
||||
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
||||
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
||||
}
|
||||
async rawEvaluateHandle(context, expression) {
|
||||
const response = await this._session.send("script.evaluate", {
|
||||
expression,
|
||||
target: this._target,
|
||||
resultOwnership: bidi.Script.ResultOwnership.Root,
|
||||
// Necessary for the handle to be returned.
|
||||
serializationOptions: { maxObjectDepth: 0, maxDomDepth: 0 },
|
||||
awaitPromise: true,
|
||||
userActivation: true
|
||||
});
|
||||
if (response.type === "success") {
|
||||
if ("handle" in response.result)
|
||||
return createHandle(context, response.result);
|
||||
throw new js.JavaScriptErrorInEvaluate("Cannot get handle: " + JSON.stringify(response.result));
|
||||
}
|
||||
if (response.type === "exception")
|
||||
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
||||
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
||||
}
|
||||
async evaluateWithArguments(functionDeclaration, returnByValue, utilityScript, values, handles) {
|
||||
const response = await this._session.send("script.callFunction", {
|
||||
functionDeclaration,
|
||||
target: this._target,
|
||||
arguments: [
|
||||
{ handle: utilityScript._objectId },
|
||||
...values.map(import_bidiSerializer.BidiSerializer.serialize),
|
||||
...handles.map((handle) => ({ handle: handle._objectId }))
|
||||
],
|
||||
resultOwnership: returnByValue ? void 0 : bidi.Script.ResultOwnership.Root,
|
||||
// Necessary for the handle to be returned.
|
||||
serializationOptions: returnByValue ? {} : { maxObjectDepth: 0, maxDomDepth: 0 },
|
||||
awaitPromise: true,
|
||||
userActivation: true
|
||||
});
|
||||
if (response.type === "exception")
|
||||
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
||||
if (response.type === "success") {
|
||||
if (returnByValue)
|
||||
return (0, import_utilityScriptSerializers.parseEvaluationResultValue)(import_bidiDeserializer.BidiDeserializer.deserialize(response.result));
|
||||
return createHandle(utilityScript._context, response.result);
|
||||
}
|
||||
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
||||
}
|
||||
async getProperties(handle) {
|
||||
const names = await handle.evaluate((object) => {
|
||||
const names2 = [];
|
||||
const descriptors = Object.getOwnPropertyDescriptors(object);
|
||||
for (const name in descriptors) {
|
||||
if (descriptors[name]?.enumerable)
|
||||
names2.push(name);
|
||||
}
|
||||
return names2;
|
||||
});
|
||||
const values = await Promise.all(names.map((name) => handle.evaluateHandle((object, name2) => object[name2], name)));
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
for (let i = 0; i < names.length; i++)
|
||||
map.set(names[i], values[i]);
|
||||
return map;
|
||||
}
|
||||
async releaseHandle(handle) {
|
||||
if (!handle._objectId)
|
||||
return;
|
||||
await this._session.send("script.disown", {
|
||||
target: this._target,
|
||||
handles: [handle._objectId]
|
||||
});
|
||||
}
|
||||
async nodeIdForElementHandle(handle) {
|
||||
const shared = await this._remoteValueForReference({ handle: handle._objectId });
|
||||
if (!("sharedId" in shared))
|
||||
throw new Error("Element is not a node");
|
||||
return {
|
||||
sharedId: shared.sharedId
|
||||
};
|
||||
}
|
||||
async remoteObjectForNodeId(context, nodeId) {
|
||||
const result = await this._remoteValueForReference(nodeId, true);
|
||||
if (!("handle" in result))
|
||||
throw new Error("Can't get remote object for nodeId");
|
||||
return createHandle(context, result);
|
||||
}
|
||||
async contentFrameIdForFrame(handle) {
|
||||
const contentWindow = await this._rawCallFunction("e => e.contentWindow", { handle: handle._objectId });
|
||||
if (contentWindow?.type === "window")
|
||||
return contentWindow.value.context;
|
||||
return null;
|
||||
}
|
||||
async frameIdForWindowHandle(handle) {
|
||||
if (!handle._objectId)
|
||||
throw new Error("JSHandle is not a DOM node handle");
|
||||
const contentWindow = await this._remoteValueForReference({ handle: handle._objectId });
|
||||
if (contentWindow.type === "window")
|
||||
return contentWindow.value.context;
|
||||
return null;
|
||||
}
|
||||
async _remoteValueForReference(reference, createHandle2) {
|
||||
return await this._rawCallFunction("e => e", reference, createHandle2);
|
||||
}
|
||||
async _rawCallFunction(functionDeclaration, arg, createHandle2) {
|
||||
const response = await this._session.send("script.callFunction", {
|
||||
functionDeclaration,
|
||||
target: this._target,
|
||||
arguments: [arg],
|
||||
// "Root" is necessary for the handle to be returned.
|
||||
resultOwnership: createHandle2 ? bidi.Script.ResultOwnership.Root : bidi.Script.ResultOwnership.None,
|
||||
serializationOptions: { maxObjectDepth: 0, maxDomDepth: 0 },
|
||||
awaitPromise: true,
|
||||
userActivation: true
|
||||
});
|
||||
if (response.type === "exception")
|
||||
throw new js.JavaScriptErrorInEvaluate(response.exceptionDetails.text);
|
||||
if (response.type === "success")
|
||||
return response.result;
|
||||
throw new js.JavaScriptErrorInEvaluate("Unexpected response type: " + JSON.stringify(response));
|
||||
}
|
||||
}
|
||||
function renderPreview(remoteObject) {
|
||||
if (remoteObject.type === "undefined")
|
||||
return "undefined";
|
||||
if (remoteObject.type === "null")
|
||||
return "null";
|
||||
if ("value" in remoteObject)
|
||||
return String(remoteObject.value);
|
||||
return `<${remoteObject.type}>`;
|
||||
}
|
||||
function remoteObjectValue(remoteObject) {
|
||||
if (remoteObject.type === "undefined")
|
||||
return void 0;
|
||||
if (remoteObject.type === "null")
|
||||
return null;
|
||||
if (remoteObject.type === "number" && typeof remoteObject.value === "string")
|
||||
return js.parseUnserializableValue(remoteObject.value);
|
||||
if ("value" in remoteObject)
|
||||
return remoteObject.value;
|
||||
return void 0;
|
||||
}
|
||||
function createHandle(context, remoteObject) {
|
||||
if (remoteObject.type === "node") {
|
||||
(0, import_utils.assert)(context instanceof dom.FrameExecutionContext);
|
||||
return new dom.ElementHandle(context, remoteObject.handle);
|
||||
}
|
||||
const objectId = "handle" in remoteObject ? remoteObject.handle : void 0;
|
||||
return new js.JSHandle(context, remoteObject.type, renderPreview(remoteObject), objectId, remoteObjectValue(remoteObject));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiExecutionContext,
|
||||
createHandle
|
||||
});
|
||||
130
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiFirefox.js
generated
vendored
Normal file
130
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiFirefox.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiFirefox_exports = {};
|
||||
__export(bidiFirefox_exports, {
|
||||
BidiFirefox: () => BidiFirefox
|
||||
});
|
||||
module.exports = __toCommonJS(bidiFirefox_exports);
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_ascii = require("../utils/ascii");
|
||||
var import_browserType = require("../browserType");
|
||||
var import_bidiBrowser = require("./bidiBrowser");
|
||||
var import_bidiConnection = require("./bidiConnection");
|
||||
var import_firefoxPrefs = require("./third_party/firefoxPrefs");
|
||||
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
||||
class BidiFirefox extends import_browserType.BrowserType {
|
||||
constructor(parent) {
|
||||
super(parent, "firefox");
|
||||
}
|
||||
executablePath() {
|
||||
return "";
|
||||
}
|
||||
async connectToTransport(transport, options) {
|
||||
return import_bidiBrowser.BidiBrowser.connect(this.attribution.playwright, transport, options);
|
||||
}
|
||||
doRewriteStartupLog(error) {
|
||||
if (!error.logs)
|
||||
return error;
|
||||
if (error.logs.includes(`as root in a regular user's session is not supported.`))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
||||
Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? " in your GitHub Actions workflow file" : ""} when running Playwright.`, 1);
|
||||
if (error.logs.includes("no DISPLAY environment variable specified"))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
||||
return error;
|
||||
}
|
||||
amendEnvironment(env) {
|
||||
if (!import_path.default.isAbsolute(import_os.default.homedir()))
|
||||
throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${import_os.default.platform() === "win32" ? "USERPROFILE" : "HOME"} to a relative path?`);
|
||||
env = {
|
||||
...env,
|
||||
"MOZ_CRASHREPORTER": "1",
|
||||
"MOZ_CRASHREPORTER_NO_REPORT": "1",
|
||||
"MOZ_CRASHREPORTER_SHUTDOWN": "1"
|
||||
};
|
||||
if (import_os.default.platform() === "linux") {
|
||||
return { ...env, SNAP_NAME: void 0, SNAP_INSTANCE_NAME: void 0 };
|
||||
}
|
||||
return env;
|
||||
}
|
||||
attemptToGracefullyCloseBrowser(transport) {
|
||||
this._attemptToGracefullyCloseBrowser(transport).catch(() => {
|
||||
});
|
||||
}
|
||||
async _attemptToGracefullyCloseBrowser(transport) {
|
||||
if (!transport.onmessage) {
|
||||
transport.send({ method: "session.new", params: { capabilities: {} }, id: import_bidiConnection.kShutdownSessionNewMessageId });
|
||||
await new Promise((resolve) => {
|
||||
transport.onmessage = (message) => {
|
||||
if (message.id === import_bidiConnection.kShutdownSessionNewMessageId)
|
||||
resolve(true);
|
||||
};
|
||||
});
|
||||
}
|
||||
transport.send({ method: "browser.close", params: {}, id: import_bidiConnection.kBrowserCloseMessageId });
|
||||
}
|
||||
supportsPipeTransport() {
|
||||
return false;
|
||||
}
|
||||
async prepareUserDataDir(options, userDataDir) {
|
||||
await (0, import_firefoxPrefs.createProfile)({
|
||||
path: userDataDir,
|
||||
preferences: options.firefoxUserPrefs || {}
|
||||
});
|
||||
}
|
||||
async defaultArgs(options, isPersistent, userDataDir) {
|
||||
const { args = [], headless } = options;
|
||||
const userDataDirArg = args.find((arg) => arg.startsWith("-profile") || arg.startsWith("--profile"));
|
||||
if (userDataDirArg)
|
||||
throw this._createUserDataDirArgMisuseError("--profile");
|
||||
if (args.find((arg) => !arg.startsWith("-")))
|
||||
throw new Error("Arguments can not specify page to be opened");
|
||||
const firefoxArguments = ["--remote-debugging-port=0"];
|
||||
if (headless)
|
||||
firefoxArguments.push("--headless");
|
||||
else
|
||||
firefoxArguments.push("--foreground");
|
||||
firefoxArguments.push(`--profile`, userDataDir);
|
||||
firefoxArguments.push(...args);
|
||||
return firefoxArguments;
|
||||
}
|
||||
async waitForReadyState(options, browserLogsCollector) {
|
||||
const result = new import_manualPromise.ManualPromise();
|
||||
browserLogsCollector.onMessage((message) => {
|
||||
const match = message.match(/WebDriver BiDi listening on (ws:\/\/.*)$/);
|
||||
if (match)
|
||||
result.resolve({ wsEndpoint: match[1] + "/session" });
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiFirefox
|
||||
});
|
||||
146
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiInput.js
generated
vendored
Normal file
146
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiInput.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiInput_exports = {};
|
||||
__export(bidiInput_exports, {
|
||||
RawKeyboardImpl: () => RawKeyboardImpl,
|
||||
RawMouseImpl: () => RawMouseImpl,
|
||||
RawTouchscreenImpl: () => RawTouchscreenImpl
|
||||
});
|
||||
module.exports = __toCommonJS(bidiInput_exports);
|
||||
var import_input = require("../input");
|
||||
var import_bidiKeyboard = require("./third_party/bidiKeyboard");
|
||||
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
||||
class RawKeyboardImpl {
|
||||
constructor(session) {
|
||||
this._session = session;
|
||||
}
|
||||
setSession(session) {
|
||||
this._session = session;
|
||||
}
|
||||
async keydown(progress, modifiers, keyName, description, autoRepeat) {
|
||||
keyName = (0, import_input.resolveSmartModifierString)(keyName);
|
||||
const actions = [];
|
||||
actions.push({ type: "keyDown", value: (0, import_bidiKeyboard.getBidiKeyValue)(keyName) });
|
||||
await this._performActions(progress, actions);
|
||||
}
|
||||
async keyup(progress, modifiers, keyName, description) {
|
||||
keyName = (0, import_input.resolveSmartModifierString)(keyName);
|
||||
const actions = [];
|
||||
actions.push({ type: "keyUp", value: (0, import_bidiKeyboard.getBidiKeyValue)(keyName) });
|
||||
await this._performActions(progress, actions);
|
||||
}
|
||||
async sendText(progress, text) {
|
||||
const actions = [];
|
||||
for (const char of text) {
|
||||
const value = (0, import_bidiKeyboard.getBidiKeyValue)(char);
|
||||
actions.push({ type: "keyDown", value });
|
||||
actions.push({ type: "keyUp", value });
|
||||
}
|
||||
await this._performActions(progress, actions);
|
||||
}
|
||||
async _performActions(progress, actions) {
|
||||
await progress.race(this._session.send("input.performActions", {
|
||||
context: this._session.sessionId,
|
||||
actions: [
|
||||
{
|
||||
type: "key",
|
||||
id: "pw_keyboard",
|
||||
actions
|
||||
}
|
||||
]
|
||||
}));
|
||||
}
|
||||
}
|
||||
class RawMouseImpl {
|
||||
constructor(session) {
|
||||
this._session = session;
|
||||
}
|
||||
async move(progress, x, y, button, buttons, modifiers, forClick) {
|
||||
await this._performActions(progress, [{ type: "pointerMove", x, y }]);
|
||||
}
|
||||
async down(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
await this._performActions(progress, [{ type: "pointerDown", button: toBidiButton(button) }]);
|
||||
}
|
||||
async up(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
await this._performActions(progress, [{ type: "pointerUp", button: toBidiButton(button) }]);
|
||||
}
|
||||
async wheel(progress, x, y, buttons, modifiers, deltaX, deltaY) {
|
||||
x = Math.floor(x);
|
||||
y = Math.floor(y);
|
||||
await progress.race(this._session.send("input.performActions", {
|
||||
context: this._session.sessionId,
|
||||
actions: [
|
||||
{
|
||||
type: "wheel",
|
||||
id: "pw_mouse_wheel",
|
||||
actions: [{ type: "scroll", x, y, deltaX, deltaY }]
|
||||
}
|
||||
]
|
||||
}));
|
||||
}
|
||||
async _performActions(progress, actions) {
|
||||
await progress.race(this._session.send("input.performActions", {
|
||||
context: this._session.sessionId,
|
||||
actions: [
|
||||
{
|
||||
type: "pointer",
|
||||
id: "pw_mouse",
|
||||
parameters: {
|
||||
pointerType: bidi.Input.PointerType.Mouse
|
||||
},
|
||||
actions
|
||||
}
|
||||
]
|
||||
}));
|
||||
}
|
||||
}
|
||||
class RawTouchscreenImpl {
|
||||
constructor(session) {
|
||||
this._session = session;
|
||||
}
|
||||
async tap(progress, x, y, modifiers) {
|
||||
}
|
||||
}
|
||||
function toBidiButton(button) {
|
||||
switch (button) {
|
||||
case "left":
|
||||
return 0;
|
||||
case "right":
|
||||
return 2;
|
||||
case "middle":
|
||||
return 1;
|
||||
}
|
||||
throw new Error("Unknown button: " + button);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
RawKeyboardImpl,
|
||||
RawMouseImpl,
|
||||
RawTouchscreenImpl
|
||||
});
|
||||
383
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiNetworkManager.js
generated
vendored
Normal file
383
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiNetworkManager.js
generated
vendored
Normal file
@@ -0,0 +1,383 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiNetworkManager_exports = {};
|
||||
__export(bidiNetworkManager_exports, {
|
||||
BidiNetworkManager: () => BidiNetworkManager,
|
||||
bidiBytesValueToString: () => bidiBytesValueToString
|
||||
});
|
||||
module.exports = __toCommonJS(bidiNetworkManager_exports);
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_cookieStore = require("../cookieStore");
|
||||
var network = __toESM(require("../network"));
|
||||
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
||||
class BidiNetworkManager {
|
||||
constructor(bidiSession, page) {
|
||||
this._userRequestInterceptionEnabled = false;
|
||||
this._protocolRequestInterceptionEnabled = false;
|
||||
this._attemptedAuthentications = /* @__PURE__ */ new Set();
|
||||
this._session = bidiSession;
|
||||
this._requests = /* @__PURE__ */ new Map();
|
||||
this._page = page;
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.beforeRequestSent", this._onBeforeRequestSent.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.responseStarted", this._onResponseStarted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.responseCompleted", this._onResponseCompleted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.fetchError", this._onFetchError.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "network.authRequired", this._onAuthRequired.bind(this))
|
||||
];
|
||||
}
|
||||
dispose() {
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
}
|
||||
_onBeforeRequestSent(param) {
|
||||
if (param.request.url.startsWith("data:"))
|
||||
return;
|
||||
const redirectedFrom = param.redirectCount ? this._requests.get(param.request.request) || null : null;
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : param.context ? this._page.frameManager.frame(param.context) : null;
|
||||
if (!frame)
|
||||
return;
|
||||
if (redirectedFrom)
|
||||
this._deleteRequest(redirectedFrom._id);
|
||||
let route;
|
||||
if (param.intercepts) {
|
||||
if (redirectedFrom) {
|
||||
let params = {};
|
||||
if (redirectedFrom._originalRequestRoute?._alreadyContinuedHeaders)
|
||||
params = toBidiRequestHeaders(redirectedFrom._originalRequestRoute._alreadyContinuedHeaders ?? []);
|
||||
this._session.sendMayFail("network.continueRequest", {
|
||||
request: param.request.request,
|
||||
...params
|
||||
});
|
||||
} else {
|
||||
route = new BidiRouteImpl(this._session, param.request.request);
|
||||
}
|
||||
}
|
||||
const request = new BidiRequest(frame, redirectedFrom, param, route);
|
||||
this._requests.set(request._id, request);
|
||||
this._page.frameManager.requestStarted(request.request, route);
|
||||
}
|
||||
_onResponseStarted(params) {
|
||||
const request = this._requests.get(params.request.request);
|
||||
if (!request)
|
||||
return;
|
||||
const getResponseBody = async () => {
|
||||
const { bytes } = await this._session.send("network.getData", { request: params.request.request, dataType: bidi.Network.DataType.Response });
|
||||
const encoding = bytes.type === "base64" ? "base64" : "utf8";
|
||||
return Buffer.from(bytes.value, encoding);
|
||||
};
|
||||
const timings = params.request.timings;
|
||||
const startTime = timings.requestTime;
|
||||
function relativeToStart(time) {
|
||||
if (!time)
|
||||
return -1;
|
||||
return time - startTime;
|
||||
}
|
||||
const timing = {
|
||||
startTime,
|
||||
requestStart: relativeToStart(timings.requestStart),
|
||||
responseStart: relativeToStart(timings.responseStart),
|
||||
domainLookupStart: relativeToStart(timings.dnsStart),
|
||||
domainLookupEnd: relativeToStart(timings.dnsEnd),
|
||||
connectStart: relativeToStart(timings.connectStart),
|
||||
secureConnectionStart: relativeToStart(timings.tlsStart),
|
||||
connectEnd: relativeToStart(timings.connectEnd)
|
||||
};
|
||||
const response = new network.Response(request.request, params.response.status, params.response.statusText, fromBidiHeaders(params.response.headers), timing, getResponseBody, false);
|
||||
response._serverAddrFinished();
|
||||
response._securityDetailsFinished();
|
||||
response.setRawResponseHeaders(null);
|
||||
response.setResponseHeadersSize(params.response.headersSize);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
}
|
||||
_onResponseCompleted(params) {
|
||||
const request = this._requests.get(params.request.request);
|
||||
if (!request)
|
||||
return;
|
||||
const response = request.request._existingResponse();
|
||||
response.setTransferSize(params.response.bodySize);
|
||||
response.setEncodedBodySize(params.response.bodySize);
|
||||
const isRedirected = response.status() >= 300 && response.status() <= 399;
|
||||
const responseEndTime = params.request.timings.responseEnd - response.timing().startTime;
|
||||
if (isRedirected) {
|
||||
response._requestFinished(responseEndTime);
|
||||
} else {
|
||||
this._deleteRequest(request._id);
|
||||
response._requestFinished(responseEndTime);
|
||||
}
|
||||
response._setHttpVersion(params.response.protocol);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
_onFetchError(params) {
|
||||
const request = this._requests.get(params.request.request);
|
||||
if (!request)
|
||||
return;
|
||||
this._deleteRequest(request._id);
|
||||
const response = request.request._existingResponse();
|
||||
if (response) {
|
||||
response.setTransferSize(null);
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished(-1);
|
||||
}
|
||||
request.request._setFailureText(params.errorText);
|
||||
this._page.frameManager.requestFailed(request.request, params.errorText === "NS_BINDING_ABORTED");
|
||||
}
|
||||
_onAuthRequired(params) {
|
||||
const isBasic = params.response.authChallenges?.some((challenge) => challenge.scheme.startsWith("Basic"));
|
||||
const credentials = this._page.browserContext._options.httpCredentials;
|
||||
if (isBasic && credentials && (!credentials.origin || new URL(params.request.url).origin.toLowerCase() === credentials.origin.toLowerCase())) {
|
||||
if (this._attemptedAuthentications.has(params.request.request)) {
|
||||
this._session.sendMayFail("network.continueWithAuth", {
|
||||
request: params.request.request,
|
||||
action: "cancel"
|
||||
});
|
||||
} else {
|
||||
this._attemptedAuthentications.add(params.request.request);
|
||||
this._session.sendMayFail("network.continueWithAuth", {
|
||||
request: params.request.request,
|
||||
action: "provideCredentials",
|
||||
credentials: {
|
||||
type: "password",
|
||||
username: credentials.username,
|
||||
password: credentials.password
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this._session.sendMayFail("network.continueWithAuth", {
|
||||
request: params.request.request,
|
||||
action: "cancel"
|
||||
});
|
||||
}
|
||||
}
|
||||
_deleteRequest(requestId) {
|
||||
this._requests.delete(requestId);
|
||||
this._attemptedAuthentications.delete(requestId);
|
||||
}
|
||||
async setRequestInterception(value) {
|
||||
this._userRequestInterceptionEnabled = value;
|
||||
await this._updateProtocolRequestInterception();
|
||||
}
|
||||
async setCredentials(credentials) {
|
||||
this._credentials = credentials;
|
||||
await this._updateProtocolRequestInterception();
|
||||
}
|
||||
async _updateProtocolRequestInterception(initial) {
|
||||
const enabled = this._userRequestInterceptionEnabled || !!this._credentials;
|
||||
if (enabled === this._protocolRequestInterceptionEnabled)
|
||||
return;
|
||||
this._protocolRequestInterceptionEnabled = enabled;
|
||||
if (initial && !enabled)
|
||||
return;
|
||||
const cachePromise = this._session.send("network.setCacheBehavior", { cacheBehavior: enabled ? "bypass" : "default" });
|
||||
let interceptPromise = Promise.resolve(void 0);
|
||||
if (enabled) {
|
||||
interceptPromise = this._session.send("network.addIntercept", {
|
||||
phases: [bidi.Network.InterceptPhase.AuthRequired, bidi.Network.InterceptPhase.BeforeRequestSent],
|
||||
urlPatterns: [{ type: "pattern" }]
|
||||
// urlPatterns: [{ type: 'string', pattern: '*' }],
|
||||
}).then((r) => {
|
||||
this._intercepId = r.intercept;
|
||||
});
|
||||
} else if (this._intercepId) {
|
||||
interceptPromise = this._session.send("network.removeIntercept", { intercept: this._intercepId });
|
||||
this._intercepId = void 0;
|
||||
}
|
||||
await Promise.all([cachePromise, interceptPromise]);
|
||||
}
|
||||
}
|
||||
class BidiRequest {
|
||||
constructor(frame, redirectedFrom, payload, route) {
|
||||
this._id = payload.request.request;
|
||||
if (redirectedFrom)
|
||||
redirectedFrom._redirectedTo = this;
|
||||
const postDataBuffer = null;
|
||||
this.request = new network.Request(
|
||||
frame._page.browserContext,
|
||||
frame,
|
||||
null,
|
||||
redirectedFrom ? redirectedFrom.request : null,
|
||||
payload.navigation ?? void 0,
|
||||
payload.request.url,
|
||||
resourceTypeFromBidi(payload.request.destination, payload.request.initiatorType, payload.initiator?.type),
|
||||
payload.request.method,
|
||||
postDataBuffer,
|
||||
fromBidiHeaders(payload.request.headers)
|
||||
);
|
||||
this.request.setRawRequestHeaders(null);
|
||||
this.request._setBodySize(payload.request.bodySize || 0);
|
||||
this._originalRequestRoute = route ?? redirectedFrom?._originalRequestRoute;
|
||||
route?._setRequest(this.request);
|
||||
}
|
||||
_finalRequest() {
|
||||
let request = this;
|
||||
while (request._redirectedTo)
|
||||
request = request._redirectedTo;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
class BidiRouteImpl {
|
||||
constructor(session, requestId) {
|
||||
this._session = session;
|
||||
this._requestId = requestId;
|
||||
}
|
||||
_setRequest(request) {
|
||||
this._request = request;
|
||||
}
|
||||
async continue(overrides) {
|
||||
let headers = overrides.headers || this._request.headers();
|
||||
if (overrides.postData && headers) {
|
||||
headers = headers.map((header) => {
|
||||
if (header.name.toLowerCase() === "content-length")
|
||||
return { name: header.name, value: overrides.postData.byteLength.toString() };
|
||||
return header;
|
||||
});
|
||||
}
|
||||
this._alreadyContinuedHeaders = headers;
|
||||
await this._session.sendMayFail("network.continueRequest", {
|
||||
request: this._requestId,
|
||||
url: overrides.url,
|
||||
method: overrides.method,
|
||||
...toBidiRequestHeaders(this._alreadyContinuedHeaders),
|
||||
body: overrides.postData ? { type: "base64", value: Buffer.from(overrides.postData).toString("base64") } : void 0
|
||||
});
|
||||
}
|
||||
async fulfill(response) {
|
||||
const base64body = response.isBase64 ? response.body : Buffer.from(response.body).toString("base64");
|
||||
await this._session.sendMayFail("network.provideResponse", {
|
||||
request: this._requestId,
|
||||
statusCode: response.status,
|
||||
reasonPhrase: network.statusText(response.status),
|
||||
...toBidiResponseHeaders(response.headers),
|
||||
body: { type: "base64", value: base64body }
|
||||
});
|
||||
}
|
||||
async abort(errorCode) {
|
||||
await this._session.sendMayFail("network.failRequest", {
|
||||
request: this._requestId
|
||||
});
|
||||
}
|
||||
}
|
||||
function fromBidiHeaders(bidiHeaders) {
|
||||
const result = [];
|
||||
for (const { name, value } of bidiHeaders)
|
||||
result.push({ name, value: bidiBytesValueToString(value) });
|
||||
return result;
|
||||
}
|
||||
function toBidiRequestHeaders(allHeaders) {
|
||||
const bidiHeaders = toBidiHeaders(allHeaders);
|
||||
return { headers: bidiHeaders };
|
||||
}
|
||||
function toBidiResponseHeaders(headers) {
|
||||
const setCookieHeaders = headers.filter((h) => h.name.toLowerCase() === "set-cookie");
|
||||
const otherHeaders = headers.filter((h) => h.name.toLowerCase() !== "set-cookie");
|
||||
const rawCookies = setCookieHeaders.map((h) => (0, import_cookieStore.parseRawCookie)(h.value));
|
||||
const cookies = rawCookies.filter(Boolean).map((c) => {
|
||||
return {
|
||||
...c,
|
||||
value: { type: "string", value: c.value },
|
||||
sameSite: toBidiSameSite(c.sameSite)
|
||||
};
|
||||
});
|
||||
return { cookies, headers: toBidiHeaders(otherHeaders) };
|
||||
}
|
||||
function toBidiHeaders(headers) {
|
||||
return headers.map(({ name, value }) => ({ name, value: { type: "string", value } }));
|
||||
}
|
||||
function bidiBytesValueToString(value) {
|
||||
if (value.type === "string")
|
||||
return value.value;
|
||||
if (value.type === "base64")
|
||||
return Buffer.from(value.type, "base64").toString("binary");
|
||||
return "unknown value type: " + value.type;
|
||||
}
|
||||
function toBidiSameSite(sameSite) {
|
||||
if (!sameSite)
|
||||
return void 0;
|
||||
if (sameSite === "Strict")
|
||||
return bidi.Network.SameSite.Strict;
|
||||
if (sameSite === "Lax")
|
||||
return bidi.Network.SameSite.Lax;
|
||||
return bidi.Network.SameSite.None;
|
||||
}
|
||||
function resourceTypeFromBidi(requestDestination, requestInitiatorType, eventInitiatorType) {
|
||||
switch (requestDestination) {
|
||||
case "audio":
|
||||
return "media";
|
||||
case "audioworklet":
|
||||
return "script";
|
||||
case "document":
|
||||
return "document";
|
||||
case "font":
|
||||
return "font";
|
||||
case "frame":
|
||||
return "document";
|
||||
case "iframe":
|
||||
return "document";
|
||||
case "image":
|
||||
return "image";
|
||||
case "object":
|
||||
return "object";
|
||||
case "paintworklet":
|
||||
return "script";
|
||||
case "script":
|
||||
return "script";
|
||||
case "serviceworker":
|
||||
return "script";
|
||||
case "sharedworker":
|
||||
return "script";
|
||||
case "style":
|
||||
return "stylesheet";
|
||||
case "track":
|
||||
return "texttrack";
|
||||
case "video":
|
||||
return "media";
|
||||
case "worker":
|
||||
return "script";
|
||||
case "":
|
||||
switch (requestInitiatorType) {
|
||||
case "fetch":
|
||||
return "fetch";
|
||||
case "font":
|
||||
return "font";
|
||||
case "xmlhttprequest":
|
||||
return "xhr";
|
||||
case null:
|
||||
return eventInitiatorType === "script" ? "xhr" : "document";
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
default:
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiNetworkManager,
|
||||
bidiBytesValueToString
|
||||
});
|
||||
102
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiOverCdp.js
generated
vendored
Normal file
102
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiOverCdp.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiOverCdp_exports = {};
|
||||
__export(bidiOverCdp_exports, {
|
||||
connectBidiOverCdp: () => connectBidiOverCdp
|
||||
});
|
||||
module.exports = __toCommonJS(bidiOverCdp_exports);
|
||||
var bidiMapper = __toESM(require("chromium-bidi/lib/cjs/bidiMapper/BidiMapper"));
|
||||
var bidiCdpConnection = __toESM(require("chromium-bidi/lib/cjs/cdp/CdpConnection"));
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
const bidiServerLogger = (prefix, ...args) => {
|
||||
import_debugLogger.debugLogger.log(prefix, args);
|
||||
};
|
||||
async function connectBidiOverCdp(cdp) {
|
||||
let server = void 0;
|
||||
const bidiTransport = new BidiTransportImpl();
|
||||
const bidiConnection = new BidiConnection(bidiTransport, () => server?.close());
|
||||
const cdpTransportImpl = new CdpTransportImpl(cdp);
|
||||
const cdpConnection = new bidiCdpConnection.MapperCdpConnection(cdpTransportImpl, bidiServerLogger);
|
||||
cdp.onclose = () => bidiConnection.onclose?.();
|
||||
server = await bidiMapper.BidiServer.createAndStart(
|
||||
bidiTransport,
|
||||
cdpConnection,
|
||||
await cdpConnection.createBrowserSession(),
|
||||
/* selfTargetId= */
|
||||
"",
|
||||
void 0,
|
||||
bidiServerLogger
|
||||
);
|
||||
return bidiConnection;
|
||||
}
|
||||
class BidiTransportImpl {
|
||||
setOnMessage(handler) {
|
||||
this._handler = handler;
|
||||
}
|
||||
sendMessage(message) {
|
||||
return this._bidiConnection.onmessage?.(message);
|
||||
}
|
||||
close() {
|
||||
this._bidiConnection.onclose?.();
|
||||
}
|
||||
}
|
||||
class BidiConnection {
|
||||
constructor(bidiTransport, closeCallback) {
|
||||
this._bidiTransport = bidiTransport;
|
||||
this._bidiTransport._bidiConnection = this;
|
||||
this._closeCallback = closeCallback;
|
||||
}
|
||||
send(s) {
|
||||
this._bidiTransport._handler?.(s);
|
||||
}
|
||||
close() {
|
||||
this._closeCallback();
|
||||
}
|
||||
}
|
||||
class CdpTransportImpl {
|
||||
constructor(connection) {
|
||||
this._connection = connection;
|
||||
this._connection.onmessage = (message) => {
|
||||
this._handler?.(JSON.stringify(message));
|
||||
};
|
||||
}
|
||||
setOnMessage(handler) {
|
||||
this._handler = handler;
|
||||
}
|
||||
sendMessage(message) {
|
||||
return this._connection.send(JSON.parse(message));
|
||||
}
|
||||
close() {
|
||||
this._connection.close();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
connectBidiOverCdp
|
||||
});
|
||||
572
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiPage.js
generated
vendored
Normal file
572
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiPage.js
generated
vendored
Normal file
@@ -0,0 +1,572 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiPage_exports = {};
|
||||
__export(bidiPage_exports, {
|
||||
BidiPage: () => BidiPage,
|
||||
kPlaywrightBindingChannel: () => kPlaywrightBindingChannel
|
||||
});
|
||||
module.exports = __toCommonJS(bidiPage_exports);
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var dialog = __toESM(require("../dialog"));
|
||||
var dom = __toESM(require("../dom"));
|
||||
var import_bidiBrowser = require("./bidiBrowser");
|
||||
var import_page = require("../page");
|
||||
var import_bidiExecutionContext = require("./bidiExecutionContext");
|
||||
var import_bidiInput = require("./bidiInput");
|
||||
var import_bidiNetworkManager = require("./bidiNetworkManager");
|
||||
var import_bidiPdf = require("./bidiPdf");
|
||||
var bidi = __toESM(require("./third_party/bidiProtocol"));
|
||||
var network = __toESM(require("../network"));
|
||||
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
||||
const kPlaywrightBindingChannel = "playwrightChannel";
|
||||
class BidiPage {
|
||||
constructor(browserContext, bidiSession, opener) {
|
||||
this._realmToWorkerContext = /* @__PURE__ */ new Map();
|
||||
this._sessionListeners = [];
|
||||
this._initScriptIds = /* @__PURE__ */ new Map();
|
||||
this._session = bidiSession;
|
||||
this._opener = opener;
|
||||
this.rawKeyboard = new import_bidiInput.RawKeyboardImpl(bidiSession);
|
||||
this.rawMouse = new import_bidiInput.RawMouseImpl(bidiSession);
|
||||
this.rawTouchscreen = new import_bidiInput.RawTouchscreenImpl(bidiSession);
|
||||
this._realmToContext = /* @__PURE__ */ new Map();
|
||||
this._page = new import_page.Page(this, browserContext);
|
||||
this._browserContext = browserContext;
|
||||
this._networkManager = new import_bidiNetworkManager.BidiNetworkManager(this._session, this._page);
|
||||
this._pdf = new import_bidiPdf.BidiPDF(this._session);
|
||||
this._page.on(import_page.Page.Events.FrameDetached, (frame) => this._removeContextsForFrame(frame, false));
|
||||
this._sessionListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.realmCreated", this._onRealmCreated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "script.message", this._onScriptMessage.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.contextDestroyed", this._onBrowsingContextDestroyed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationStarted", this._onNavigationStarted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationCommitted", this._onNavigationCommitted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationAborted", this._onNavigationAborted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.navigationFailed", this._onNavigationFailed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.fragmentNavigated", this._onFragmentNavigated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.historyUpdated", this._onHistoryUpdated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.domContentLoaded", this._onDomContentLoaded.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.load", this._onLoad.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadWillBegin", this._onDownloadWillBegin.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadEnd", this._onDownloadEnded.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(bidiSession, "input.fileDialogOpened", this._onFileDialogOpened.bind(this))
|
||||
];
|
||||
this._initialize().then(
|
||||
() => this._page.reportAsNew(this._opener?._page),
|
||||
(error) => this._page.reportAsNew(this._opener?._page, error)
|
||||
);
|
||||
}
|
||||
async _initialize() {
|
||||
this._onFrameAttached(this._session.sessionId, null);
|
||||
await Promise.all([
|
||||
this.updateHttpCredentials(),
|
||||
this.updateRequestInterception()
|
||||
// If the page is created by the Playwright client's call, some initialization
|
||||
// may be pending. Wait for it to complete before reporting the page as new.
|
||||
]);
|
||||
}
|
||||
didClose() {
|
||||
this._session.dispose();
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._sessionListeners);
|
||||
this._page._didClose();
|
||||
}
|
||||
_onFrameAttached(frameId, parentFrameId) {
|
||||
return this._page.frameManager.frameAttached(frameId, parentFrameId);
|
||||
}
|
||||
_removeContextsForFrame(frame, notifyFrame) {
|
||||
for (const [contextId, context] of this._realmToContext) {
|
||||
if (context.frame === frame) {
|
||||
this._realmToContext.delete(contextId);
|
||||
if (notifyFrame)
|
||||
frame._contextDestroyed(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
_onRealmCreated(realmInfo) {
|
||||
if (realmInfo.type === "dedicated-worker") {
|
||||
const delegate2 = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
|
||||
const worker = new import_page.Worker(this._page, realmInfo.origin);
|
||||
this._realmToWorkerContext.set(realmInfo.realm, worker.createExecutionContext(delegate2));
|
||||
worker.workerScriptLoaded();
|
||||
this._page.addWorker(realmInfo.realm, worker);
|
||||
return;
|
||||
}
|
||||
if (this._realmToContext.has(realmInfo.realm))
|
||||
return;
|
||||
if (realmInfo.type !== "window")
|
||||
return;
|
||||
const frame = this._page.frameManager.frame(realmInfo.context);
|
||||
if (!frame)
|
||||
return;
|
||||
let worldName;
|
||||
if (!realmInfo.sandbox) {
|
||||
worldName = "main";
|
||||
this._touchUtilityWorld(realmInfo.context);
|
||||
} else if (realmInfo.sandbox === UTILITY_WORLD_NAME) {
|
||||
worldName = "utility";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const delegate = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
|
||||
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
||||
frame._contextCreated(worldName, context);
|
||||
this._realmToContext.set(realmInfo.realm, context);
|
||||
}
|
||||
async _touchUtilityWorld(context) {
|
||||
await this._session.sendMayFail("script.evaluate", {
|
||||
expression: "1 + 1",
|
||||
target: {
|
||||
context,
|
||||
sandbox: UTILITY_WORLD_NAME
|
||||
},
|
||||
serializationOptions: {
|
||||
maxObjectDepth: 10,
|
||||
maxDomDepth: 10
|
||||
},
|
||||
awaitPromise: true,
|
||||
userActivation: true
|
||||
});
|
||||
}
|
||||
_onRealmDestroyed(params) {
|
||||
const context = this._realmToContext.get(params.realm);
|
||||
if (context) {
|
||||
this._realmToContext.delete(params.realm);
|
||||
context.frame._contextDestroyed(context);
|
||||
return true;
|
||||
}
|
||||
const existed = this._realmToWorkerContext.delete(params.realm);
|
||||
if (existed) {
|
||||
this._page.removeWorker(params.realm);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// TODO: route the message directly to the browser
|
||||
_onBrowsingContextDestroyed(params) {
|
||||
this._browserContext._browser._onBrowsingContextDestroyed(params);
|
||||
}
|
||||
_onNavigationStarted(params) {
|
||||
const frameId = params.context;
|
||||
this._page.frameManager.frameRequestedNavigation(frameId, params.navigation);
|
||||
}
|
||||
_onNavigationCommitted(params) {
|
||||
const frameId = params.context;
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(
|
||||
frameId,
|
||||
params.url,
|
||||
"",
|
||||
params.navigation,
|
||||
/* initial */
|
||||
false
|
||||
);
|
||||
}
|
||||
_onDomContentLoaded(params) {
|
||||
const frameId = params.context;
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, "domcontentloaded");
|
||||
}
|
||||
_onLoad(params) {
|
||||
this._page.frameManager.frameLifecycleEvent(params.context, "load");
|
||||
}
|
||||
_onNavigationAborted(params) {
|
||||
this._page.frameManager.frameAbortedNavigation(params.context, "Navigation aborted", params.navigation || void 0);
|
||||
}
|
||||
_onNavigationFailed(params) {
|
||||
this._page.frameManager.frameAbortedNavigation(params.context, "Navigation failed", params.navigation || void 0);
|
||||
}
|
||||
_onFragmentNavigated(params) {
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
|
||||
}
|
||||
_onHistoryUpdated(params) {
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(params.context, params.url);
|
||||
}
|
||||
_onUserPromptOpened(event) {
|
||||
this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
|
||||
this._page,
|
||||
event.type,
|
||||
event.message,
|
||||
async (accept, userText) => {
|
||||
await this._session.send("browsingContext.handleUserPrompt", { context: event.context, accept, userText });
|
||||
},
|
||||
event.defaultValue
|
||||
));
|
||||
}
|
||||
_onDownloadWillBegin(event) {
|
||||
if (!event.navigation)
|
||||
return;
|
||||
this._page.frameManager.frameAbortedNavigation(event.context, "Download is starting");
|
||||
let originPage = this._page.initializedOrUndefined();
|
||||
if (!originPage && this._opener)
|
||||
originPage = this._opener._page.initializedOrUndefined();
|
||||
if (!originPage)
|
||||
return;
|
||||
this._browserContext._browser._downloadCreated(originPage, event.navigation, event.url, event.suggestedFilename);
|
||||
}
|
||||
_onDownloadEnded(event) {
|
||||
if (!event.navigation)
|
||||
return;
|
||||
this._browserContext._browser._downloadFinished(event.navigation, event.status === "canceled" ? "canceled" : void 0);
|
||||
}
|
||||
_onLogEntryAdded(params) {
|
||||
if (params.type === "javascript" && params.level === "error") {
|
||||
let errorName = "";
|
||||
let errorMessage;
|
||||
if (params.text?.includes(": ")) {
|
||||
const index = params.text.indexOf(": ");
|
||||
errorName = params.text.substring(0, index);
|
||||
errorMessage = params.text.substring(index + 2);
|
||||
} else {
|
||||
errorMessage = params.text ?? void 0;
|
||||
}
|
||||
const error = new Error(errorMessage);
|
||||
error.name = errorName;
|
||||
error.stack = `${params.text}
|
||||
${params.stackTrace?.callFrames.map((f) => {
|
||||
const location2 = `${f.url}:${f.lineNumber + 1}:${f.columnNumber + 1}`;
|
||||
return f.functionName ? ` at ${f.functionName} (${location2})` : ` at ${location2}`;
|
||||
}).join("\n")}`;
|
||||
this._page.addPageError(error);
|
||||
return;
|
||||
}
|
||||
if (params.type !== "console")
|
||||
return;
|
||||
const entry = params;
|
||||
const context = this._realmToContext.get(params.source.realm) ?? this._realmToWorkerContext.get(params.source.realm);
|
||||
if (!context)
|
||||
return;
|
||||
const callFrame = params.stackTrace?.callFrames[0];
|
||||
const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
|
||||
this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
|
||||
}
|
||||
async _onFileDialogOpened(params) {
|
||||
if (!params.element)
|
||||
return;
|
||||
const frame = this._page.frameManager.frame(params.context);
|
||||
if (!frame)
|
||||
return;
|
||||
const executionContext = await frame._mainContext();
|
||||
const handle = await toBidiExecutionContext(executionContext).remoteObjectForNodeId(executionContext, { sharedId: params.element.sharedId });
|
||||
await this._page._onFileChooserOpened(handle);
|
||||
}
|
||||
async navigateFrame(frame, url, referrer) {
|
||||
const { navigation } = await this._session.send("browsingContext.navigate", {
|
||||
context: frame._id,
|
||||
url
|
||||
});
|
||||
return { newDocumentId: navigation || void 0 };
|
||||
}
|
||||
async updateExtraHTTPHeaders() {
|
||||
const allHeaders = network.mergeHeaders([
|
||||
this._browserContext._options.extraHTTPHeaders,
|
||||
this._page.extraHTTPHeaders()
|
||||
]);
|
||||
await this._session.send("network.setExtraHeaders", {
|
||||
headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
|
||||
contexts: [this._session.sessionId]
|
||||
});
|
||||
}
|
||||
async updateEmulateMedia() {
|
||||
}
|
||||
async updateUserAgent() {
|
||||
}
|
||||
async bringToFront() {
|
||||
await this._session.send("browsingContext.activate", {
|
||||
context: this._session.sessionId
|
||||
});
|
||||
}
|
||||
async updateEmulatedViewportSize() {
|
||||
const options = this._browserContext._options;
|
||||
const emulatedSize = this._page.emulatedSize();
|
||||
if (!emulatedSize)
|
||||
return;
|
||||
const viewportSize = emulatedSize.viewport;
|
||||
await Promise.all([
|
||||
this._session.send("browsingContext.setViewport", {
|
||||
context: this._session.sessionId,
|
||||
viewport: {
|
||||
width: viewportSize.width,
|
||||
height: viewportSize.height
|
||||
},
|
||||
devicePixelRatio: options.deviceScaleFactor || 1
|
||||
}),
|
||||
this._session.send("emulation.setScreenOrientationOverride", {
|
||||
contexts: [this._session.sessionId],
|
||||
screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile, viewportSize)
|
||||
})
|
||||
]);
|
||||
}
|
||||
async updateRequestInterception() {
|
||||
await this._networkManager.setRequestInterception(this._page.needsRequestInterception());
|
||||
}
|
||||
async updateOffline() {
|
||||
}
|
||||
async updateHttpCredentials() {
|
||||
await this._networkManager.setCredentials(this._browserContext._options.httpCredentials);
|
||||
}
|
||||
async updateFileChooserInterception() {
|
||||
}
|
||||
async reload() {
|
||||
await this._session.send("browsingContext.reload", {
|
||||
context: this._session.sessionId,
|
||||
// ignoreCache: true,
|
||||
wait: bidi.BrowsingContext.ReadinessState.Interactive
|
||||
});
|
||||
}
|
||||
async goBack() {
|
||||
return await this._session.send("browsingContext.traverseHistory", {
|
||||
context: this._session.sessionId,
|
||||
delta: -1
|
||||
}).then(() => true).catch(() => false);
|
||||
}
|
||||
async goForward() {
|
||||
return await this._session.send("browsingContext.traverseHistory", {
|
||||
context: this._session.sessionId,
|
||||
delta: 1
|
||||
}).then(() => true).catch(() => false);
|
||||
}
|
||||
async requestGC() {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
async _onScriptMessage(event) {
|
||||
if (event.channel !== kPlaywrightBindingChannel)
|
||||
return;
|
||||
const pageOrError = await this._page.waitForInitializedOrError();
|
||||
if (pageOrError instanceof Error)
|
||||
return;
|
||||
const context = this._realmToContext.get(event.source.realm);
|
||||
if (!context)
|
||||
return;
|
||||
if (event.data.type !== "string")
|
||||
return;
|
||||
await this._page.onBindingCalled(event.data.value, context);
|
||||
}
|
||||
async addInitScript(initScript) {
|
||||
const { script } = await this._session.send("script.addPreloadScript", {
|
||||
// TODO: remove function call from the source.
|
||||
functionDeclaration: `() => { return ${initScript.source} }`,
|
||||
// TODO: push to iframes?
|
||||
contexts: [this._session.sessionId]
|
||||
});
|
||||
this._initScriptIds.set(initScript, script);
|
||||
}
|
||||
async removeInitScripts(initScripts) {
|
||||
const ids = [];
|
||||
for (const script of initScripts) {
|
||||
const id = this._initScriptIds.get(script);
|
||||
if (id)
|
||||
ids.push(id);
|
||||
this._initScriptIds.delete(script);
|
||||
}
|
||||
await Promise.all(ids.map((script) => this._session.send("script.removePreloadScript", { script })));
|
||||
}
|
||||
async closePage(runBeforeUnload) {
|
||||
if (runBeforeUnload) {
|
||||
this._session.sendMayFail("browsingContext.close", {
|
||||
context: this._session.sessionId,
|
||||
promptUnload: runBeforeUnload
|
||||
});
|
||||
} else {
|
||||
await this._session.send("browsingContext.close", {
|
||||
context: this._session.sessionId,
|
||||
promptUnload: runBeforeUnload
|
||||
});
|
||||
}
|
||||
}
|
||||
async setBackgroundColor(color) {
|
||||
if (color)
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) {
|
||||
const rect = documentRect || viewportRect;
|
||||
const { data } = await progress.race(this._session.send("browsingContext.captureScreenshot", {
|
||||
context: this._session.sessionId,
|
||||
format: {
|
||||
type: `image/${format === "png" ? "png" : "jpeg"}`,
|
||||
quality: quality ? quality / 100 : 0.8
|
||||
},
|
||||
origin: documentRect ? "document" : "viewport",
|
||||
clip: {
|
||||
type: "box",
|
||||
...rect
|
||||
}
|
||||
}));
|
||||
return Buffer.from(data, "base64");
|
||||
}
|
||||
async getContentFrame(handle) {
|
||||
const executionContext = toBidiExecutionContext(handle._context);
|
||||
const frameId = await executionContext.contentFrameIdForFrame(handle);
|
||||
if (!frameId)
|
||||
return null;
|
||||
return this._page.frameManager.frame(frameId);
|
||||
}
|
||||
async getOwnerFrame(handle) {
|
||||
const windowHandle = await handle.evaluateHandle((node) => {
|
||||
const doc = node.ownerDocument ?? node;
|
||||
return doc.defaultView;
|
||||
});
|
||||
if (!windowHandle)
|
||||
return null;
|
||||
const executionContext = toBidiExecutionContext(handle._context);
|
||||
return executionContext.frameIdForWindowHandle(windowHandle);
|
||||
}
|
||||
async getBoundingBox(handle) {
|
||||
const box = await handle.evaluate((element) => {
|
||||
if (!(element instanceof Element))
|
||||
return null;
|
||||
const rect = element.getBoundingClientRect();
|
||||
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
|
||||
});
|
||||
if (!box)
|
||||
return null;
|
||||
const position = await this._framePosition(handle._frame);
|
||||
if (!position)
|
||||
return null;
|
||||
box.x += position.x;
|
||||
box.y += position.y;
|
||||
return box;
|
||||
}
|
||||
// TODO: move to Frame.
|
||||
async _framePosition(frame) {
|
||||
if (frame === this._page.mainFrame())
|
||||
return { x: 0, y: 0 };
|
||||
const element = await frame.frameElement();
|
||||
const box = await element.boundingBox();
|
||||
if (!box)
|
||||
return null;
|
||||
const style = await element.evaluateInUtility(([injected, iframe]) => injected.describeIFrameStyle(iframe), {}).catch((e) => "error:notconnected");
|
||||
if (style === "error:notconnected" || style === "transformed")
|
||||
return null;
|
||||
box.x += style.left;
|
||||
box.y += style.top;
|
||||
return box;
|
||||
}
|
||||
async scrollRectIntoViewIfNeeded(handle, rect) {
|
||||
return await handle.evaluateInUtility(([injected, node]) => {
|
||||
node.scrollIntoView({
|
||||
block: "center",
|
||||
inline: "center",
|
||||
behavior: "instant"
|
||||
});
|
||||
}, null).then(() => "done").catch((e) => {
|
||||
if (e instanceof Error && e.message.includes("Node is detached from document"))
|
||||
return "error:notconnected";
|
||||
if (e instanceof Error && e.message.includes("Node does not have a layout object"))
|
||||
return "error:notvisible";
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
async setScreencastOptions(options) {
|
||||
}
|
||||
rafCountForStablePosition() {
|
||||
return 1;
|
||||
}
|
||||
async getContentQuads(handle) {
|
||||
const quads = await handle.evaluateInUtility(([injected, node]) => {
|
||||
if (!node.isConnected)
|
||||
return "error:notconnected";
|
||||
const rects = node.getClientRects();
|
||||
if (!rects)
|
||||
return null;
|
||||
return [...rects].map((rect) => [
|
||||
{ x: rect.left, y: rect.top },
|
||||
{ x: rect.right, y: rect.top },
|
||||
{ x: rect.right, y: rect.bottom },
|
||||
{ x: rect.left, y: rect.bottom }
|
||||
]);
|
||||
}, null);
|
||||
if (!quads || quads === "error:notconnected")
|
||||
return quads;
|
||||
const position = await this._framePosition(handle._frame);
|
||||
if (!position)
|
||||
return null;
|
||||
quads.forEach((quad) => quad.forEach((point) => {
|
||||
point.x += position.x;
|
||||
point.y += position.y;
|
||||
}));
|
||||
return quads;
|
||||
}
|
||||
async setInputFilePaths(handle, paths) {
|
||||
const fromContext = toBidiExecutionContext(handle._context);
|
||||
await this._session.send("input.setFiles", {
|
||||
context: this._session.sessionId,
|
||||
element: await fromContext.nodeIdForElementHandle(handle),
|
||||
files: paths
|
||||
});
|
||||
}
|
||||
async adoptElementHandle(handle, to) {
|
||||
const fromContext = toBidiExecutionContext(handle._context);
|
||||
const nodeId = await fromContext.nodeIdForElementHandle(handle);
|
||||
const executionContext = toBidiExecutionContext(to);
|
||||
return await executionContext.remoteObjectForNodeId(to, nodeId);
|
||||
}
|
||||
async inputActionEpilogue() {
|
||||
}
|
||||
async resetForReuse(progress) {
|
||||
}
|
||||
async pdf(options) {
|
||||
return this._pdf.generate(options);
|
||||
}
|
||||
async getFrameElement(frame) {
|
||||
const parent = frame.parentFrame();
|
||||
if (!parent)
|
||||
throw new Error("Frame has been detached.");
|
||||
const parentContext = await parent._mainContext();
|
||||
const list = await parentContext.evaluateHandle(() => {
|
||||
return [...document.querySelectorAll("iframe,frame")];
|
||||
});
|
||||
const length = await list.evaluate((list2) => list2.length);
|
||||
let foundElement = null;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const element = await list.evaluateHandle((list2, i2) => list2[i2], i);
|
||||
const candidate = await element.contentFrame();
|
||||
if (frame === candidate) {
|
||||
foundElement = element;
|
||||
break;
|
||||
} else {
|
||||
element.dispose();
|
||||
}
|
||||
}
|
||||
list.dispose();
|
||||
if (!foundElement)
|
||||
throw new Error("Frame has been detached.");
|
||||
return foundElement;
|
||||
}
|
||||
shouldToggleStyleSheetToSyncAnimations() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function toBidiExecutionContext(executionContext) {
|
||||
return executionContext.delegate;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiPage,
|
||||
kPlaywrightBindingChannel
|
||||
});
|
||||
106
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiPdf.js
generated
vendored
Normal file
106
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/bidiPdf.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiPdf_exports = {};
|
||||
__export(bidiPdf_exports, {
|
||||
BidiPDF: () => BidiPDF
|
||||
});
|
||||
module.exports = __toCommonJS(bidiPdf_exports);
|
||||
var import_utils = require("../../utils");
|
||||
const PagePaperFormats = {
|
||||
letter: { width: 8.5, height: 11 },
|
||||
legal: { width: 8.5, height: 14 },
|
||||
tabloid: { width: 11, height: 17 },
|
||||
ledger: { width: 17, height: 11 },
|
||||
a0: { width: 33.1, height: 46.8 },
|
||||
a1: { width: 23.4, height: 33.1 },
|
||||
a2: { width: 16.54, height: 23.4 },
|
||||
a3: { width: 11.7, height: 16.54 },
|
||||
a4: { width: 8.27, height: 11.7 },
|
||||
a5: { width: 5.83, height: 8.27 },
|
||||
a6: { width: 4.13, height: 5.83 }
|
||||
};
|
||||
const unitToPixels = {
|
||||
"px": 1,
|
||||
"in": 96,
|
||||
"cm": 37.8,
|
||||
"mm": 3.78
|
||||
};
|
||||
function convertPrintParameterToInches(text) {
|
||||
if (text === void 0)
|
||||
return void 0;
|
||||
let unit = text.substring(text.length - 2).toLowerCase();
|
||||
let valueText = "";
|
||||
if (unitToPixels.hasOwnProperty(unit)) {
|
||||
valueText = text.substring(0, text.length - 2);
|
||||
} else {
|
||||
unit = "px";
|
||||
valueText = text;
|
||||
}
|
||||
const value = Number(valueText);
|
||||
(0, import_utils.assert)(!isNaN(value), "Failed to parse parameter value: " + text);
|
||||
const pixels = value * unitToPixels[unit];
|
||||
return pixels / 96;
|
||||
}
|
||||
class BidiPDF {
|
||||
constructor(session) {
|
||||
this._session = session;
|
||||
}
|
||||
async generate(options) {
|
||||
const {
|
||||
scale = 1,
|
||||
printBackground = false,
|
||||
landscape = false,
|
||||
pageRanges = "",
|
||||
margin = {}
|
||||
} = options;
|
||||
let paperWidth = 8.5;
|
||||
let paperHeight = 11;
|
||||
if (options.format) {
|
||||
const format = PagePaperFormats[options.format.toLowerCase()];
|
||||
(0, import_utils.assert)(format, "Unknown paper format: " + options.format);
|
||||
paperWidth = format.width;
|
||||
paperHeight = format.height;
|
||||
} else {
|
||||
paperWidth = convertPrintParameterToInches(options.width) || paperWidth;
|
||||
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
|
||||
}
|
||||
const { data } = await this._session.send("browsingContext.print", {
|
||||
context: this._session.sessionId,
|
||||
background: printBackground,
|
||||
margin: {
|
||||
bottom: convertPrintParameterToInches(margin.bottom) || 0,
|
||||
left: convertPrintParameterToInches(margin.left) || 0,
|
||||
right: convertPrintParameterToInches(margin.right) || 0,
|
||||
top: convertPrintParameterToInches(margin.top) || 0
|
||||
},
|
||||
orientation: landscape ? "landscape" : "portrait",
|
||||
page: {
|
||||
width: paperWidth,
|
||||
height: paperHeight
|
||||
},
|
||||
pageRanges: pageRanges ? pageRanges.split(",").map((r) => r.trim()) : void 0,
|
||||
scale
|
||||
});
|
||||
return Buffer.from(data, "base64");
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiPDF
|
||||
});
|
||||
22
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiCommands.d.js
generated
vendored
Normal file
22
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiCommands.d.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiCommands_d_exports = {};
|
||||
module.exports = __toCommonJS(bidiCommands_d_exports);
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
98
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiDeserializer.js
generated
vendored
Normal file
98
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiDeserializer.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiDeserializer_exports = {};
|
||||
__export(bidiDeserializer_exports, {
|
||||
BidiDeserializer: () => BidiDeserializer
|
||||
});
|
||||
module.exports = __toCommonJS(bidiDeserializer_exports);
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
class BidiDeserializer {
|
||||
static deserialize(result) {
|
||||
if (!result)
|
||||
return void 0;
|
||||
switch (result.type) {
|
||||
case "array":
|
||||
return result.value?.map((value) => {
|
||||
return BidiDeserializer.deserialize(value);
|
||||
});
|
||||
case "set":
|
||||
return result.value?.reduce((acc, value) => {
|
||||
return acc.add(BidiDeserializer.deserialize(value));
|
||||
}, /* @__PURE__ */ new Set());
|
||||
case "object":
|
||||
return result.value?.reduce((acc, tuple) => {
|
||||
const { key, value } = BidiDeserializer._deserializeTuple(tuple);
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
case "map":
|
||||
return result.value?.reduce((acc, tuple) => {
|
||||
const { key, value } = BidiDeserializer._deserializeTuple(tuple);
|
||||
return acc.set(key, value);
|
||||
}, /* @__PURE__ */ new Map());
|
||||
case "promise":
|
||||
return {};
|
||||
case "regexp":
|
||||
return new RegExp(result.value.pattern, result.value.flags);
|
||||
case "date":
|
||||
return new Date(result.value);
|
||||
case "undefined":
|
||||
return void 0;
|
||||
case "null":
|
||||
return null;
|
||||
case "number":
|
||||
return BidiDeserializer._deserializeNumber(result.value);
|
||||
case "bigint":
|
||||
return BigInt(result.value);
|
||||
case "boolean":
|
||||
return Boolean(result.value);
|
||||
case "string":
|
||||
return result.value;
|
||||
}
|
||||
throw new Error(`Deserialization of type ${result.type} not supported.`);
|
||||
}
|
||||
static _deserializeNumber(value) {
|
||||
switch (value) {
|
||||
case "-0":
|
||||
return -0;
|
||||
case "NaN":
|
||||
return NaN;
|
||||
case "Infinity":
|
||||
return Infinity;
|
||||
case "-Infinity":
|
||||
return -Infinity;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
static _deserializeTuple([serializedKey, serializedValue]) {
|
||||
const key = typeof serializedKey === "string" ? serializedKey : BidiDeserializer.deserialize(serializedKey);
|
||||
const value = BidiDeserializer.deserialize(serializedValue);
|
||||
return { key, value };
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiDeserializer
|
||||
});
|
||||
256
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiKeyboard.js
generated
vendored
Normal file
256
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiKeyboard.js
generated
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiKeyboard_exports = {};
|
||||
__export(bidiKeyboard_exports, {
|
||||
getBidiKeyValue: () => getBidiKeyValue
|
||||
});
|
||||
module.exports = __toCommonJS(bidiKeyboard_exports);
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
const getBidiKeyValue = (keyName) => {
|
||||
switch (keyName) {
|
||||
case "\r":
|
||||
case "\n":
|
||||
keyName = "Enter";
|
||||
break;
|
||||
}
|
||||
if ([...keyName].length === 1) {
|
||||
return keyName;
|
||||
}
|
||||
switch (keyName) {
|
||||
case "Cancel":
|
||||
return "\uE001";
|
||||
case "Help":
|
||||
return "\uE002";
|
||||
case "Backspace":
|
||||
return "\uE003";
|
||||
case "Tab":
|
||||
return "\uE004";
|
||||
case "Clear":
|
||||
return "\uE005";
|
||||
case "Enter":
|
||||
return "\uE007";
|
||||
case "Shift":
|
||||
case "ShiftLeft":
|
||||
return "\uE008";
|
||||
case "Control":
|
||||
case "ControlLeft":
|
||||
return "\uE009";
|
||||
case "Alt":
|
||||
case "AltLeft":
|
||||
return "\uE00A";
|
||||
case "Pause":
|
||||
return "\uE00B";
|
||||
case "Escape":
|
||||
return "\uE00C";
|
||||
case "PageUp":
|
||||
return "\uE00E";
|
||||
case "PageDown":
|
||||
return "\uE00F";
|
||||
case "End":
|
||||
return "\uE010";
|
||||
case "Home":
|
||||
return "\uE011";
|
||||
case "ArrowLeft":
|
||||
return "\uE012";
|
||||
case "ArrowUp":
|
||||
return "\uE013";
|
||||
case "ArrowRight":
|
||||
return "\uE014";
|
||||
case "ArrowDown":
|
||||
return "\uE015";
|
||||
case "Insert":
|
||||
return "\uE016";
|
||||
case "Delete":
|
||||
return "\uE017";
|
||||
case "NumpadEqual":
|
||||
return "\uE019";
|
||||
case "Numpad0":
|
||||
return "\uE01A";
|
||||
case "Numpad1":
|
||||
return "\uE01B";
|
||||
case "Numpad2":
|
||||
return "\uE01C";
|
||||
case "Numpad3":
|
||||
return "\uE01D";
|
||||
case "Numpad4":
|
||||
return "\uE01E";
|
||||
case "Numpad5":
|
||||
return "\uE01F";
|
||||
case "Numpad6":
|
||||
return "\uE020";
|
||||
case "Numpad7":
|
||||
return "\uE021";
|
||||
case "Numpad8":
|
||||
return "\uE022";
|
||||
case "Numpad9":
|
||||
return "\uE023";
|
||||
case "NumpadMultiply":
|
||||
return "\uE024";
|
||||
case "NumpadAdd":
|
||||
return "\uE025";
|
||||
case "NumpadSubtract":
|
||||
return "\uE027";
|
||||
case "NumpadDecimal":
|
||||
return "\uE028";
|
||||
case "NumpadDivide":
|
||||
return "\uE029";
|
||||
case "F1":
|
||||
return "\uE031";
|
||||
case "F2":
|
||||
return "\uE032";
|
||||
case "F3":
|
||||
return "\uE033";
|
||||
case "F4":
|
||||
return "\uE034";
|
||||
case "F5":
|
||||
return "\uE035";
|
||||
case "F6":
|
||||
return "\uE036";
|
||||
case "F7":
|
||||
return "\uE037";
|
||||
case "F8":
|
||||
return "\uE038";
|
||||
case "F9":
|
||||
return "\uE039";
|
||||
case "F10":
|
||||
return "\uE03A";
|
||||
case "F11":
|
||||
return "\uE03B";
|
||||
case "F12":
|
||||
return "\uE03C";
|
||||
case "Meta":
|
||||
case "MetaLeft":
|
||||
return "\uE03D";
|
||||
case "ShiftRight":
|
||||
return "\uE050";
|
||||
case "ControlRight":
|
||||
return "\uE051";
|
||||
case "AltRight":
|
||||
return "\uE052";
|
||||
case "MetaRight":
|
||||
return "\uE053";
|
||||
case "Space":
|
||||
return " ";
|
||||
case "Digit0":
|
||||
return "0";
|
||||
case "Digit1":
|
||||
return "1";
|
||||
case "Digit2":
|
||||
return "2";
|
||||
case "Digit3":
|
||||
return "3";
|
||||
case "Digit4":
|
||||
return "4";
|
||||
case "Digit5":
|
||||
return "5";
|
||||
case "Digit6":
|
||||
return "6";
|
||||
case "Digit7":
|
||||
return "7";
|
||||
case "Digit8":
|
||||
return "8";
|
||||
case "Digit9":
|
||||
return "9";
|
||||
case "KeyA":
|
||||
return "a";
|
||||
case "KeyB":
|
||||
return "b";
|
||||
case "KeyC":
|
||||
return "c";
|
||||
case "KeyD":
|
||||
return "d";
|
||||
case "KeyE":
|
||||
return "e";
|
||||
case "KeyF":
|
||||
return "f";
|
||||
case "KeyG":
|
||||
return "g";
|
||||
case "KeyH":
|
||||
return "h";
|
||||
case "KeyI":
|
||||
return "i";
|
||||
case "KeyJ":
|
||||
return "j";
|
||||
case "KeyK":
|
||||
return "k";
|
||||
case "KeyL":
|
||||
return "l";
|
||||
case "KeyM":
|
||||
return "m";
|
||||
case "KeyN":
|
||||
return "n";
|
||||
case "KeyO":
|
||||
return "o";
|
||||
case "KeyP":
|
||||
return "p";
|
||||
case "KeyQ":
|
||||
return "q";
|
||||
case "KeyR":
|
||||
return "r";
|
||||
case "KeyS":
|
||||
return "s";
|
||||
case "KeyT":
|
||||
return "t";
|
||||
case "KeyU":
|
||||
return "u";
|
||||
case "KeyV":
|
||||
return "v";
|
||||
case "KeyW":
|
||||
return "w";
|
||||
case "KeyX":
|
||||
return "x";
|
||||
case "KeyY":
|
||||
return "y";
|
||||
case "KeyZ":
|
||||
return "z";
|
||||
case "Semicolon":
|
||||
return ";";
|
||||
case "Equal":
|
||||
return "=";
|
||||
case "Comma":
|
||||
return ",";
|
||||
case "Minus":
|
||||
return "-";
|
||||
case "Period":
|
||||
return ".";
|
||||
case "Slash":
|
||||
return "/";
|
||||
case "Backquote":
|
||||
return "`";
|
||||
case "BracketLeft":
|
||||
return "[";
|
||||
case "Backslash":
|
||||
return "\\";
|
||||
case "BracketRight":
|
||||
return "]";
|
||||
case "Quote":
|
||||
return '"';
|
||||
default:
|
||||
throw new Error(`Unknown key: "${keyName}"`);
|
||||
}
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
getBidiKeyValue
|
||||
});
|
||||
24
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocol.js
generated
vendored
Normal file
24
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocol.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiProtocol_exports = {};
|
||||
module.exports = __toCommonJS(bidiProtocol_exports);
|
||||
__reExport(bidiProtocol_exports, require("./bidiProtocolCore"), module.exports);
|
||||
__reExport(bidiProtocol_exports, require("./bidiProtocolPermissions"), module.exports);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
...require("./bidiProtocolCore"),
|
||||
...require("./bidiProtocolPermissions")
|
||||
});
|
||||
179
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolCore.js
generated
vendored
Normal file
179
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolCore.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiProtocolCore_exports = {};
|
||||
__export(bidiProtocolCore_exports, {
|
||||
BrowsingContext: () => BrowsingContext,
|
||||
Emulation: () => Emulation,
|
||||
ErrorCode: () => ErrorCode,
|
||||
Input: () => Input,
|
||||
Log: () => Log,
|
||||
Network: () => Network,
|
||||
Script: () => Script,
|
||||
Session: () => Session
|
||||
});
|
||||
module.exports = __toCommonJS(bidiProtocolCore_exports);
|
||||
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
||||
ErrorCode2["InvalidArgument"] = "invalid argument";
|
||||
ErrorCode2["InvalidSelector"] = "invalid selector";
|
||||
ErrorCode2["InvalidSessionId"] = "invalid session id";
|
||||
ErrorCode2["InvalidWebExtension"] = "invalid web extension";
|
||||
ErrorCode2["MoveTargetOutOfBounds"] = "move target out of bounds";
|
||||
ErrorCode2["NoSuchAlert"] = "no such alert";
|
||||
ErrorCode2["NoSuchNetworkCollector"] = "no such network collector";
|
||||
ErrorCode2["NoSuchElement"] = "no such element";
|
||||
ErrorCode2["NoSuchFrame"] = "no such frame";
|
||||
ErrorCode2["NoSuchHandle"] = "no such handle";
|
||||
ErrorCode2["NoSuchHistoryEntry"] = "no such history entry";
|
||||
ErrorCode2["NoSuchIntercept"] = "no such intercept";
|
||||
ErrorCode2["NoSuchNetworkData"] = "no such network data";
|
||||
ErrorCode2["NoSuchNode"] = "no such node";
|
||||
ErrorCode2["NoSuchRequest"] = "no such request";
|
||||
ErrorCode2["NoSuchScript"] = "no such script";
|
||||
ErrorCode2["NoSuchStoragePartition"] = "no such storage partition";
|
||||
ErrorCode2["NoSuchUserContext"] = "no such user context";
|
||||
ErrorCode2["NoSuchWebExtension"] = "no such web extension";
|
||||
ErrorCode2["SessionNotCreated"] = "session not created";
|
||||
ErrorCode2["UnableToCaptureScreen"] = "unable to capture screen";
|
||||
ErrorCode2["UnableToCloseBrowser"] = "unable to close browser";
|
||||
ErrorCode2["UnableToSetCookie"] = "unable to set cookie";
|
||||
ErrorCode2["UnableToSetFileInput"] = "unable to set file input";
|
||||
ErrorCode2["UnavailableNetworkData"] = "unavailable network data";
|
||||
ErrorCode2["UnderspecifiedStoragePartition"] = "underspecified storage partition";
|
||||
ErrorCode2["UnknownCommand"] = "unknown command";
|
||||
ErrorCode2["UnknownError"] = "unknown error";
|
||||
ErrorCode2["UnsupportedOperation"] = "unsupported operation";
|
||||
return ErrorCode2;
|
||||
})(ErrorCode || {});
|
||||
var Session;
|
||||
((Session2) => {
|
||||
let UserPromptHandlerType;
|
||||
((UserPromptHandlerType2) => {
|
||||
UserPromptHandlerType2["Accept"] = "accept";
|
||||
UserPromptHandlerType2["Dismiss"] = "dismiss";
|
||||
UserPromptHandlerType2["Ignore"] = "ignore";
|
||||
})(UserPromptHandlerType = Session2.UserPromptHandlerType || (Session2.UserPromptHandlerType = {}));
|
||||
})(Session || (Session = {}));
|
||||
var BrowsingContext;
|
||||
((BrowsingContext2) => {
|
||||
let ReadinessState;
|
||||
((ReadinessState2) => {
|
||||
ReadinessState2["None"] = "none";
|
||||
ReadinessState2["Interactive"] = "interactive";
|
||||
ReadinessState2["Complete"] = "complete";
|
||||
})(ReadinessState = BrowsingContext2.ReadinessState || (BrowsingContext2.ReadinessState = {}));
|
||||
})(BrowsingContext || (BrowsingContext = {}));
|
||||
((BrowsingContext2) => {
|
||||
let UserPromptType;
|
||||
((UserPromptType2) => {
|
||||
UserPromptType2["Alert"] = "alert";
|
||||
UserPromptType2["Beforeunload"] = "beforeunload";
|
||||
UserPromptType2["Confirm"] = "confirm";
|
||||
UserPromptType2["Prompt"] = "prompt";
|
||||
})(UserPromptType = BrowsingContext2.UserPromptType || (BrowsingContext2.UserPromptType = {}));
|
||||
})(BrowsingContext || (BrowsingContext = {}));
|
||||
((BrowsingContext2) => {
|
||||
let CreateType;
|
||||
((CreateType2) => {
|
||||
CreateType2["Tab"] = "tab";
|
||||
CreateType2["Window"] = "window";
|
||||
})(CreateType = BrowsingContext2.CreateType || (BrowsingContext2.CreateType = {}));
|
||||
})(BrowsingContext || (BrowsingContext = {}));
|
||||
var Emulation;
|
||||
((Emulation2) => {
|
||||
let ForcedColorsModeTheme;
|
||||
((ForcedColorsModeTheme2) => {
|
||||
ForcedColorsModeTheme2["Light"] = "light";
|
||||
ForcedColorsModeTheme2["Dark"] = "dark";
|
||||
})(ForcedColorsModeTheme = Emulation2.ForcedColorsModeTheme || (Emulation2.ForcedColorsModeTheme = {}));
|
||||
})(Emulation || (Emulation = {}));
|
||||
((Emulation2) => {
|
||||
let ScreenOrientationNatural;
|
||||
((ScreenOrientationNatural2) => {
|
||||
ScreenOrientationNatural2["Portrait"] = "portrait";
|
||||
ScreenOrientationNatural2["Landscape"] = "landscape";
|
||||
})(ScreenOrientationNatural = Emulation2.ScreenOrientationNatural || (Emulation2.ScreenOrientationNatural = {}));
|
||||
})(Emulation || (Emulation = {}));
|
||||
var Network;
|
||||
((Network2) => {
|
||||
let CollectorType;
|
||||
((CollectorType2) => {
|
||||
CollectorType2["Blob"] = "blob";
|
||||
})(CollectorType = Network2.CollectorType || (Network2.CollectorType = {}));
|
||||
})(Network || (Network = {}));
|
||||
((Network2) => {
|
||||
let SameSite;
|
||||
((SameSite2) => {
|
||||
SameSite2["Strict"] = "strict";
|
||||
SameSite2["Lax"] = "lax";
|
||||
SameSite2["None"] = "none";
|
||||
SameSite2["Default"] = "default";
|
||||
})(SameSite = Network2.SameSite || (Network2.SameSite = {}));
|
||||
})(Network || (Network = {}));
|
||||
((Network2) => {
|
||||
let DataType;
|
||||
((DataType2) => {
|
||||
DataType2["Response"] = "response";
|
||||
})(DataType = Network2.DataType || (Network2.DataType = {}));
|
||||
})(Network || (Network = {}));
|
||||
((Network2) => {
|
||||
let InterceptPhase;
|
||||
((InterceptPhase2) => {
|
||||
InterceptPhase2["BeforeRequestSent"] = "beforeRequestSent";
|
||||
InterceptPhase2["ResponseStarted"] = "responseStarted";
|
||||
InterceptPhase2["AuthRequired"] = "authRequired";
|
||||
})(InterceptPhase = Network2.InterceptPhase || (Network2.InterceptPhase = {}));
|
||||
})(Network || (Network = {}));
|
||||
var Script;
|
||||
((Script2) => {
|
||||
let ResultOwnership;
|
||||
((ResultOwnership2) => {
|
||||
ResultOwnership2["Root"] = "root";
|
||||
ResultOwnership2["None"] = "none";
|
||||
})(ResultOwnership = Script2.ResultOwnership || (Script2.ResultOwnership = {}));
|
||||
})(Script || (Script = {}));
|
||||
var Log;
|
||||
((Log2) => {
|
||||
let Level;
|
||||
((Level2) => {
|
||||
Level2["Debug"] = "debug";
|
||||
Level2["Info"] = "info";
|
||||
Level2["Warn"] = "warn";
|
||||
Level2["Error"] = "error";
|
||||
})(Level = Log2.Level || (Log2.Level = {}));
|
||||
})(Log || (Log = {}));
|
||||
var Input;
|
||||
((Input2) => {
|
||||
let PointerType;
|
||||
((PointerType2) => {
|
||||
PointerType2["Mouse"] = "mouse";
|
||||
PointerType2["Pen"] = "pen";
|
||||
PointerType2["Touch"] = "touch";
|
||||
})(PointerType = Input2.PointerType || (Input2.PointerType = {}));
|
||||
})(Input || (Input = {}));
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowsingContext,
|
||||
Emulation,
|
||||
ErrorCode,
|
||||
Input,
|
||||
Log,
|
||||
Network,
|
||||
Script,
|
||||
Session
|
||||
});
|
||||
42
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolPermissions.js
generated
vendored
Normal file
42
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiProtocolPermissions.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiProtocolPermissions_exports = {};
|
||||
__export(bidiProtocolPermissions_exports, {
|
||||
Permissions: () => Permissions
|
||||
});
|
||||
module.exports = __toCommonJS(bidiProtocolPermissions_exports);
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var Permissions;
|
||||
((Permissions2) => {
|
||||
let PermissionState;
|
||||
((PermissionState2) => {
|
||||
PermissionState2["Granted"] = "granted";
|
||||
PermissionState2["Denied"] = "denied";
|
||||
PermissionState2["Prompt"] = "prompt";
|
||||
})(PermissionState = Permissions2.PermissionState || (Permissions2.PermissionState = {}));
|
||||
})(Permissions || (Permissions = {}));
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Permissions
|
||||
});
|
||||
148
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiSerializer.js
generated
vendored
Normal file
148
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/bidiSerializer.js
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bidiSerializer_exports = {};
|
||||
__export(bidiSerializer_exports, {
|
||||
BidiSerializer: () => BidiSerializer,
|
||||
isDate: () => isDate,
|
||||
isPlainObject: () => isPlainObject,
|
||||
isRegExp: () => isRegExp
|
||||
});
|
||||
module.exports = __toCommonJS(bidiSerializer_exports);
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
class UnserializableError extends Error {
|
||||
}
|
||||
class BidiSerializer {
|
||||
static serialize(arg) {
|
||||
switch (typeof arg) {
|
||||
case "symbol":
|
||||
case "function":
|
||||
throw new UnserializableError(`Unable to serializable ${typeof arg}`);
|
||||
case "object":
|
||||
return BidiSerializer._serializeObject(arg);
|
||||
case "undefined":
|
||||
return {
|
||||
type: "undefined"
|
||||
};
|
||||
case "number":
|
||||
return BidiSerializer._serializeNumber(arg);
|
||||
case "bigint":
|
||||
return {
|
||||
type: "bigint",
|
||||
value: arg.toString()
|
||||
};
|
||||
case "string":
|
||||
return {
|
||||
type: "string",
|
||||
value: arg
|
||||
};
|
||||
case "boolean":
|
||||
return {
|
||||
type: "boolean",
|
||||
value: arg
|
||||
};
|
||||
}
|
||||
}
|
||||
static _serializeNumber(arg) {
|
||||
let value;
|
||||
if (Object.is(arg, -0)) {
|
||||
value = "-0";
|
||||
} else if (Object.is(arg, Infinity)) {
|
||||
value = "Infinity";
|
||||
} else if (Object.is(arg, -Infinity)) {
|
||||
value = "-Infinity";
|
||||
} else if (Object.is(arg, NaN)) {
|
||||
value = "NaN";
|
||||
} else {
|
||||
value = arg;
|
||||
}
|
||||
return {
|
||||
type: "number",
|
||||
value
|
||||
};
|
||||
}
|
||||
static _serializeObject(arg) {
|
||||
if (arg === null) {
|
||||
return {
|
||||
type: "null"
|
||||
};
|
||||
} else if (Array.isArray(arg)) {
|
||||
const parsedArray = arg.map((subArg) => {
|
||||
return BidiSerializer.serialize(subArg);
|
||||
});
|
||||
return {
|
||||
type: "array",
|
||||
value: parsedArray
|
||||
};
|
||||
} else if (isPlainObject(arg)) {
|
||||
try {
|
||||
JSON.stringify(arg);
|
||||
} catch (error) {
|
||||
if (error instanceof TypeError && error.message.startsWith("Converting circular structure to JSON")) {
|
||||
error.message += " Recursive objects are not allowed.";
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
const parsedObject = [];
|
||||
for (const key in arg) {
|
||||
parsedObject.push([BidiSerializer.serialize(key), BidiSerializer.serialize(arg[key])]);
|
||||
}
|
||||
return {
|
||||
type: "object",
|
||||
value: parsedObject
|
||||
};
|
||||
} else if (isRegExp(arg)) {
|
||||
return {
|
||||
type: "regexp",
|
||||
value: {
|
||||
pattern: arg.source,
|
||||
flags: arg.flags
|
||||
}
|
||||
};
|
||||
} else if (isDate(arg)) {
|
||||
return {
|
||||
type: "date",
|
||||
value: arg.toISOString()
|
||||
};
|
||||
}
|
||||
throw new UnserializableError(
|
||||
"Custom object serialization not possible. Use plain objects instead."
|
||||
);
|
||||
}
|
||||
}
|
||||
const isPlainObject = (obj) => {
|
||||
return typeof obj === "object" && obj?.constructor === Object;
|
||||
};
|
||||
const isRegExp = (obj) => {
|
||||
return typeof obj === "object" && obj?.constructor === RegExp;
|
||||
};
|
||||
const isDate = (obj) => {
|
||||
return typeof obj === "object" && obj?.constructor === Date;
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BidiSerializer,
|
||||
isDate,
|
||||
isPlainObject,
|
||||
isRegExp
|
||||
});
|
||||
259
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/firefoxPrefs.js
generated
vendored
Normal file
259
.playwright-mcp/node_modules/playwright-core/lib/server/bidi/third_party/firefoxPrefs.js
generated
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var firefoxPrefs_exports = {};
|
||||
__export(firefoxPrefs_exports, {
|
||||
createProfile: () => createProfile
|
||||
});
|
||||
module.exports = __toCommonJS(firefoxPrefs_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
async function createProfile(options) {
|
||||
if (!import_fs.default.existsSync(options.path)) {
|
||||
await import_fs.default.promises.mkdir(options.path, {
|
||||
recursive: true
|
||||
});
|
||||
}
|
||||
await writePreferences({
|
||||
preferences: {
|
||||
...defaultProfilePreferences(options.preferences),
|
||||
...options.preferences
|
||||
},
|
||||
path: options.path
|
||||
});
|
||||
}
|
||||
function defaultProfilePreferences(extraPrefs) {
|
||||
const server = "dummy.test";
|
||||
const defaultPrefs = {
|
||||
// Make sure Shield doesn't hit the network.
|
||||
"app.normandy.api_url": "",
|
||||
// Disable Firefox old build background check
|
||||
"app.update.checkInstallTime": false,
|
||||
// Disable automatically upgrading Firefox
|
||||
"app.update.disabledForTesting": true,
|
||||
// Increase the APZ content response timeout to 1 minute
|
||||
"apz.content_response_timeout": 6e4,
|
||||
// Prevent various error message on the console
|
||||
// jest-puppeteer asserts that no error message is emitted by the console
|
||||
"browser.contentblocking.features.standard": "-tp,tpPrivate,cookieBehavior0,-cm,-fp",
|
||||
// Enable the dump function: which sends messages to the system
|
||||
// console
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1543115
|
||||
"browser.dom.window.dump.enabled": true,
|
||||
// Make sure newtab weather doesn't hit the network to retrieve weather data.
|
||||
"browser.newtabpage.activity-stream.discoverystream.region-weather-config": "",
|
||||
// Make sure newtab wallpapers don't hit the network to retrieve wallpaper data.
|
||||
"browser.newtabpage.activity-stream.newtabWallpapers.enabled": false,
|
||||
"browser.newtabpage.activity-stream.newtabWallpapers.v2.enabled": false,
|
||||
// Make sure Topsites doesn't hit the network to retrieve sponsored tiles.
|
||||
"browser.newtabpage.activity-stream.showSponsoredTopSites": false,
|
||||
// Disable topstories
|
||||
"browser.newtabpage.activity-stream.feeds.system.topstories": false,
|
||||
// Always display a blank page
|
||||
"browser.newtabpage.enabled": false,
|
||||
// Background thumbnails in particular cause grief: and disabling
|
||||
// thumbnails in general cannot hurt
|
||||
"browser.pagethumbnails.capturing_disabled": true,
|
||||
// Disable safebrowsing components.
|
||||
"browser.safebrowsing.blockedURIs.enabled": false,
|
||||
"browser.safebrowsing.downloads.enabled": false,
|
||||
"browser.safebrowsing.malware.enabled": false,
|
||||
"browser.safebrowsing.phishing.enabled": false,
|
||||
// Disable updates to search engines.
|
||||
"browser.search.update": false,
|
||||
// Do not restore the last open set of tabs if the browser has crashed
|
||||
"browser.sessionstore.resume_from_crash": false,
|
||||
// Skip check for default browser on startup
|
||||
"browser.shell.checkDefaultBrowser": false,
|
||||
// Disable newtabpage
|
||||
"browser.startup.homepage": "about:blank",
|
||||
// Do not redirect user when a milstone upgrade of Firefox is detected
|
||||
"browser.startup.homepage_override.mstone": "ignore",
|
||||
// Start with a blank page about:blank
|
||||
"browser.startup.page": 0,
|
||||
// Do not allow background tabs to be zombified on Android: otherwise for
|
||||
// tests that open additional tabs: the test harness tab itself might get
|
||||
// unloaded
|
||||
"browser.tabs.disableBackgroundZombification": false,
|
||||
// Do not warn when closing all other open tabs
|
||||
"browser.tabs.warnOnCloseOtherTabs": false,
|
||||
// Do not warn when multiple tabs will be opened
|
||||
"browser.tabs.warnOnOpen": false,
|
||||
// Do not automatically offer translations, as tests do not expect this.
|
||||
"browser.translations.automaticallyPopup": false,
|
||||
// Disable the UI tour.
|
||||
"browser.uitour.enabled": false,
|
||||
// Turn off search suggestions in the location bar so as not to trigger
|
||||
// network connections.
|
||||
"browser.urlbar.suggest.searches": false,
|
||||
// Disable first run splash page on Windows 10
|
||||
"browser.usedOnWindows10.introURL": "",
|
||||
// Do not warn on quitting Firefox
|
||||
"browser.warnOnQuit": false,
|
||||
// Defensively disable data reporting systems
|
||||
"datareporting.healthreport.documentServerURI": `http://${server}/dummy/healthreport/`,
|
||||
"datareporting.healthreport.logging.consoleEnabled": false,
|
||||
"datareporting.healthreport.service.enabled": false,
|
||||
"datareporting.healthreport.service.firstRun": false,
|
||||
"datareporting.healthreport.uploadEnabled": false,
|
||||
// Do not show datareporting policy notifications which can interfere with tests
|
||||
"datareporting.policy.dataSubmissionEnabled": false,
|
||||
"datareporting.policy.dataSubmissionPolicyBypassNotification": true,
|
||||
// DevTools JSONViewer sometimes fails to load dependencies with its require.js.
|
||||
// This doesn't affect Puppeteer but spams console (Bug 1424372)
|
||||
"devtools.jsonview.enabled": false,
|
||||
// Disable popup-blocker
|
||||
"dom.disable_open_during_load": false,
|
||||
// Enable the support for File object creation in the content process
|
||||
// Required for |Page.setFileInputFiles| protocol method.
|
||||
"dom.file.createInChild": true,
|
||||
// Disable the ProcessHangMonitor
|
||||
"dom.ipc.reportProcessHangs": false,
|
||||
// Disable slow script dialogues
|
||||
"dom.max_chrome_script_run_time": 0,
|
||||
"dom.max_script_run_time": 0,
|
||||
// Disable background timer throttling to allow tests to run in parallel
|
||||
// without a decrease in performance.
|
||||
"dom.min_background_timeout_value": 0,
|
||||
"dom.min_background_timeout_value_without_budget_throttling": 0,
|
||||
"dom.timeout.enable_budget_timer_throttling": false,
|
||||
// Disable HTTPS-First upgrades
|
||||
"dom.security.https_first": false,
|
||||
// Only load extensions from the application and user profile
|
||||
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
||||
"extensions.autoDisableScopes": 0,
|
||||
"extensions.enabledScopes": 5,
|
||||
// Disable metadata caching for installed add-ons by default
|
||||
"extensions.getAddons.cache.enabled": false,
|
||||
// Disable installing any distribution extensions or add-ons.
|
||||
"extensions.installDistroAddons": false,
|
||||
// Disabled screenshots extension
|
||||
"extensions.screenshots.disabled": true,
|
||||
// Turn off extension updates so they do not bother tests
|
||||
"extensions.update.enabled": false,
|
||||
// Turn off extension updates so they do not bother tests
|
||||
"extensions.update.notifyUser": false,
|
||||
// Make sure opening about:addons will not hit the network
|
||||
"extensions.webservice.discoverURL": `http://${server}/dummy/discoveryURL`,
|
||||
// Allow the application to have focus even it runs in the background
|
||||
"focusmanager.testmode": true,
|
||||
// Disable useragent updates
|
||||
"general.useragent.updates.enabled": false,
|
||||
// Always use network provider for geolocation tests so we bypass the
|
||||
// macOS dialog raised by the corelocation provider
|
||||
"geo.provider.testing": true,
|
||||
// Do not scan Wifi
|
||||
"geo.wifi.scan": false,
|
||||
// No hang monitor
|
||||
"hangmonitor.timeout": 0,
|
||||
// Show chrome errors and warnings in the error console
|
||||
"javascript.options.showInConsole": true,
|
||||
// Do not throttle rendering (requestAnimationFrame) in background tabs
|
||||
"layout.testing.top-level-always-active": true,
|
||||
// Disable download and usage of OpenH264: and Widevine plugins
|
||||
"media.gmp-manager.updateEnabled": false,
|
||||
// Disable the GFX sanity window
|
||||
"media.sanity-test.disabled": true,
|
||||
// Disable connectivity service pings
|
||||
"network.connectivity-service.enabled": false,
|
||||
// Disable experimental feature that is only available in Nightly
|
||||
"network.cookie.sameSite.laxByDefault": false,
|
||||
// Do not prompt for temporary redirects
|
||||
"network.http.prompt-temp-redirect": false,
|
||||
// Disable speculative connections so they are not reported as leaking
|
||||
// when they are hanging around
|
||||
"network.http.speculative-parallel-limit": 0,
|
||||
// Do not automatically switch between offline and online
|
||||
"network.manage-offline-status": false,
|
||||
// Make sure SNTP requests do not hit the network
|
||||
"network.sntp.pools": server,
|
||||
// Disable Flash.
|
||||
"plugin.state.flash": 0,
|
||||
"privacy.trackingprotection.enabled": false,
|
||||
// Can be removed once Firefox 89 is no longer supported
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1710839
|
||||
"remote.enabled": true,
|
||||
// Don't do network connections for mitm priming
|
||||
"security.certerrors.mitm.priming.enabled": false,
|
||||
// Local documents have access to all other local documents,
|
||||
// including directory listings
|
||||
"security.fileuri.strict_origin_policy": false,
|
||||
// Do not wait for the notification button security delay
|
||||
"security.notification_enable_delay": 0,
|
||||
// Do not automatically fill sign-in forms with known usernames and
|
||||
// passwords
|
||||
"signon.autofillForms": false,
|
||||
// Disable password capture, so that tests that include forms are not
|
||||
// influenced by the presence of the persistent doorhanger notification
|
||||
"signon.rememberSignons": false,
|
||||
// Disable first-run welcome page
|
||||
"startup.homepage_welcome_url": "about:blank",
|
||||
// Disable first-run welcome page
|
||||
"startup.homepage_welcome_url.additional": "",
|
||||
// Disable browser animations (tabs, fullscreen, sliding alerts)
|
||||
"toolkit.cosmeticAnimations.enabled": false,
|
||||
// Prevent starting into safe mode after application crashes
|
||||
"toolkit.startup.max_resumed_crashes": -1
|
||||
};
|
||||
return Object.assign(defaultPrefs, extraPrefs);
|
||||
}
|
||||
async function writePreferences(options) {
|
||||
const prefsPath = import_path.default.join(options.path, "prefs.js");
|
||||
const lines = Object.entries(options.preferences).map(([key, value]) => {
|
||||
return `user_pref(${JSON.stringify(key)}, ${JSON.stringify(value)});`;
|
||||
});
|
||||
const result = await Promise.allSettled([
|
||||
import_fs.default.promises.writeFile(import_path.default.join(options.path, "user.js"), lines.join("\n")),
|
||||
// Create a backup of the preferences file if it already exitsts.
|
||||
import_fs.default.promises.access(prefsPath, import_fs.default.constants.F_OK).then(
|
||||
async () => {
|
||||
await import_fs.default.promises.copyFile(
|
||||
prefsPath,
|
||||
import_path.default.join(options.path, "prefs.js.playwright")
|
||||
);
|
||||
},
|
||||
// Swallow only if file does not exist
|
||||
() => {
|
||||
}
|
||||
)
|
||||
]);
|
||||
for (const command of result) {
|
||||
if (command.status === "rejected") {
|
||||
throw command.reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createProfile
|
||||
});
|
||||
149
.playwright-mcp/node_modules/playwright-core/lib/server/browser.js
generated
vendored
Normal file
149
.playwright-mcp/node_modules/playwright-core/lib/server/browser.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browser_exports = {};
|
||||
__export(browser_exports, {
|
||||
Browser: () => Browser
|
||||
});
|
||||
module.exports = __toCommonJS(browser_exports);
|
||||
var import_artifact = require("./artifact");
|
||||
var import_browserContext = require("./browserContext");
|
||||
var import_download = require("./download");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_page = require("./page");
|
||||
var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
|
||||
class Browser extends import_instrumentation.SdkObject {
|
||||
constructor(parent, options) {
|
||||
super(parent, "browser");
|
||||
this._downloads = /* @__PURE__ */ new Map();
|
||||
this._defaultContext = null;
|
||||
this._startedClosing = false;
|
||||
this._idToVideo = /* @__PURE__ */ new Map();
|
||||
this._isCollocatedWithServer = true;
|
||||
this.attribution.browser = this;
|
||||
this.options = options;
|
||||
this.instrumentation.onBrowserOpen(this);
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Context: "context",
|
||||
Disconnected: "disconnected"
|
||||
};
|
||||
}
|
||||
sdkLanguage() {
|
||||
return this.options.sdkLanguage || this.attribution.playwright.options.sdkLanguage;
|
||||
}
|
||||
async newContext(progress, options) {
|
||||
(0, import_browserContext.validateBrowserContextOptions)(options, this.options);
|
||||
let clientCertificatesProxy;
|
||||
let context;
|
||||
try {
|
||||
if (options.clientCertificates?.length) {
|
||||
clientCertificatesProxy = await import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(progress, options);
|
||||
options = { ...options };
|
||||
options.proxyOverride = clientCertificatesProxy.proxySettings();
|
||||
options.internalIgnoreHTTPSErrors = true;
|
||||
}
|
||||
context = await progress.race(this.doCreateNewContext(options));
|
||||
context._clientCertificatesProxy = clientCertificatesProxy;
|
||||
if (options.__testHookBeforeSetStorageState)
|
||||
await progress.race(options.__testHookBeforeSetStorageState());
|
||||
await context.setStorageState(progress, options.storageState, "initial");
|
||||
this.emit(Browser.Events.Context, context);
|
||||
return context;
|
||||
} catch (error) {
|
||||
await context?.close({ reason: "Failed to create context" }).catch(() => {
|
||||
});
|
||||
await clientCertificatesProxy?.close().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async newContextForReuse(progress, params) {
|
||||
const hash = import_browserContext.BrowserContext.reusableContextHash(params);
|
||||
if (!this._contextForReuse || hash !== this._contextForReuse.hash || !this._contextForReuse.context.canResetForReuse()) {
|
||||
if (this._contextForReuse)
|
||||
await this._contextForReuse.context.close({ reason: "Context reused" });
|
||||
this._contextForReuse = { context: await this.newContext(progress, params), hash };
|
||||
return this._contextForReuse.context;
|
||||
}
|
||||
await this._contextForReuse.context.resetForReuse(progress, params);
|
||||
return this._contextForReuse.context;
|
||||
}
|
||||
contextForReuse() {
|
||||
return this._contextForReuse?.context;
|
||||
}
|
||||
_downloadCreated(page, uuid, url, suggestedFilename) {
|
||||
const download = new import_download.Download(page, this.options.downloadsPath || "", uuid, url, suggestedFilename);
|
||||
this._downloads.set(uuid, download);
|
||||
}
|
||||
_downloadFilenameSuggested(uuid, suggestedFilename) {
|
||||
const download = this._downloads.get(uuid);
|
||||
if (!download)
|
||||
return;
|
||||
download._filenameSuggested(suggestedFilename);
|
||||
}
|
||||
_downloadFinished(uuid, error) {
|
||||
const download = this._downloads.get(uuid);
|
||||
if (!download)
|
||||
return;
|
||||
download.artifact.reportFinished(error ? new Error(error) : void 0);
|
||||
this._downloads.delete(uuid);
|
||||
}
|
||||
_videoStarted(context, videoId, path, pageOrError) {
|
||||
const artifact = new import_artifact.Artifact(context, path);
|
||||
this._idToVideo.set(videoId, { context, artifact });
|
||||
pageOrError.then((page) => {
|
||||
if (page instanceof import_page.Page) {
|
||||
page.video = artifact;
|
||||
page.emitOnContext(import_browserContext.BrowserContext.Events.VideoStarted, artifact);
|
||||
page.emit(import_page.Page.Events.Video, artifact);
|
||||
}
|
||||
});
|
||||
}
|
||||
_takeVideo(videoId) {
|
||||
const video = this._idToVideo.get(videoId);
|
||||
this._idToVideo.delete(videoId);
|
||||
return video?.artifact;
|
||||
}
|
||||
_didClose() {
|
||||
for (const context of this.contexts())
|
||||
context._browserClosed();
|
||||
if (this._defaultContext)
|
||||
this._defaultContext._browserClosed();
|
||||
this.emit(Browser.Events.Disconnected);
|
||||
this.instrumentation.onBrowserClose(this);
|
||||
}
|
||||
async close(options) {
|
||||
if (!this._startedClosing) {
|
||||
if (options.reason)
|
||||
this._closeReason = options.reason;
|
||||
this._startedClosing = true;
|
||||
await this.options.browserProcess.close();
|
||||
}
|
||||
if (this.isConnected())
|
||||
await new Promise((x) => this.once(Browser.Events.Disconnected, x));
|
||||
}
|
||||
async killForTests() {
|
||||
await this.options.browserProcess.kill();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Browser
|
||||
});
|
||||
695
.playwright-mcp/node_modules/playwright-core/lib/server/browserContext.js
generated
vendored
Normal file
695
.playwright-mcp/node_modules/playwright-core/lib/server/browserContext.js
generated
vendored
Normal file
@@ -0,0 +1,695 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserContext_exports = {};
|
||||
__export(browserContext_exports, {
|
||||
BrowserContext: () => BrowserContext,
|
||||
normalizeProxySettings: () => normalizeProxySettings,
|
||||
validateBrowserContextOptions: () => validateBrowserContextOptions,
|
||||
verifyClientCertificates: () => verifyClientCertificates,
|
||||
verifyGeolocation: () => verifyGeolocation
|
||||
});
|
||||
module.exports = __toCommonJS(browserContext_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_crypto = require("./utils/crypto");
|
||||
var import_debug = require("./utils/debug");
|
||||
var import_clock = require("./clock");
|
||||
var import_debugger = require("./debugger");
|
||||
var import_dialog = require("./dialog");
|
||||
var import_fetch = require("./fetch");
|
||||
var import_fileUtils = require("./utils/fileUtils");
|
||||
var import_stackTrace = require("../utils/isomorphic/stackTrace");
|
||||
var import_harRecorder = require("./har/harRecorder");
|
||||
var import_helper = require("./helper");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var network = __toESM(require("./network"));
|
||||
var import_page = require("./page");
|
||||
var import_page2 = require("./page");
|
||||
var import_recorderApp = require("./recorder/recorderApp");
|
||||
var import_selectors = require("./selectors");
|
||||
var import_tracing = require("./trace/recorder/tracing");
|
||||
var rawStorageSource = __toESM(require("../generated/storageScriptSource"));
|
||||
class BrowserContext extends import_instrumentation.SdkObject {
|
||||
constructor(browser, options, browserContextId) {
|
||||
super(browser, "browser-context");
|
||||
this._pageBindings = /* @__PURE__ */ new Map();
|
||||
this.requestInterceptors = [];
|
||||
this._closedStatus = "open";
|
||||
this._permissions = /* @__PURE__ */ new Map();
|
||||
this._downloads = /* @__PURE__ */ new Set();
|
||||
this._origins = /* @__PURE__ */ new Set();
|
||||
this._harRecorders = /* @__PURE__ */ new Map();
|
||||
this._tempDirs = [];
|
||||
this._creatingStorageStatePage = false;
|
||||
this.initScripts = [];
|
||||
this._routesInFlight = /* @__PURE__ */ new Set();
|
||||
this.attribution.context = this;
|
||||
this._browser = browser;
|
||||
this._options = options;
|
||||
this._browserContextId = browserContextId;
|
||||
this._isPersistentContext = !browserContextId;
|
||||
this._closePromise = new Promise((fulfill) => this._closePromiseFulfill = fulfill);
|
||||
this._selectors = new import_selectors.Selectors(options.selectorEngines || [], options.testIdAttributeName);
|
||||
this.fetchRequest = new import_fetch.BrowserContextAPIRequestContext(this);
|
||||
this.tracing = new import_tracing.Tracing(this, browser.options.tracesDir);
|
||||
this.clock = new import_clock.Clock(this);
|
||||
this.dialogManager = new import_dialog.DialogManager(this.instrumentation);
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Console: "console",
|
||||
Close: "close",
|
||||
Page: "page",
|
||||
// Can't use just 'error' due to node.js special treatment of error events.
|
||||
// @see https://nodejs.org/api/events.html#events_error_events
|
||||
PageError: "pageerror",
|
||||
Request: "request",
|
||||
Response: "response",
|
||||
RequestFailed: "requestfailed",
|
||||
RequestFinished: "requestfinished",
|
||||
RequestAborted: "requestaborted",
|
||||
RequestFulfilled: "requestfulfilled",
|
||||
RequestContinued: "requestcontinued",
|
||||
BeforeClose: "beforeclose",
|
||||
VideoStarted: "videostarted",
|
||||
RecorderEvent: "recorderevent"
|
||||
};
|
||||
}
|
||||
isPersistentContext() {
|
||||
return this._isPersistentContext;
|
||||
}
|
||||
selectors() {
|
||||
return this._selectors;
|
||||
}
|
||||
async _initialize() {
|
||||
if (this.attribution.playwright.options.isInternalPlaywright)
|
||||
return;
|
||||
this._debugger = new import_debugger.Debugger(this);
|
||||
if ((0, import_debug.debugMode)() === "inspector")
|
||||
await import_recorderApp.RecorderApp.show(this, { pauseOnNextStatement: true });
|
||||
if (this._debugger.isPaused())
|
||||
import_recorderApp.RecorderApp.showInspectorNoReply(this);
|
||||
this._debugger.on(import_debugger.Debugger.Events.PausedStateChanged, () => {
|
||||
if (this._debugger.isPaused())
|
||||
import_recorderApp.RecorderApp.showInspectorNoReply(this);
|
||||
});
|
||||
if ((0, import_debug.debugMode)() === "console") {
|
||||
await this.extendInjectedScript(`
|
||||
function installConsoleApi(injectedScript) { injectedScript.consoleApi.install(); }
|
||||
module.exports = { default: () => installConsoleApi };
|
||||
`);
|
||||
}
|
||||
if (this._options.serviceWorkers === "block")
|
||||
await this.addInitScript(void 0, `
|
||||
if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { console.warn('Service Worker registration blocked by Playwright'); };
|
||||
`);
|
||||
if (this._options.permissions)
|
||||
await this.grantPermissions(this._options.permissions);
|
||||
}
|
||||
debugger() {
|
||||
return this._debugger;
|
||||
}
|
||||
async _ensureVideosPath() {
|
||||
if (this._options.recordVideo)
|
||||
await (0, import_fileUtils.mkdirIfNeeded)(import_path.default.join(this._options.recordVideo.dir, "dummy"));
|
||||
}
|
||||
canResetForReuse() {
|
||||
if (this._closedStatus !== "open")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
static reusableContextHash(params) {
|
||||
const paramsCopy = { ...params };
|
||||
if (paramsCopy.selectorEngines?.length === 0)
|
||||
delete paramsCopy.selectorEngines;
|
||||
for (const k of Object.keys(paramsCopy)) {
|
||||
const key = k;
|
||||
if (paramsCopy[key] === defaultNewContextParamValues[key])
|
||||
delete paramsCopy[key];
|
||||
}
|
||||
for (const key of paramsThatAllowContextReuse)
|
||||
delete paramsCopy[key];
|
||||
return JSON.stringify(paramsCopy);
|
||||
}
|
||||
async resetForReuse(progress, params) {
|
||||
await this.tracing.resetForReuse(progress);
|
||||
if (params) {
|
||||
for (const key of paramsThatAllowContextReuse)
|
||||
this._options[key] = params[key];
|
||||
if (params.testIdAttributeName)
|
||||
this.selectors().setTestIdAttributeName(params.testIdAttributeName);
|
||||
}
|
||||
let page = this.pages()[0];
|
||||
const otherPages = this.possiblyUninitializedPages().filter((p) => p !== page);
|
||||
for (const p of otherPages)
|
||||
await p.close();
|
||||
if (page && page.hasCrashed()) {
|
||||
await page.close();
|
||||
page = void 0;
|
||||
}
|
||||
await page?.mainFrame().gotoImpl(progress, "about:blank", {});
|
||||
await this.clock.uninstall(progress);
|
||||
await progress.race(this.setUserAgent(this._options.userAgent));
|
||||
await progress.race(this.doUpdateDefaultEmulatedMedia());
|
||||
await progress.race(this.doUpdateDefaultViewport());
|
||||
await this.setStorageState(progress, this._options.storageState, "resetForReuse");
|
||||
await page?.resetForReuse(progress);
|
||||
}
|
||||
_browserClosed() {
|
||||
for (const page of this.pages())
|
||||
page._didClose();
|
||||
this._didCloseInternal();
|
||||
}
|
||||
_didCloseInternal() {
|
||||
if (this._closedStatus === "closed") {
|
||||
return;
|
||||
}
|
||||
this._clientCertificatesProxy?.close().catch(() => {
|
||||
});
|
||||
this.tracing.abort();
|
||||
if (this._isPersistentContext)
|
||||
this.onClosePersistent();
|
||||
this._closePromiseFulfill(new Error("Context closed"));
|
||||
this.emit(BrowserContext.Events.Close);
|
||||
}
|
||||
pages() {
|
||||
return this.possiblyUninitializedPages().filter((page) => page.initializedOrUndefined());
|
||||
}
|
||||
async cookies(urls = []) {
|
||||
if (urls && !Array.isArray(urls))
|
||||
urls = [urls];
|
||||
return await this.doGetCookies(urls);
|
||||
}
|
||||
async clearCookies(options) {
|
||||
const currentCookies = await this.cookies();
|
||||
await this.doClearCookies();
|
||||
const matches = (cookie, prop, value) => {
|
||||
if (!value)
|
||||
return true;
|
||||
if (value instanceof RegExp) {
|
||||
value.lastIndex = 0;
|
||||
return value.test(cookie[prop]);
|
||||
}
|
||||
return cookie[prop] === value;
|
||||
};
|
||||
const cookiesToReadd = currentCookies.filter((cookie) => {
|
||||
return !matches(cookie, "name", options.name) || !matches(cookie, "domain", options.domain) || !matches(cookie, "path", options.path);
|
||||
});
|
||||
await this.addCookies(cookiesToReadd);
|
||||
}
|
||||
setHTTPCredentials(httpCredentials) {
|
||||
return this.doSetHTTPCredentials(httpCredentials);
|
||||
}
|
||||
getBindingClient(name) {
|
||||
return this._pageBindings.get(name)?.forClient;
|
||||
}
|
||||
async exposePlaywrightBindingIfNeeded() {
|
||||
this._playwrightBindingExposed ??= (async () => {
|
||||
await this.doExposePlaywrightBinding();
|
||||
this.bindingsInitScript = import_page2.PageBinding.createInitScript();
|
||||
this.initScripts.push(this.bindingsInitScript);
|
||||
await this.doAddInitScript(this.bindingsInitScript);
|
||||
await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
|
||||
})();
|
||||
return await this._playwrightBindingExposed;
|
||||
}
|
||||
needsPlaywrightBinding() {
|
||||
return this._playwrightBindingExposed !== void 0;
|
||||
}
|
||||
async exposeBinding(progress, name, needsHandle, playwrightBinding, forClient) {
|
||||
if (this._pageBindings.has(name))
|
||||
throw new Error(`Function "${name}" has been already registered`);
|
||||
for (const page of this.pages()) {
|
||||
if (page.getBinding(name))
|
||||
throw new Error(`Function "${name}" has been already registered in one of the pages`);
|
||||
}
|
||||
await progress.race(this.exposePlaywrightBindingIfNeeded());
|
||||
const binding = new import_page2.PageBinding(name, playwrightBinding, needsHandle);
|
||||
binding.forClient = forClient;
|
||||
this._pageBindings.set(name, binding);
|
||||
try {
|
||||
await progress.race(this.doAddInitScript(binding.initScript));
|
||||
await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
|
||||
return binding;
|
||||
} catch (error) {
|
||||
this._pageBindings.delete(name);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async removeExposedBindings(bindings) {
|
||||
bindings = bindings.filter((binding) => this._pageBindings.get(binding.name) === binding);
|
||||
for (const binding of bindings)
|
||||
this._pageBindings.delete(binding.name);
|
||||
await this.doRemoveInitScripts(bindings.map((binding) => binding.initScript));
|
||||
const cleanup = bindings.map((binding) => `{ ${binding.cleanupScript} };
|
||||
`).join("");
|
||||
await this.safeNonStallingEvaluateInAllFrames(cleanup, "main");
|
||||
}
|
||||
async grantPermissions(permissions, origin) {
|
||||
let resolvedOrigin = "*";
|
||||
if (origin) {
|
||||
const url = new URL(origin);
|
||||
resolvedOrigin = url.origin;
|
||||
}
|
||||
const existing = new Set(this._permissions.get(resolvedOrigin) || []);
|
||||
permissions.forEach((p) => existing.add(p));
|
||||
const list = [...existing.values()];
|
||||
this._permissions.set(resolvedOrigin, list);
|
||||
await this.doGrantPermissions(resolvedOrigin, list);
|
||||
}
|
||||
async clearPermissions() {
|
||||
this._permissions.clear();
|
||||
await this.doClearPermissions();
|
||||
}
|
||||
async setExtraHTTPHeaders(progress, headers) {
|
||||
const oldHeaders = this._options.extraHTTPHeaders;
|
||||
this._options.extraHTTPHeaders = headers;
|
||||
try {
|
||||
await progress.race(this.doUpdateExtraHTTPHeaders());
|
||||
} catch (error) {
|
||||
this._options.extraHTTPHeaders = oldHeaders;
|
||||
this.doUpdateExtraHTTPHeaders().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async setOffline(progress, offline) {
|
||||
const oldOffline = this._options.offline;
|
||||
this._options.offline = offline;
|
||||
try {
|
||||
await progress.race(this.doUpdateOffline());
|
||||
} catch (error) {
|
||||
this._options.offline = oldOffline;
|
||||
this.doUpdateOffline().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async _loadDefaultContextAsIs(progress) {
|
||||
if (!this.possiblyUninitializedPages().length) {
|
||||
const waitForEvent = import_helper.helper.waitForEvent(progress, this, BrowserContext.Events.Page);
|
||||
await Promise.race([waitForEvent.promise, this._closePromise]);
|
||||
}
|
||||
const page = this.possiblyUninitializedPages()[0];
|
||||
if (!page)
|
||||
return;
|
||||
const pageOrError = await progress.race(page.waitForInitializedOrError());
|
||||
if (pageOrError instanceof Error)
|
||||
throw pageOrError;
|
||||
await page.mainFrame()._waitForLoadState(progress, "load");
|
||||
return page;
|
||||
}
|
||||
async _loadDefaultContext(progress) {
|
||||
const defaultPage = await this._loadDefaultContextAsIs(progress);
|
||||
if (!defaultPage)
|
||||
return;
|
||||
const browserName = this._browser.options.name;
|
||||
if (this._options.isMobile && browserName === "chromium" || this._options.locale && browserName === "webkit") {
|
||||
await this.newPage(progress);
|
||||
await defaultPage.close();
|
||||
}
|
||||
}
|
||||
_authenticateProxyViaHeader() {
|
||||
const proxy = this._options.proxy || this._browser.options.proxy || { username: void 0, password: void 0 };
|
||||
const { username, password } = proxy;
|
||||
if (username) {
|
||||
this._options.httpCredentials = { username, password };
|
||||
const token = Buffer.from(`${username}:${password}`).toString("base64");
|
||||
this._options.extraHTTPHeaders = network.mergeHeaders([
|
||||
this._options.extraHTTPHeaders,
|
||||
network.singleHeader("Proxy-Authorization", `Basic ${token}`)
|
||||
]);
|
||||
}
|
||||
}
|
||||
_authenticateProxyViaCredentials() {
|
||||
const proxy = this._options.proxy || this._browser.options.proxy;
|
||||
if (!proxy)
|
||||
return;
|
||||
const { username, password } = proxy;
|
||||
if (username)
|
||||
this._options.httpCredentials = { username, password: password || "" };
|
||||
}
|
||||
async addInitScript(progress, source) {
|
||||
const initScript = new import_page.InitScript(source);
|
||||
this.initScripts.push(initScript);
|
||||
try {
|
||||
const promise = this.doAddInitScript(initScript);
|
||||
if (progress)
|
||||
await progress.race(promise);
|
||||
else
|
||||
await promise;
|
||||
return initScript;
|
||||
} catch (error) {
|
||||
this.removeInitScripts([initScript]).catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async removeInitScripts(initScripts) {
|
||||
const set = new Set(initScripts);
|
||||
this.initScripts = this.initScripts.filter((script) => !set.has(script));
|
||||
await this.doRemoveInitScripts(initScripts);
|
||||
}
|
||||
async addRequestInterceptor(progress, handler) {
|
||||
this.requestInterceptors.push(handler);
|
||||
await this.doUpdateRequestInterception();
|
||||
}
|
||||
async removeRequestInterceptor(handler) {
|
||||
const index = this.requestInterceptors.indexOf(handler);
|
||||
if (index === -1)
|
||||
return;
|
||||
this.requestInterceptors.splice(index, 1);
|
||||
await this.notifyRoutesInFlightAboutRemovedHandler(handler);
|
||||
await this.doUpdateRequestInterception();
|
||||
}
|
||||
isClosingOrClosed() {
|
||||
return this._closedStatus !== "open";
|
||||
}
|
||||
async _deleteAllDownloads() {
|
||||
await Promise.all(Array.from(this._downloads).map((download) => download.artifact.deleteOnContextClose()));
|
||||
}
|
||||
async _deleteAllTempDirs() {
|
||||
await Promise.all(this._tempDirs.map(async (dir) => await import_fs.default.promises.unlink(dir).catch((e) => {
|
||||
})));
|
||||
}
|
||||
setCustomCloseHandler(handler) {
|
||||
this._customCloseHandler = handler;
|
||||
}
|
||||
async close(options) {
|
||||
if (this._closedStatus === "open") {
|
||||
if (options.reason)
|
||||
this._closeReason = options.reason;
|
||||
this.emit(BrowserContext.Events.BeforeClose);
|
||||
this._closedStatus = "closing";
|
||||
for (const harRecorder of this._harRecorders.values())
|
||||
await harRecorder.flush();
|
||||
await this.tracing.flush();
|
||||
const promises = [];
|
||||
for (const { context, artifact } of this._browser._idToVideo.values()) {
|
||||
if (context === this)
|
||||
promises.push(artifact.finishedPromise());
|
||||
}
|
||||
if (this._customCloseHandler) {
|
||||
await this._customCloseHandler();
|
||||
} else {
|
||||
await this.doClose(options.reason);
|
||||
}
|
||||
promises.push(this._deleteAllDownloads());
|
||||
promises.push(this._deleteAllTempDirs());
|
||||
await Promise.all(promises);
|
||||
if (!this._customCloseHandler)
|
||||
this._didCloseInternal();
|
||||
}
|
||||
await this._closePromise;
|
||||
}
|
||||
async newPage(progress, forStorageState) {
|
||||
let page;
|
||||
try {
|
||||
this._creatingStorageStatePage = !!forStorageState;
|
||||
page = await progress.race(this.doCreateNewPage());
|
||||
const pageOrError = await progress.race(page.waitForInitializedOrError());
|
||||
if (pageOrError instanceof import_page2.Page) {
|
||||
if (pageOrError.isClosed())
|
||||
throw new Error("Page has been closed.");
|
||||
return pageOrError;
|
||||
}
|
||||
throw pageOrError;
|
||||
} catch (error) {
|
||||
await page?.close({ reason: "Failed to create page" }).catch(() => {
|
||||
});
|
||||
throw error;
|
||||
} finally {
|
||||
this._creatingStorageStatePage = false;
|
||||
}
|
||||
}
|
||||
addVisitedOrigin(origin) {
|
||||
this._origins.add(origin);
|
||||
}
|
||||
async storageState(progress, indexedDB = false) {
|
||||
const result = {
|
||||
cookies: await this.cookies(),
|
||||
origins: []
|
||||
};
|
||||
const originsToSave = new Set(this._origins);
|
||||
const collectScript = `(() => {
|
||||
const module = {};
|
||||
${rawStorageSource.source}
|
||||
const script = new (module.exports.StorageScript())(${this._browser.options.name === "firefox"});
|
||||
return script.collect(${indexedDB});
|
||||
})()`;
|
||||
for (const page of this.pages()) {
|
||||
const origin = page.mainFrame().origin();
|
||||
if (!origin || !originsToSave.has(origin))
|
||||
continue;
|
||||
try {
|
||||
const storage = await page.mainFrame().nonStallingEvaluateInExistingContext(collectScript, "utility");
|
||||
if (storage.localStorage.length || storage.indexedDB?.length)
|
||||
result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
|
||||
originsToSave.delete(origin);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
if (originsToSave.size) {
|
||||
const page = await this.newPage(
|
||||
progress,
|
||||
true
|
||||
/* forStorageState */
|
||||
);
|
||||
try {
|
||||
await page.addRequestInterceptor(progress, (route) => {
|
||||
route.fulfill({ body: "<html></html>" }).catch(() => {
|
||||
});
|
||||
}, "prepend");
|
||||
for (const origin of originsToSave) {
|
||||
const frame = page.mainFrame();
|
||||
await frame.gotoImpl(progress, origin, {});
|
||||
const storage = await progress.race(frame.evaluateExpression(collectScript, { world: "utility" }));
|
||||
if (storage.localStorage.length || storage.indexedDB?.length)
|
||||
result.origins.push({ origin, localStorage: storage.localStorage, indexedDB: storage.indexedDB });
|
||||
}
|
||||
} finally {
|
||||
await page.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
isCreatingStorageStatePage() {
|
||||
return this._creatingStorageStatePage;
|
||||
}
|
||||
async setStorageState(progress, state, mode) {
|
||||
let page;
|
||||
let interceptor;
|
||||
try {
|
||||
if (mode !== "initial") {
|
||||
await progress.race(this.clearCache());
|
||||
await progress.race(this.doClearCookies());
|
||||
}
|
||||
if (state?.cookies)
|
||||
await progress.race(this.addCookies(state.cookies));
|
||||
const newOrigins = new Map(state?.origins?.map((p) => [p.origin, p]) || []);
|
||||
const allOrigins = /* @__PURE__ */ new Set([...this._origins, ...newOrigins.keys()]);
|
||||
if (allOrigins.size) {
|
||||
if (mode === "resetForReuse")
|
||||
page = this.pages()[0];
|
||||
if (!page)
|
||||
page = await this.newPage(
|
||||
progress,
|
||||
mode !== "resetForReuse"
|
||||
/* forStorageState */
|
||||
);
|
||||
interceptor = (route) => {
|
||||
route.fulfill({ body: "<html></html>" }).catch(() => {
|
||||
});
|
||||
};
|
||||
await page.addRequestInterceptor(progress, interceptor, "prepend");
|
||||
for (const origin of allOrigins) {
|
||||
const frame = page.mainFrame();
|
||||
await frame.gotoImpl(progress, origin, {});
|
||||
const restoreScript = `(() => {
|
||||
const module = {};
|
||||
${rawStorageSource.source}
|
||||
const script = new (module.exports.StorageScript())(${this._browser.options.name === "firefox"});
|
||||
return script.restore(${JSON.stringify(newOrigins.get(origin))});
|
||||
})()`;
|
||||
await progress.race(frame.evaluateExpression(restoreScript, { world: "utility" }));
|
||||
}
|
||||
}
|
||||
this._origins = /* @__PURE__ */ new Set([...newOrigins.keys()]);
|
||||
} catch (error) {
|
||||
(0, import_stackTrace.rewriteErrorMessage)(error, `Error setting storage state:
|
||||
` + error.message);
|
||||
throw error;
|
||||
} finally {
|
||||
if (mode !== "resetForReuse")
|
||||
await page?.close();
|
||||
else if (interceptor)
|
||||
await page?.removeRequestInterceptor(interceptor);
|
||||
}
|
||||
}
|
||||
async extendInjectedScript(source, arg) {
|
||||
const installInFrame = (frame) => frame.extendInjectedScript(source, arg).catch(() => {
|
||||
});
|
||||
const installInPage = (page) => {
|
||||
page.on(import_page2.Page.Events.InternalFrameNavigatedToNewDocument, installInFrame);
|
||||
return Promise.all(page.frames().map(installInFrame));
|
||||
};
|
||||
this.on(BrowserContext.Events.Page, installInPage);
|
||||
return Promise.all(this.pages().map(installInPage));
|
||||
}
|
||||
async safeNonStallingEvaluateInAllFrames(expression, world, options = {}) {
|
||||
await Promise.all(this.pages().map((page) => page.safeNonStallingEvaluateInAllFrames(expression, world, options)));
|
||||
}
|
||||
harStart(page, options) {
|
||||
const harId = (0, import_crypto.createGuid)();
|
||||
this._harRecorders.set(harId, new import_harRecorder.HarRecorder(this, page, options));
|
||||
return harId;
|
||||
}
|
||||
async harExport(harId) {
|
||||
const recorder = this._harRecorders.get(harId || "");
|
||||
return recorder.export();
|
||||
}
|
||||
addRouteInFlight(route) {
|
||||
this._routesInFlight.add(route);
|
||||
}
|
||||
removeRouteInFlight(route) {
|
||||
this._routesInFlight.delete(route);
|
||||
}
|
||||
async notifyRoutesInFlightAboutRemovedHandler(handler) {
|
||||
await Promise.all([...this._routesInFlight].map((route) => route.removeHandler(handler)));
|
||||
}
|
||||
}
|
||||
function validateBrowserContextOptions(options, browserOptions) {
|
||||
if (options.noDefaultViewport && options.deviceScaleFactor !== void 0)
|
||||
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
||||
if (options.noDefaultViewport && !!options.isMobile)
|
||||
throw new Error(`"isMobile" option is not supported with null "viewport"`);
|
||||
if (options.acceptDownloads === void 0 && browserOptions.name !== "electron")
|
||||
options.acceptDownloads = "accept";
|
||||
else if (options.acceptDownloads === void 0 && browserOptions.name === "electron")
|
||||
options.acceptDownloads = "internal-browser-default";
|
||||
if (!options.viewport && !options.noDefaultViewport)
|
||||
options.viewport = { width: 1280, height: 720 };
|
||||
if (options.recordVideo) {
|
||||
if (!options.recordVideo.size) {
|
||||
if (options.noDefaultViewport) {
|
||||
options.recordVideo.size = { width: 800, height: 600 };
|
||||
} else {
|
||||
const size = options.viewport;
|
||||
const scale = Math.min(1, 800 / Math.max(size.width, size.height));
|
||||
options.recordVideo.size = {
|
||||
width: Math.floor(size.width * scale),
|
||||
height: Math.floor(size.height * scale)
|
||||
};
|
||||
}
|
||||
}
|
||||
options.recordVideo.size.width &= ~1;
|
||||
options.recordVideo.size.height &= ~1;
|
||||
}
|
||||
if (options.proxy)
|
||||
options.proxy = normalizeProxySettings(options.proxy);
|
||||
verifyGeolocation(options.geolocation);
|
||||
}
|
||||
function verifyGeolocation(geolocation) {
|
||||
if (!geolocation)
|
||||
return;
|
||||
geolocation.accuracy = geolocation.accuracy || 0;
|
||||
const { longitude, latitude, accuracy } = geolocation;
|
||||
if (longitude < -180 || longitude > 180)
|
||||
throw new Error(`geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.`);
|
||||
if (latitude < -90 || latitude > 90)
|
||||
throw new Error(`geolocation.latitude: precondition -90 <= LATITUDE <= 90 failed.`);
|
||||
if (accuracy < 0)
|
||||
throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);
|
||||
}
|
||||
function verifyClientCertificates(clientCertificates) {
|
||||
if (!clientCertificates)
|
||||
return;
|
||||
for (const cert of clientCertificates) {
|
||||
if (!cert.origin)
|
||||
throw new Error(`clientCertificates.origin is required`);
|
||||
if (!cert.cert && !cert.key && !cert.passphrase && !cert.pfx)
|
||||
throw new Error("None of cert, key, passphrase or pfx is specified");
|
||||
if (cert.cert && !cert.key)
|
||||
throw new Error("cert is specified without key");
|
||||
if (!cert.cert && cert.key)
|
||||
throw new Error("key is specified without cert");
|
||||
if (cert.pfx && (cert.cert || cert.key))
|
||||
throw new Error("pfx is specified together with cert, key or passphrase");
|
||||
}
|
||||
}
|
||||
function normalizeProxySettings(proxy) {
|
||||
let { server, bypass } = proxy;
|
||||
let url;
|
||||
try {
|
||||
url = new URL(server);
|
||||
if (!url.host || !url.protocol)
|
||||
url = new URL("http://" + server);
|
||||
} catch (e) {
|
||||
url = new URL("http://" + server);
|
||||
}
|
||||
if (url.protocol === "socks4:" && (proxy.username || proxy.password))
|
||||
throw new Error(`Socks4 proxy protocol does not support authentication`);
|
||||
if (url.protocol === "socks5:" && (proxy.username || proxy.password))
|
||||
throw new Error(`Browser does not support socks5 proxy authentication`);
|
||||
server = url.protocol + "//" + url.host;
|
||||
if (bypass)
|
||||
bypass = bypass.split(",").map((t) => t.trim()).join(",");
|
||||
return { ...proxy, server, bypass };
|
||||
}
|
||||
const paramsThatAllowContextReuse = [
|
||||
"colorScheme",
|
||||
"forcedColors",
|
||||
"reducedMotion",
|
||||
"contrast",
|
||||
"screen",
|
||||
"userAgent",
|
||||
"viewport",
|
||||
"testIdAttributeName"
|
||||
];
|
||||
const defaultNewContextParamValues = {
|
||||
noDefaultViewport: false,
|
||||
ignoreHTTPSErrors: false,
|
||||
javaScriptEnabled: true,
|
||||
bypassCSP: false,
|
||||
offline: false,
|
||||
isMobile: false,
|
||||
hasTouch: false,
|
||||
acceptDownloads: "accept",
|
||||
strictSelectors: false,
|
||||
serviceWorkers: "allow",
|
||||
locale: "en-US"
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserContext,
|
||||
normalizeProxySettings,
|
||||
validateBrowserContextOptions,
|
||||
verifyClientCertificates,
|
||||
verifyGeolocation
|
||||
});
|
||||
328
.playwright-mcp/node_modules/playwright-core/lib/server/browserType.js
generated
vendored
Normal file
328
.playwright-mcp/node_modules/playwright-core/lib/server/browserType.js
generated
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserType_exports = {};
|
||||
__export(browserType_exports, {
|
||||
BrowserType: () => BrowserType,
|
||||
kNoXServerRunningError: () => kNoXServerRunningError
|
||||
});
|
||||
module.exports = __toCommonJS(browserType_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_browserContext = require("./browserContext");
|
||||
var import_debug = require("./utils/debug");
|
||||
var import_assert = require("../utils/isomorphic/assert");
|
||||
var import_manualPromise = require("../utils/isomorphic/manualPromise");
|
||||
var import_time = require("../utils/isomorphic/time");
|
||||
var import_fileUtils = require("./utils/fileUtils");
|
||||
var import_helper = require("./helper");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_pipeTransport = require("./pipeTransport");
|
||||
var import_processLauncher = require("./utils/processLauncher");
|
||||
var import_protocolError = require("./protocolError");
|
||||
var import_registry = require("./registry");
|
||||
var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
|
||||
var import_transport = require("./transport");
|
||||
var import_debugLogger = require("./utils/debugLogger");
|
||||
const kNoXServerRunningError = "Looks like you launched a headed browser without having a XServer running.\nSet either 'headless: true' or use 'xvfb-run <your-playwright-app>' before running Playwright.\n\n<3 Playwright Team";
|
||||
class BrowserType extends import_instrumentation.SdkObject {
|
||||
constructor(parent, browserName) {
|
||||
super(parent, "browser-type");
|
||||
this.attribution.browserType = this;
|
||||
this._name = browserName;
|
||||
this.logName = "browser";
|
||||
}
|
||||
executablePath() {
|
||||
return import_registry.registry.findExecutable(this._name).executablePath(this.attribution.playwright.options.sdkLanguage) || "";
|
||||
}
|
||||
name() {
|
||||
return this._name;
|
||||
}
|
||||
async launch(progress, options, protocolLogger) {
|
||||
options = this._validateLaunchOptions(options);
|
||||
const seleniumHubUrl = options.__testHookSeleniumRemoteURL || process.env.SELENIUM_REMOTE_URL;
|
||||
if (seleniumHubUrl)
|
||||
return this._launchWithSeleniumHub(progress, seleniumHubUrl, options);
|
||||
return this._innerLaunchWithRetries(progress, options, void 0, import_helper.helper.debugProtocolLogger(protocolLogger)).catch((e) => {
|
||||
throw this._rewriteStartupLog(e);
|
||||
});
|
||||
}
|
||||
async launchPersistentContext(progress, userDataDir, options) {
|
||||
const launchOptions = this._validateLaunchOptions(options);
|
||||
let clientCertificatesProxy;
|
||||
if (options.clientCertificates?.length) {
|
||||
clientCertificatesProxy = await import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(progress, options);
|
||||
launchOptions.proxyOverride = clientCertificatesProxy.proxySettings();
|
||||
options = { ...options };
|
||||
options.internalIgnoreHTTPSErrors = true;
|
||||
}
|
||||
try {
|
||||
const browser = await this._innerLaunchWithRetries(progress, launchOptions, options, import_helper.helper.debugProtocolLogger(), userDataDir).catch((e) => {
|
||||
throw this._rewriteStartupLog(e);
|
||||
});
|
||||
browser._defaultContext._clientCertificatesProxy = clientCertificatesProxy;
|
||||
return browser._defaultContext;
|
||||
} catch (error) {
|
||||
await clientCertificatesProxy?.close().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async _innerLaunchWithRetries(progress, options, persistent, protocolLogger, userDataDir) {
|
||||
try {
|
||||
return await this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
|
||||
} catch (error) {
|
||||
const errorMessage = typeof error === "object" && typeof error.message === "string" ? error.message : "";
|
||||
if (errorMessage.includes("Inconsistency detected by ld.so")) {
|
||||
progress.log(`<restarting browser due to hitting race condition in glibc>`);
|
||||
return this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async _innerLaunch(progress, options, persistent, protocolLogger, maybeUserDataDir) {
|
||||
options.proxy = options.proxy ? (0, import_browserContext.normalizeProxySettings)(options.proxy) : void 0;
|
||||
const browserLogsCollector = new import_debugLogger.RecentLogsCollector();
|
||||
const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
|
||||
try {
|
||||
if (options.__testHookBeforeCreateBrowser)
|
||||
await progress.race(options.__testHookBeforeCreateBrowser());
|
||||
const browserOptions = {
|
||||
name: this._name,
|
||||
isChromium: this._name === "chromium",
|
||||
channel: options.channel,
|
||||
slowMo: options.slowMo,
|
||||
persistent,
|
||||
headful: !options.headless,
|
||||
artifactsDir,
|
||||
downloadsPath: options.downloadsPath || artifactsDir,
|
||||
tracesDir: options.tracesDir || artifactsDir,
|
||||
browserProcess,
|
||||
customExecutablePath: options.executablePath,
|
||||
proxy: options.proxy,
|
||||
protocolLogger,
|
||||
browserLogsCollector,
|
||||
wsEndpoint: transport instanceof import_transport.WebSocketTransport ? transport.wsEndpoint : void 0,
|
||||
originalLaunchOptions: options
|
||||
};
|
||||
if (persistent)
|
||||
(0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
|
||||
copyTestHooks(options, browserOptions);
|
||||
const browser = await progress.race(this.connectToTransport(transport, browserOptions, browserLogsCollector));
|
||||
browser._userDataDirForTest = userDataDir;
|
||||
if (persistent && !options.ignoreAllDefaultArgs)
|
||||
await browser._defaultContext._loadDefaultContext(progress);
|
||||
return browser;
|
||||
} catch (error) {
|
||||
await browserProcess.close().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async _prepareToLaunch(options, isPersistent, userDataDir) {
|
||||
const {
|
||||
ignoreDefaultArgs,
|
||||
ignoreAllDefaultArgs,
|
||||
args = [],
|
||||
executablePath = null
|
||||
} = options;
|
||||
await this._createArtifactDirs(options);
|
||||
const tempDirectories = [];
|
||||
const artifactsDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-"));
|
||||
tempDirectories.push(artifactsDir);
|
||||
if (userDataDir) {
|
||||
(0, import_assert.assert)(import_path.default.isAbsolute(userDataDir), "userDataDir must be an absolute path");
|
||||
if (!await (0, import_fileUtils.existsAsync)(userDataDir))
|
||||
await import_fs.default.promises.mkdir(userDataDir, { recursive: true, mode: 448 });
|
||||
} else {
|
||||
userDataDir = await import_fs.default.promises.mkdtemp(import_path.default.join(import_os.default.tmpdir(), `playwright_${this._name}dev_profile-`));
|
||||
tempDirectories.push(userDataDir);
|
||||
}
|
||||
await this.prepareUserDataDir(options, userDataDir);
|
||||
const browserArguments = [];
|
||||
if (ignoreAllDefaultArgs)
|
||||
browserArguments.push(...args);
|
||||
else if (ignoreDefaultArgs)
|
||||
browserArguments.push(...(await this.defaultArgs(options, isPersistent, userDataDir)).filter((arg) => ignoreDefaultArgs.indexOf(arg) === -1));
|
||||
else
|
||||
browserArguments.push(...await this.defaultArgs(options, isPersistent, userDataDir));
|
||||
let executable;
|
||||
if (executablePath) {
|
||||
if (!await (0, import_fileUtils.existsAsync)(executablePath))
|
||||
throw new Error(`Failed to launch ${this._name} because executable doesn't exist at ${executablePath}`);
|
||||
executable = executablePath;
|
||||
} else {
|
||||
const registryExecutable = import_registry.registry.findExecutable(this.getExecutableName(options));
|
||||
if (!registryExecutable || registryExecutable.browserName !== this._name)
|
||||
throw new Error(`Unsupported ${this._name} channel "${options.channel}"`);
|
||||
executable = registryExecutable.executablePathOrDie(this.attribution.playwright.options.sdkLanguage);
|
||||
await import_registry.registry.validateHostRequirementsForExecutablesIfNeeded([registryExecutable], this.attribution.playwright.options.sdkLanguage);
|
||||
}
|
||||
return { executable, browserArguments, userDataDir, artifactsDir, tempDirectories };
|
||||
}
|
||||
async _launchProcess(progress, options, isPersistent, browserLogsCollector, userDataDir) {
|
||||
const {
|
||||
handleSIGINT = true,
|
||||
handleSIGTERM = true,
|
||||
handleSIGHUP = true
|
||||
} = options;
|
||||
const env = options.env ? (0, import_processLauncher.envArrayToObject)(options.env) : process.env;
|
||||
const prepared = await progress.race(this._prepareToLaunch(options, isPersistent, userDataDir));
|
||||
let transport = void 0;
|
||||
let browserProcess = void 0;
|
||||
const exitPromise = new import_manualPromise.ManualPromise();
|
||||
const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
|
||||
command: prepared.executable,
|
||||
args: prepared.browserArguments,
|
||||
env: this.amendEnvironment(env, prepared.userDataDir, isPersistent, options),
|
||||
handleSIGINT,
|
||||
handleSIGTERM,
|
||||
handleSIGHUP,
|
||||
log: (message) => {
|
||||
progress.log(message);
|
||||
browserLogsCollector.log(message);
|
||||
},
|
||||
stdio: "pipe",
|
||||
tempDirectories: prepared.tempDirectories,
|
||||
attemptToGracefullyClose: async () => {
|
||||
if (options.__testHookGracefullyClose)
|
||||
await options.__testHookGracefullyClose();
|
||||
if (transport) {
|
||||
this.attemptToGracefullyCloseBrowser(transport);
|
||||
} else {
|
||||
throw new Error("Force-killing the browser because no transport is available to gracefully close it.");
|
||||
}
|
||||
},
|
||||
onExit: (exitCode, signal) => {
|
||||
exitPromise.resolve();
|
||||
if (browserProcess && browserProcess.onclose)
|
||||
browserProcess.onclose(exitCode, signal);
|
||||
}
|
||||
});
|
||||
async function closeOrKill(timeout) {
|
||||
let timer;
|
||||
try {
|
||||
await Promise.race([
|
||||
gracefullyClose(),
|
||||
new Promise((resolve, reject) => timer = setTimeout(reject, timeout))
|
||||
]);
|
||||
} catch (ignored) {
|
||||
await kill().catch((ignored2) => {
|
||||
});
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
browserProcess = {
|
||||
onclose: void 0,
|
||||
process: launchedProcess,
|
||||
close: () => closeOrKill(options.__testHookBrowserCloseTimeout || import_time.DEFAULT_PLAYWRIGHT_TIMEOUT),
|
||||
kill
|
||||
};
|
||||
try {
|
||||
const { wsEndpoint } = await progress.race([
|
||||
this.waitForReadyState(options, browserLogsCollector),
|
||||
exitPromise.then(() => ({ wsEndpoint: void 0 }))
|
||||
]);
|
||||
if (options.cdpPort !== void 0 || !this.supportsPipeTransport()) {
|
||||
transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint);
|
||||
} else {
|
||||
const stdio = launchedProcess.stdio;
|
||||
transport = new import_pipeTransport.PipeTransport(stdio[3], stdio[4]);
|
||||
}
|
||||
return { browserProcess, artifactsDir: prepared.artifactsDir, userDataDir: prepared.userDataDir, transport };
|
||||
} catch (error) {
|
||||
await closeOrKill(import_time.DEFAULT_PLAYWRIGHT_TIMEOUT).catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async _createArtifactDirs(options) {
|
||||
if (options.downloadsPath)
|
||||
await import_fs.default.promises.mkdir(options.downloadsPath, { recursive: true });
|
||||
if (options.tracesDir)
|
||||
await import_fs.default.promises.mkdir(options.tracesDir, { recursive: true });
|
||||
}
|
||||
async connectOverCDP(progress, endpointURL, options) {
|
||||
throw new Error("CDP connections are only supported by Chromium");
|
||||
}
|
||||
async _launchWithSeleniumHub(progress, hubUrl, options) {
|
||||
throw new Error("Connecting to SELENIUM_REMOTE_URL is only supported by Chromium");
|
||||
}
|
||||
_validateLaunchOptions(options) {
|
||||
const { devtools = false } = options;
|
||||
let { headless = !devtools, downloadsPath, proxy } = options;
|
||||
if ((0, import_debug.debugMode)() === "inspector")
|
||||
headless = false;
|
||||
if (downloadsPath && !import_path.default.isAbsolute(downloadsPath))
|
||||
downloadsPath = import_path.default.join(process.cwd(), downloadsPath);
|
||||
if (options.socksProxyPort)
|
||||
proxy = { server: `socks5://127.0.0.1:${options.socksProxyPort}` };
|
||||
return { ...options, devtools, headless, downloadsPath, proxy };
|
||||
}
|
||||
_createUserDataDirArgMisuseError(userDataDirArg) {
|
||||
switch (this.attribution.playwright.options.sdkLanguage) {
|
||||
case "java":
|
||||
return new Error(`Pass userDataDir parameter to 'BrowserType.launchPersistentContext(userDataDir, options)' instead of specifying '${userDataDirArg}' argument`);
|
||||
case "python":
|
||||
return new Error(`Pass user_data_dir parameter to 'browser_type.launch_persistent_context(user_data_dir, **kwargs)' instead of specifying '${userDataDirArg}' argument`);
|
||||
case "csharp":
|
||||
return new Error(`Pass userDataDir parameter to 'BrowserType.LaunchPersistentContextAsync(userDataDir, options)' instead of specifying '${userDataDirArg}' argument`);
|
||||
default:
|
||||
return new Error(`Pass userDataDir parameter to 'browserType.launchPersistentContext(userDataDir, options)' instead of specifying '${userDataDirArg}' argument`);
|
||||
}
|
||||
}
|
||||
_rewriteStartupLog(error) {
|
||||
if (!(0, import_protocolError.isProtocolError)(error))
|
||||
return error;
|
||||
return this.doRewriteStartupLog(error);
|
||||
}
|
||||
async waitForReadyState(options, browserLogsCollector) {
|
||||
return {};
|
||||
}
|
||||
async prepareUserDataDir(options, userDataDir) {
|
||||
}
|
||||
supportsPipeTransport() {
|
||||
return true;
|
||||
}
|
||||
getExecutableName(options) {
|
||||
return options.channel || this._name;
|
||||
}
|
||||
}
|
||||
function copyTestHooks(from, to) {
|
||||
for (const [key, value] of Object.entries(from)) {
|
||||
if (key.startsWith("__testHook"))
|
||||
to[key] = value;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserType,
|
||||
kNoXServerRunningError
|
||||
});
|
||||
82
.playwright-mcp/node_modules/playwright-core/lib/server/callLog.js
generated
vendored
Normal file
82
.playwright-mcp/node_modules/playwright-core/lib/server/callLog.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var callLog_exports = {};
|
||||
__export(callLog_exports, {
|
||||
compressCallLog: () => compressCallLog,
|
||||
findRepeatedSubsequencesForTest: () => findRepeatedSubsequencesForTest
|
||||
});
|
||||
module.exports = __toCommonJS(callLog_exports);
|
||||
function compressCallLog(log) {
|
||||
const lines = [];
|
||||
for (const block of findRepeatedSubsequences(log)) {
|
||||
for (let i = 0; i < block.sequence.length; i++) {
|
||||
const line = block.sequence[i];
|
||||
const leadingWhitespace = line.match(/^\s*/);
|
||||
const whitespacePrefix = " " + leadingWhitespace?.[0] || "";
|
||||
const countPrefix = `${block.count} \xD7 `;
|
||||
if (block.count > 1 && i === 0)
|
||||
lines.push(whitespacePrefix + countPrefix + line.trim());
|
||||
else if (block.count > 1)
|
||||
lines.push(whitespacePrefix + " ".repeat(countPrefix.length - 2) + "- " + line.trim());
|
||||
else
|
||||
lines.push(whitespacePrefix + "- " + line.trim());
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
function findRepeatedSubsequences(s) {
|
||||
const n = s.length;
|
||||
const result = [];
|
||||
let i = 0;
|
||||
const arraysEqual = (a1, a2) => {
|
||||
if (a1.length !== a2.length)
|
||||
return false;
|
||||
for (let j = 0; j < a1.length; j++) {
|
||||
if (a1[j] !== a2[j])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
while (i < n) {
|
||||
let maxRepeatCount = 1;
|
||||
let maxRepeatSubstr = [s[i]];
|
||||
let maxRepeatLength = 1;
|
||||
for (let p = 1; p <= n - i; p++) {
|
||||
const substr = s.slice(i, i + p);
|
||||
let k = 1;
|
||||
while (i + p * k <= n && arraysEqual(s.slice(i + p * (k - 1), i + p * k), substr))
|
||||
k += 1;
|
||||
k -= 1;
|
||||
if (k > 1 && k * p > maxRepeatCount * maxRepeatLength) {
|
||||
maxRepeatCount = k;
|
||||
maxRepeatSubstr = substr;
|
||||
maxRepeatLength = p;
|
||||
}
|
||||
}
|
||||
result.push({ sequence: maxRepeatSubstr, count: maxRepeatCount });
|
||||
i += maxRepeatLength * maxRepeatCount;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
const findRepeatedSubsequencesForTest = findRepeatedSubsequences;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
compressCallLog,
|
||||
findRepeatedSubsequencesForTest
|
||||
});
|
||||
BIN
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/appIcon.png
generated
vendored
Normal file
BIN
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/appIcon.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
402
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/chromium.js
generated
vendored
Normal file
402
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/chromium.js
generated
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var chromium_exports = {};
|
||||
__export(chromium_exports, {
|
||||
Chromium: () => Chromium,
|
||||
waitForReadyState: () => waitForReadyState
|
||||
});
|
||||
module.exports = __toCommonJS(chromium_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_chromiumSwitches = require("./chromiumSwitches");
|
||||
var import_crBrowser = require("./crBrowser");
|
||||
var import_crConnection = require("./crConnection");
|
||||
var import_utils = require("../../utils");
|
||||
var import_ascii = require("../utils/ascii");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
||||
var import_network = require("../utils/network");
|
||||
var import_userAgent = require("../utils/userAgent");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_browserType = require("../browserType");
|
||||
var import_helper = require("../helper");
|
||||
var import_registry = require("../registry");
|
||||
var import_transport = require("../transport");
|
||||
var import_crDevTools = require("./crDevTools");
|
||||
var import_browser = require("../browser");
|
||||
var import_fileUtils = require("../utils/fileUtils");
|
||||
var import_processLauncher = require("../utils/processLauncher");
|
||||
const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
|
||||
class Chromium extends import_browserType.BrowserType {
|
||||
constructor(parent, bidiChromium) {
|
||||
super(parent, "chromium");
|
||||
this._bidiChromium = bidiChromium;
|
||||
if ((0, import_utils.debugMode)() === "inspector")
|
||||
this._devtools = this._createDevTools();
|
||||
}
|
||||
launch(progress, options, protocolLogger) {
|
||||
if (options.channel?.startsWith("bidi-"))
|
||||
return this._bidiChromium.launch(progress, options, protocolLogger);
|
||||
return super.launch(progress, options, protocolLogger);
|
||||
}
|
||||
async launchPersistentContext(progress, userDataDir, options) {
|
||||
if (options.channel?.startsWith("bidi-"))
|
||||
return this._bidiChromium.launchPersistentContext(progress, userDataDir, options);
|
||||
return super.launchPersistentContext(progress, userDataDir, options);
|
||||
}
|
||||
async connectOverCDP(progress, endpointURL, options) {
|
||||
return await this._connectOverCDPInternal(progress, endpointURL, options);
|
||||
}
|
||||
async _connectOverCDPInternal(progress, endpointURL, options, onClose) {
|
||||
let headersMap;
|
||||
if (options.headers)
|
||||
headersMap = (0, import_utils.headersArrayToObject)(options.headers, false);
|
||||
if (!headersMap)
|
||||
headersMap = { "User-Agent": (0, import_userAgent.getUserAgent)() };
|
||||
else if (headersMap && !Object.keys(headersMap).some((key) => key.toLowerCase() === "user-agent"))
|
||||
headersMap["User-Agent"] = (0, import_userAgent.getUserAgent)();
|
||||
const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
|
||||
const doCleanup = async () => {
|
||||
await (0, import_fileUtils.removeFolders)([artifactsDir]);
|
||||
const cb = onClose;
|
||||
onClose = void 0;
|
||||
await cb?.();
|
||||
};
|
||||
let chromeTransport;
|
||||
const doClose = async () => {
|
||||
await chromeTransport?.closeAndWait();
|
||||
await doCleanup();
|
||||
};
|
||||
try {
|
||||
const wsEndpoint = await urlToWSEndpoint(progress, endpointURL, headersMap);
|
||||
chromeTransport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: headersMap });
|
||||
const browserProcess = { close: doClose, kill: doClose };
|
||||
const persistent = { noDefaultViewport: true };
|
||||
const browserOptions = {
|
||||
slowMo: options.slowMo,
|
||||
name: "chromium",
|
||||
isChromium: true,
|
||||
persistent,
|
||||
browserProcess,
|
||||
protocolLogger: import_helper.helper.debugProtocolLogger(),
|
||||
browserLogsCollector: new import_debugLogger.RecentLogsCollector(),
|
||||
artifactsDir,
|
||||
downloadsPath: options.downloadsPath || artifactsDir,
|
||||
tracesDir: options.tracesDir || artifactsDir,
|
||||
originalLaunchOptions: {}
|
||||
};
|
||||
(0, import_browserContext.validateBrowserContextOptions)(persistent, browserOptions);
|
||||
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
|
||||
browser._isCollocatedWithServer = false;
|
||||
browser.on(import_browser.Browser.Events.Disconnected, doCleanup);
|
||||
return browser;
|
||||
} catch (error) {
|
||||
await doClose().catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
_createDevTools() {
|
||||
const directory = import_registry.registry.findExecutable("chromium").directory;
|
||||
return directory ? new import_crDevTools.CRDevTools(import_path.default.join(directory, "devtools-preferences.json")) : void 0;
|
||||
}
|
||||
async connectToTransport(transport, options, browserLogsCollector) {
|
||||
let devtools = this._devtools;
|
||||
if (options.__testHookForDevTools) {
|
||||
devtools = this._createDevTools();
|
||||
await options.__testHookForDevTools(devtools);
|
||||
}
|
||||
try {
|
||||
return await import_crBrowser.CRBrowser.connect(this.attribution.playwright, transport, options, devtools);
|
||||
} catch (e) {
|
||||
if (browserLogsCollector.recentLogs().some((log) => log.includes("Failed to create a ProcessSingleton for your profile directory."))) {
|
||||
throw new Error(
|
||||
"Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."
|
||||
);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
doRewriteStartupLog(error) {
|
||||
if (!error.logs)
|
||||
return error;
|
||||
if (error.logs.includes("Missing X server"))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
||||
if (!error.logs.includes("crbug.com/357670") && !error.logs.includes("No usable sandbox!") && !error.logs.includes("crbug.com/638180"))
|
||||
return error;
|
||||
error.logs = [
|
||||
`Chromium sandboxing failed!`,
|
||||
`================================`,
|
||||
`To avoid the sandboxing issue, do either of the following:`,
|
||||
` - (preferred): Configure your environment to support sandboxing`,
|
||||
` - (alternative): Launch Chromium without sandbox using 'chromiumSandbox: false' option`,
|
||||
`================================`,
|
||||
``
|
||||
].join("\n");
|
||||
return error;
|
||||
}
|
||||
amendEnvironment(env) {
|
||||
return env;
|
||||
}
|
||||
attemptToGracefullyCloseBrowser(transport) {
|
||||
const message = { method: "Browser.close", id: import_crConnection.kBrowserCloseMessageId, params: {} };
|
||||
transport.send(message);
|
||||
}
|
||||
async _launchWithSeleniumHub(progress, hubUrl, options) {
|
||||
await progress.race(this._createArtifactDirs(options));
|
||||
if (!hubUrl.endsWith("/"))
|
||||
hubUrl = hubUrl + "/";
|
||||
const args = this._innerDefaultArgs(options);
|
||||
args.push("--remote-debugging-port=0");
|
||||
const isEdge = options.channel && options.channel.startsWith("msedge");
|
||||
let desiredCapabilities = {
|
||||
"browserName": isEdge ? "MicrosoftEdge" : "chrome",
|
||||
[isEdge ? "ms:edgeOptions" : "goog:chromeOptions"]: { args }
|
||||
};
|
||||
if (process.env.SELENIUM_REMOTE_CAPABILITIES) {
|
||||
const remoteCapabilities = parseSeleniumRemoteParams({ name: "capabilities", value: process.env.SELENIUM_REMOTE_CAPABILITIES }, progress);
|
||||
if (remoteCapabilities)
|
||||
desiredCapabilities = { ...desiredCapabilities, ...remoteCapabilities };
|
||||
}
|
||||
let headers = {};
|
||||
if (process.env.SELENIUM_REMOTE_HEADERS) {
|
||||
const remoteHeaders = parseSeleniumRemoteParams({ name: "headers", value: process.env.SELENIUM_REMOTE_HEADERS }, progress);
|
||||
if (remoteHeaders)
|
||||
headers = remoteHeaders;
|
||||
}
|
||||
progress.log(`<selenium> connecting to ${hubUrl}`);
|
||||
const response = await (0, import_network.fetchData)(progress, {
|
||||
url: hubUrl + "session",
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
...headers
|
||||
},
|
||||
data: JSON.stringify({
|
||||
capabilities: { alwaysMatch: desiredCapabilities }
|
||||
})
|
||||
}, seleniumErrorHandler);
|
||||
const value = JSON.parse(response).value;
|
||||
const sessionId = value.sessionId;
|
||||
progress.log(`<selenium> connected to sessionId=${sessionId}`);
|
||||
const disconnectFromSelenium = async () => {
|
||||
progress.log(`<selenium> disconnecting from sessionId=${sessionId}`);
|
||||
await (0, import_network.fetchData)(void 0, {
|
||||
url: hubUrl + "session/" + sessionId,
|
||||
method: "DELETE",
|
||||
headers
|
||||
}).catch((error) => progress.log(`<error disconnecting from selenium>: ${error}`));
|
||||
progress.log(`<selenium> disconnected from sessionId=${sessionId}`);
|
||||
import_processLauncher.gracefullyCloseSet.delete(disconnectFromSelenium);
|
||||
};
|
||||
import_processLauncher.gracefullyCloseSet.add(disconnectFromSelenium);
|
||||
try {
|
||||
const capabilities = value.capabilities;
|
||||
let endpointURL;
|
||||
if (capabilities["se:cdp"]) {
|
||||
progress.log(`<selenium> using selenium v4`);
|
||||
const endpointURLString = addProtocol(capabilities["se:cdp"]);
|
||||
endpointURL = new URL(endpointURLString);
|
||||
if (endpointURL.hostname === "localhost" || endpointURL.hostname === "127.0.0.1")
|
||||
endpointURL.hostname = new URL(hubUrl).hostname;
|
||||
progress.log(`<selenium> retrieved endpoint ${endpointURL.toString()} for sessionId=${sessionId}`);
|
||||
} else {
|
||||
progress.log(`<selenium> using selenium v3`);
|
||||
const maybeChromeOptions = capabilities["goog:chromeOptions"];
|
||||
const chromeOptions = maybeChromeOptions && typeof maybeChromeOptions === "object" ? maybeChromeOptions : void 0;
|
||||
const debuggerAddress = chromeOptions && typeof chromeOptions.debuggerAddress === "string" ? chromeOptions.debuggerAddress : void 0;
|
||||
const chromeOptionsURL = typeof maybeChromeOptions === "string" ? maybeChromeOptions : void 0;
|
||||
const endpointURLString = addProtocol(debuggerAddress || chromeOptionsURL).replace("localhost", "127.0.0.1");
|
||||
progress.log(`<selenium> retrieved endpoint ${endpointURLString} for sessionId=${sessionId}`);
|
||||
endpointURL = new URL(endpointURLString);
|
||||
if (endpointURL.hostname === "localhost" || endpointURL.hostname === "127.0.0.1") {
|
||||
const sessionInfoUrl = new URL(hubUrl).origin + "/grid/api/testsession?session=" + sessionId;
|
||||
try {
|
||||
const sessionResponse = await (0, import_network.fetchData)(progress, {
|
||||
url: sessionInfoUrl,
|
||||
method: "GET",
|
||||
headers
|
||||
}, seleniumErrorHandler);
|
||||
const proxyId = JSON.parse(sessionResponse).proxyId;
|
||||
endpointURL.hostname = new URL(proxyId).hostname;
|
||||
progress.log(`<selenium> resolved endpoint ip ${endpointURL.toString()} for sessionId=${sessionId}`);
|
||||
} catch (e) {
|
||||
progress.log(`<selenium> unable to resolve endpoint ip for sessionId=${sessionId}, running in standalone?`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return await this._connectOverCDPInternal(progress, endpointURL.toString(), {
|
||||
...options,
|
||||
headers: (0, import_utils.headersObjectToArray)(headers)
|
||||
}, disconnectFromSelenium);
|
||||
} catch (e) {
|
||||
await disconnectFromSelenium();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async defaultArgs(options, isPersistent, userDataDir) {
|
||||
const chromeArguments = this._innerDefaultArgs(options);
|
||||
chromeArguments.push(`--user-data-dir=${userDataDir}`);
|
||||
if (options.cdpPort !== void 0)
|
||||
chromeArguments.push(`--remote-debugging-port=${options.cdpPort}`);
|
||||
else
|
||||
chromeArguments.push("--remote-debugging-pipe");
|
||||
if (isPersistent)
|
||||
chromeArguments.push("about:blank");
|
||||
else
|
||||
chromeArguments.push("--no-startup-window");
|
||||
return chromeArguments;
|
||||
}
|
||||
_innerDefaultArgs(options) {
|
||||
const { args = [] } = options;
|
||||
const userDataDirArg = args.find((arg) => arg.startsWith("--user-data-dir"));
|
||||
if (userDataDirArg)
|
||||
throw this._createUserDataDirArgMisuseError("--user-data-dir");
|
||||
if (args.find((arg) => arg.startsWith("--remote-debugging-pipe")))
|
||||
throw new Error("Playwright manages remote debugging connection itself.");
|
||||
if (args.find((arg) => !arg.startsWith("-")))
|
||||
throw new Error("Arguments can not specify page to be opened");
|
||||
const chromeArguments = [...(0, import_chromiumSwitches.chromiumSwitches)(options.assistantMode, options.channel)];
|
||||
if (import_os.default.platform() === "darwin") {
|
||||
chromeArguments.push("--enable-unsafe-swiftshader");
|
||||
}
|
||||
if (options.devtools)
|
||||
chromeArguments.push("--auto-open-devtools-for-tabs");
|
||||
if (options.headless) {
|
||||
chromeArguments.push("--headless");
|
||||
chromeArguments.push(
|
||||
"--hide-scrollbars",
|
||||
"--mute-audio",
|
||||
"--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4"
|
||||
);
|
||||
}
|
||||
if (options.chromiumSandbox !== true)
|
||||
chromeArguments.push("--no-sandbox");
|
||||
const proxy = options.proxyOverride || options.proxy;
|
||||
if (proxy) {
|
||||
const proxyURL = new URL(proxy.server);
|
||||
const isSocks = proxyURL.protocol === "socks5:";
|
||||
if (isSocks && !options.socksProxyPort) {
|
||||
chromeArguments.push(`--host-resolver-rules="MAP * ~NOTFOUND , EXCLUDE ${proxyURL.hostname}"`);
|
||||
}
|
||||
chromeArguments.push(`--proxy-server=${proxy.server}`);
|
||||
const proxyBypassRules = [];
|
||||
if (options.socksProxyPort)
|
||||
proxyBypassRules.push("<-loopback>");
|
||||
if (proxy.bypass)
|
||||
proxyBypassRules.push(...proxy.bypass.split(",").map((t) => t.trim()).map((t) => t.startsWith(".") ? "*" + t : t));
|
||||
if (!process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK && !proxyBypassRules.includes("<-loopback>"))
|
||||
proxyBypassRules.push("<-loopback>");
|
||||
if (proxyBypassRules.length > 0)
|
||||
chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(";")}`);
|
||||
}
|
||||
chromeArguments.push(...args);
|
||||
return chromeArguments;
|
||||
}
|
||||
async waitForReadyState(options, browserLogsCollector) {
|
||||
return waitForReadyState(options, browserLogsCollector);
|
||||
}
|
||||
getExecutableName(options) {
|
||||
if (options.channel)
|
||||
return options.channel;
|
||||
return options.headless ? "chromium-headless-shell" : "chromium";
|
||||
}
|
||||
}
|
||||
async function waitForReadyState(options, browserLogsCollector) {
|
||||
if (options.cdpPort === void 0 && !options.args?.some((a) => a.startsWith("--remote-debugging-port")))
|
||||
return {};
|
||||
const result = new import_manualPromise.ManualPromise();
|
||||
browserLogsCollector.onMessage((message) => {
|
||||
if (message.includes("Failed to create a ProcessSingleton for your profile directory.")) {
|
||||
result.reject(new Error("Failed to create a ProcessSingleton for your profile directory. This usually means that the profile is already in use by another instance of Chromium."));
|
||||
}
|
||||
const match = message.match(/DevTools listening on (.*)/);
|
||||
if (match)
|
||||
result.resolve({ wsEndpoint: match[1] });
|
||||
});
|
||||
return result;
|
||||
}
|
||||
async function urlToWSEndpoint(progress, endpointURL, headers) {
|
||||
if (endpointURL.startsWith("ws"))
|
||||
return endpointURL;
|
||||
progress.log(`<ws preparing> retrieving websocket url from ${endpointURL}`);
|
||||
const url = new URL(endpointURL);
|
||||
if (!url.pathname.endsWith("/"))
|
||||
url.pathname += "/";
|
||||
url.pathname += "json/version/";
|
||||
const httpURL = url.toString();
|
||||
const json = await (0, import_network.fetchData)(
|
||||
progress,
|
||||
{
|
||||
url: httpURL,
|
||||
headers
|
||||
},
|
||||
async (_, resp) => new Error(`Unexpected status ${resp.statusCode} when connecting to ${httpURL}.
|
||||
This does not look like a DevTools server, try connecting via ws://.`)
|
||||
);
|
||||
return JSON.parse(json).webSocketDebuggerUrl;
|
||||
}
|
||||
async function seleniumErrorHandler(params, response) {
|
||||
const body = await streamToString(response);
|
||||
let message = body;
|
||||
try {
|
||||
const json = JSON.parse(body);
|
||||
message = json.value.localizedMessage || json.value.message;
|
||||
} catch (e) {
|
||||
}
|
||||
return new Error(`Error connecting to Selenium at ${params.url}: ${message}`);
|
||||
}
|
||||
function addProtocol(url) {
|
||||
if (!["ws://", "wss://", "http://", "https://"].some((protocol) => url.startsWith(protocol)))
|
||||
return "http://" + url;
|
||||
return url;
|
||||
}
|
||||
function streamToString(stream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
||||
stream.on("error", reject);
|
||||
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
||||
});
|
||||
}
|
||||
function parseSeleniumRemoteParams(env, progress) {
|
||||
try {
|
||||
const parsed = JSON.parse(env.value);
|
||||
progress.log(`<selenium> using additional ${env.name} "${env.value}"`);
|
||||
return parsed;
|
||||
} catch (e) {
|
||||
progress.log(`<selenium> ignoring additional ${env.name} "${env.value}": ${e}`);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Chromium,
|
||||
waitForReadyState
|
||||
});
|
||||
104
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/chromiumSwitches.js
generated
vendored
Normal file
104
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/chromiumSwitches.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var chromiumSwitches_exports = {};
|
||||
__export(chromiumSwitches_exports, {
|
||||
chromiumSwitches: () => chromiumSwitches
|
||||
});
|
||||
module.exports = __toCommonJS(chromiumSwitches_exports);
|
||||
const disabledFeatures = (assistantMode) => [
|
||||
// See https://github.com/microsoft/playwright/pull/10380
|
||||
"AcceptCHFrame",
|
||||
// See https://github.com/microsoft/playwright/issues/14047
|
||||
"AvoidUnnecessaryBeforeUnloadCheckSync",
|
||||
"DestroyProfileOnBrowserClose",
|
||||
// See https://github.com/microsoft/playwright/pull/13854
|
||||
"DialMediaRouteProvider",
|
||||
"GlobalMediaControls",
|
||||
// See https://github.com/microsoft/playwright/pull/27605
|
||||
"HttpsUpgrades",
|
||||
// Hides the Lens feature in the URL address bar. Its not working in unofficial builds.
|
||||
"LensOverlay",
|
||||
// See https://github.com/microsoft/playwright/pull/8162
|
||||
"MediaRouter",
|
||||
// See https://github.com/microsoft/playwright/issues/28023
|
||||
"PaintHolding",
|
||||
// See https://github.com/microsoft/playwright/issues/32230
|
||||
"ThirdPartyStoragePartitioning",
|
||||
// See https://github.com/microsoft/playwright/issues/16126
|
||||
"Translate",
|
||||
// See https://issues.chromium.org/u/1/issues/435410220
|
||||
"AutoDeElevate",
|
||||
// See https://github.com/microsoft/playwright/issues/37714
|
||||
"RenderDocument",
|
||||
// Prevents downloading optimization hints on startup.
|
||||
"OptimizationHints",
|
||||
assistantMode ? "AutomationControlled" : ""
|
||||
].filter(Boolean);
|
||||
const chromiumSwitches = (assistantMode, channel, android) => [
|
||||
"--disable-field-trial-config",
|
||||
// https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
|
||||
"--disable-background-networking",
|
||||
"--disable-background-timer-throttling",
|
||||
"--disable-backgrounding-occluded-windows",
|
||||
"--disable-back-forward-cache",
|
||||
// Avoids surprises like main request not being intercepted during page.goBack().
|
||||
"--disable-breakpad",
|
||||
"--disable-client-side-phishing-detection",
|
||||
"--disable-component-extensions-with-background-pages",
|
||||
"--disable-component-update",
|
||||
// Avoids unneeded network activity after startup.
|
||||
"--no-default-browser-check",
|
||||
"--disable-default-apps",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-extensions",
|
||||
"--disable-features=" + disabledFeatures(assistantMode).join(","),
|
||||
process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? "" : "--enable-features=CDPScreenshotNewSurface",
|
||||
"--allow-pre-commit-input",
|
||||
"--disable-hang-monitor",
|
||||
"--disable-ipc-flooding-protection",
|
||||
"--disable-popup-blocking",
|
||||
"--disable-prompt-on-repost",
|
||||
"--disable-renderer-backgrounding",
|
||||
"--force-color-profile=srgb",
|
||||
"--metrics-recording-only",
|
||||
"--no-first-run",
|
||||
"--password-store=basic",
|
||||
"--use-mock-keychain",
|
||||
// See https://chromium-review.googlesource.com/c/chromium/src/+/2436773
|
||||
"--no-service-autorun",
|
||||
"--export-tagged-pdf",
|
||||
// https://chromium-review.googlesource.com/c/chromium/src/+/4853540
|
||||
"--disable-search-engine-choice-screen",
|
||||
// https://issues.chromium.org/41491762
|
||||
"--unsafely-disable-devtools-self-xss-warnings",
|
||||
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
|
||||
"--edge-skip-compat-layer-relaunch",
|
||||
assistantMode ? "" : "--enable-automation",
|
||||
// This disables Chrome for Testing infobar that is visible in the persistent context.
|
||||
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
|
||||
"--disable-infobars",
|
||||
// Less annoying popups.
|
||||
"--disable-search-engine-choice-screen",
|
||||
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
|
||||
android ? "" : "--disable-sync"
|
||||
].filter(Boolean);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
chromiumSwitches
|
||||
});
|
||||
510
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crBrowser.js
generated
vendored
Normal file
510
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crBrowser.js
generated
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crBrowser_exports = {};
|
||||
__export(crBrowser_exports, {
|
||||
CRBrowser: () => CRBrowser,
|
||||
CRBrowserContext: () => CRBrowserContext
|
||||
});
|
||||
module.exports = __toCommonJS(crBrowser_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_assert = require("../../utils/isomorphic/assert");
|
||||
var import_crypto = require("../utils/crypto");
|
||||
var import_artifact = require("../artifact");
|
||||
var import_browser = require("../browser");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_frames = require("../frames");
|
||||
var network = __toESM(require("../network"));
|
||||
var import_page = require("../page");
|
||||
var import_crConnection = require("./crConnection");
|
||||
var import_crPage = require("./crPage");
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
var import_crServiceWorker = require("./crServiceWorker");
|
||||
class CRBrowser extends import_browser.Browser {
|
||||
constructor(parent, connection, options) {
|
||||
super(parent, options);
|
||||
this._clientRootSessionPromise = null;
|
||||
this._contexts = /* @__PURE__ */ new Map();
|
||||
this._crPages = /* @__PURE__ */ new Map();
|
||||
this._serviceWorkers = /* @__PURE__ */ new Map();
|
||||
this._version = "";
|
||||
this._majorVersion = 0;
|
||||
this._tracingRecording = false;
|
||||
this._userAgent = "";
|
||||
this._connection = connection;
|
||||
this._session = this._connection.rootSession;
|
||||
this._connection.on(import_crConnection.ConnectionEvents.Disconnected, () => this._didDisconnect());
|
||||
this._session.on("Target.attachedToTarget", this._onAttachedToTarget.bind(this));
|
||||
this._session.on("Target.detachedFromTarget", this._onDetachedFromTarget.bind(this));
|
||||
this._session.on("Browser.downloadWillBegin", this._onDownloadWillBegin.bind(this));
|
||||
this._session.on("Browser.downloadProgress", this._onDownloadProgress.bind(this));
|
||||
}
|
||||
static async connect(parent, transport, options, devtools) {
|
||||
options = { ...options };
|
||||
const connection = new import_crConnection.CRConnection(parent, transport, options.protocolLogger, options.browserLogsCollector);
|
||||
const browser = new CRBrowser(parent, connection, options);
|
||||
browser._devtools = devtools;
|
||||
if (browser.isClank())
|
||||
browser._isCollocatedWithServer = false;
|
||||
const session = connection.rootSession;
|
||||
if (options.__testHookOnConnectToBrowser)
|
||||
await options.__testHookOnConnectToBrowser();
|
||||
const version = await session.send("Browser.getVersion");
|
||||
browser._version = version.product.substring(version.product.indexOf("/") + 1);
|
||||
try {
|
||||
browser._majorVersion = +browser._version.split(".")[0];
|
||||
} catch {
|
||||
}
|
||||
browser._userAgent = version.userAgent;
|
||||
browser.options.headful = !version.userAgent.includes("Headless");
|
||||
if (!options.persistent) {
|
||||
await session.send("Target.setAutoAttach", { autoAttach: true, waitForDebuggerOnStart: true, flatten: true });
|
||||
return browser;
|
||||
}
|
||||
browser._defaultContext = new CRBrowserContext(browser, void 0, options.persistent);
|
||||
await Promise.all([
|
||||
session.send("Target.setAutoAttach", { autoAttach: true, waitForDebuggerOnStart: true, flatten: true }).then(async () => {
|
||||
await session.send("Target.getTargetInfo");
|
||||
}),
|
||||
browser._defaultContext._initialize()
|
||||
]);
|
||||
await browser._waitForAllPagesToBeInitialized();
|
||||
return browser;
|
||||
}
|
||||
async doCreateNewContext(options) {
|
||||
const proxy = options.proxyOverride || options.proxy;
|
||||
let proxyBypassList = void 0;
|
||||
if (proxy) {
|
||||
if (process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK)
|
||||
proxyBypassList = proxy.bypass;
|
||||
else
|
||||
proxyBypassList = "<-loopback>" + (proxy.bypass ? `,${proxy.bypass}` : "");
|
||||
}
|
||||
const { browserContextId } = await this._session.send("Target.createBrowserContext", {
|
||||
disposeOnDetach: true,
|
||||
proxyServer: proxy ? proxy.server : void 0,
|
||||
proxyBypassList
|
||||
});
|
||||
const context = new CRBrowserContext(this, browserContextId, options);
|
||||
await context._initialize();
|
||||
this._contexts.set(browserContextId, context);
|
||||
return context;
|
||||
}
|
||||
contexts() {
|
||||
return Array.from(this._contexts.values());
|
||||
}
|
||||
version() {
|
||||
return this._version;
|
||||
}
|
||||
majorVersion() {
|
||||
return this._majorVersion;
|
||||
}
|
||||
userAgent() {
|
||||
return this._userAgent;
|
||||
}
|
||||
_platform() {
|
||||
if (this._userAgent.includes("Windows"))
|
||||
return "win";
|
||||
if (this._userAgent.includes("Macintosh"))
|
||||
return "mac";
|
||||
return "linux";
|
||||
}
|
||||
isClank() {
|
||||
return this.options.name === "clank";
|
||||
}
|
||||
async _waitForAllPagesToBeInitialized() {
|
||||
await Promise.all([...this._crPages.values()].map((crPage) => crPage._page.waitForInitializedOrError()));
|
||||
}
|
||||
_onAttachedToTarget({ targetInfo, sessionId, waitingForDebugger }) {
|
||||
if (targetInfo.type === "browser")
|
||||
return;
|
||||
const session = this._session.createChildSession(sessionId);
|
||||
(0, import_assert.assert)(targetInfo.browserContextId, "targetInfo: " + JSON.stringify(targetInfo, null, 2));
|
||||
let context = this._contexts.get(targetInfo.browserContextId) || null;
|
||||
if (!context) {
|
||||
context = this._defaultContext;
|
||||
}
|
||||
if (targetInfo.type === "other" && targetInfo.url.startsWith("devtools://devtools") && this._devtools) {
|
||||
this._devtools.install(session);
|
||||
return;
|
||||
}
|
||||
const treatOtherAsPage = targetInfo.type === "other" && process.env.PW_CHROMIUM_ATTACH_TO_OTHER;
|
||||
if (!context || targetInfo.type === "other" && !treatOtherAsPage) {
|
||||
session.detach().catch(() => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
(0, import_assert.assert)(!this._crPages.has(targetInfo.targetId), "Duplicate target " + targetInfo.targetId);
|
||||
(0, import_assert.assert)(!this._serviceWorkers.has(targetInfo.targetId), "Duplicate target " + targetInfo.targetId);
|
||||
if (targetInfo.type === "page" || treatOtherAsPage) {
|
||||
const opener = targetInfo.openerId ? this._crPages.get(targetInfo.openerId) || null : null;
|
||||
const crPage = new import_crPage.CRPage(session, targetInfo.targetId, context, opener, { hasUIWindow: targetInfo.type === "page" });
|
||||
this._crPages.set(targetInfo.targetId, crPage);
|
||||
return;
|
||||
}
|
||||
if (targetInfo.type === "service_worker") {
|
||||
const serviceWorker = new import_crServiceWorker.CRServiceWorker(context, session, targetInfo.url);
|
||||
this._serviceWorkers.set(targetInfo.targetId, serviceWorker);
|
||||
context.emit(CRBrowserContext.CREvents.ServiceWorker, serviceWorker);
|
||||
return;
|
||||
}
|
||||
session.detach().catch(() => {
|
||||
});
|
||||
}
|
||||
_onDetachedFromTarget(payload) {
|
||||
const targetId = payload.targetId;
|
||||
const crPage = this._crPages.get(targetId);
|
||||
if (crPage) {
|
||||
this._crPages.delete(targetId);
|
||||
crPage.didClose();
|
||||
return;
|
||||
}
|
||||
const serviceWorker = this._serviceWorkers.get(targetId);
|
||||
if (serviceWorker) {
|
||||
this._serviceWorkers.delete(targetId);
|
||||
serviceWorker.didClose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
_didDisconnect() {
|
||||
for (const crPage of this._crPages.values())
|
||||
crPage.didClose();
|
||||
this._crPages.clear();
|
||||
for (const serviceWorker of this._serviceWorkers.values())
|
||||
serviceWorker.didClose();
|
||||
this._serviceWorkers.clear();
|
||||
this._didClose();
|
||||
}
|
||||
_findOwningPage(frameId) {
|
||||
for (const crPage of this._crPages.values()) {
|
||||
const frame = crPage._page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
return crPage;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
_onDownloadWillBegin(payload) {
|
||||
const page = this._findOwningPage(payload.frameId);
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
page.willBeginDownload();
|
||||
let originPage = page._page.initializedOrUndefined();
|
||||
if (!originPage && page._opener)
|
||||
originPage = page._opener._page.initializedOrUndefined();
|
||||
if (!originPage)
|
||||
return;
|
||||
this._downloadCreated(originPage, payload.guid, payload.url, payload.suggestedFilename);
|
||||
}
|
||||
_onDownloadProgress(payload) {
|
||||
if (payload.state === "completed")
|
||||
this._downloadFinished(payload.guid, "");
|
||||
if (payload.state === "canceled")
|
||||
this._downloadFinished(payload.guid, this._closeReason || "canceled");
|
||||
}
|
||||
async _closePage(crPage) {
|
||||
await this._session.send("Target.closeTarget", { targetId: crPage._targetId });
|
||||
}
|
||||
async newBrowserCDPSession() {
|
||||
return await this._connection.createBrowserSession();
|
||||
}
|
||||
async startTracing(page, options = {}) {
|
||||
(0, import_assert.assert)(!this._tracingRecording, "Cannot start recording trace while already recording trace.");
|
||||
this._tracingClient = page ? page.delegate._mainFrameSession._client : this._session;
|
||||
const defaultCategories = [
|
||||
"-*",
|
||||
"devtools.timeline",
|
||||
"v8.execute",
|
||||
"disabled-by-default-devtools.timeline",
|
||||
"disabled-by-default-devtools.timeline.frame",
|
||||
"toplevel",
|
||||
"blink.console",
|
||||
"blink.user_timing",
|
||||
"latencyInfo",
|
||||
"disabled-by-default-devtools.timeline.stack",
|
||||
"disabled-by-default-v8.cpu_profiler",
|
||||
"disabled-by-default-v8.cpu_profiler.hires"
|
||||
];
|
||||
const {
|
||||
screenshots = false,
|
||||
categories = defaultCategories
|
||||
} = options;
|
||||
if (screenshots)
|
||||
categories.push("disabled-by-default-devtools.screenshot");
|
||||
this._tracingRecording = true;
|
||||
await this._tracingClient.send("Tracing.start", {
|
||||
transferMode: "ReturnAsStream",
|
||||
categories: categories.join(",")
|
||||
});
|
||||
}
|
||||
async stopTracing() {
|
||||
(0, import_assert.assert)(this._tracingClient, "Tracing was not started.");
|
||||
const [event] = await Promise.all([
|
||||
new Promise((f) => this._tracingClient.once("Tracing.tracingComplete", f)),
|
||||
this._tracingClient.send("Tracing.end")
|
||||
]);
|
||||
const tracingPath = import_path.default.join(this.options.artifactsDir, (0, import_crypto.createGuid)() + ".crtrace");
|
||||
await (0, import_crProtocolHelper.saveProtocolStream)(this._tracingClient, event.stream, tracingPath);
|
||||
this._tracingRecording = false;
|
||||
const artifact = new import_artifact.Artifact(this, tracingPath);
|
||||
artifact.reportFinished();
|
||||
return artifact;
|
||||
}
|
||||
isConnected() {
|
||||
return !this._connection._closed;
|
||||
}
|
||||
async _clientRootSession() {
|
||||
if (!this._clientRootSessionPromise)
|
||||
this._clientRootSessionPromise = this._connection.createBrowserSession();
|
||||
return this._clientRootSessionPromise;
|
||||
}
|
||||
}
|
||||
class CRBrowserContext extends import_browserContext.BrowserContext {
|
||||
static {
|
||||
this.CREvents = {
|
||||
ServiceWorker: "serviceworker"
|
||||
};
|
||||
}
|
||||
constructor(browser, browserContextId, options) {
|
||||
super(browser, options, browserContextId);
|
||||
this._authenticateProxyViaCredentials();
|
||||
}
|
||||
async _initialize() {
|
||||
(0, import_assert.assert)(!Array.from(this._browser._crPages.values()).some((page) => page._browserContext === this));
|
||||
const promises = [super._initialize()];
|
||||
if (this._browser.options.name !== "clank" && this._options.acceptDownloads !== "internal-browser-default") {
|
||||
promises.push(this._browser._session.send("Browser.setDownloadBehavior", {
|
||||
behavior: this._options.acceptDownloads === "accept" ? "allowAndName" : "deny",
|
||||
browserContextId: this._browserContextId,
|
||||
downloadPath: this._browser.options.downloadsPath,
|
||||
eventsEnabled: true
|
||||
}));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
}
|
||||
_crPages() {
|
||||
return [...this._browser._crPages.values()].filter((crPage) => crPage._browserContext === this);
|
||||
}
|
||||
possiblyUninitializedPages() {
|
||||
return this._crPages().map((crPage) => crPage._page);
|
||||
}
|
||||
async doCreateNewPage() {
|
||||
const { targetId } = await this._browser._session.send("Target.createTarget", { url: "about:blank", browserContextId: this._browserContextId });
|
||||
return this._browser._crPages.get(targetId)._page;
|
||||
}
|
||||
async doGetCookies(urls) {
|
||||
const { cookies } = await this._browser._session.send("Storage.getCookies", { browserContextId: this._browserContextId });
|
||||
return network.filterCookies(cookies.map((c) => {
|
||||
const { name, value, domain, path: path2, expires, httpOnly, secure, sameSite } = c;
|
||||
const copy = {
|
||||
name,
|
||||
value,
|
||||
domain,
|
||||
path: path2,
|
||||
expires,
|
||||
httpOnly,
|
||||
secure,
|
||||
sameSite: sameSite ?? "Lax"
|
||||
};
|
||||
if (c.partitionKey) {
|
||||
copy._crHasCrossSiteAncestor = c.partitionKey.hasCrossSiteAncestor;
|
||||
copy.partitionKey = c.partitionKey.topLevelSite;
|
||||
}
|
||||
return copy;
|
||||
}), urls);
|
||||
}
|
||||
async addCookies(cookies) {
|
||||
function toChromiumCookie(cookie) {
|
||||
const { name, value, url, domain, path: path2, expires, httpOnly, secure, sameSite, partitionKey, _crHasCrossSiteAncestor } = cookie;
|
||||
const copy = {
|
||||
name,
|
||||
value,
|
||||
url,
|
||||
domain,
|
||||
path: path2,
|
||||
expires,
|
||||
httpOnly,
|
||||
secure,
|
||||
sameSite
|
||||
};
|
||||
if (partitionKey) {
|
||||
copy.partitionKey = {
|
||||
topLevelSite: partitionKey,
|
||||
// _crHasCrossSiteAncestor is non-standard, set it true by default if the cookie is partitioned.
|
||||
hasCrossSiteAncestor: _crHasCrossSiteAncestor ?? true
|
||||
};
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
await this._browser._session.send("Storage.setCookies", {
|
||||
cookies: network.rewriteCookies(cookies).map(toChromiumCookie),
|
||||
browserContextId: this._browserContextId
|
||||
});
|
||||
}
|
||||
async doClearCookies() {
|
||||
await this._browser._session.send("Storage.clearCookies", { browserContextId: this._browserContextId });
|
||||
}
|
||||
async doGrantPermissions(origin, permissions) {
|
||||
const webPermissionToProtocol = /* @__PURE__ */ new Map([
|
||||
["geolocation", "geolocation"],
|
||||
["midi", "midi"],
|
||||
["notifications", "notifications"],
|
||||
["camera", "videoCapture"],
|
||||
["microphone", "audioCapture"],
|
||||
["background-sync", "backgroundSync"],
|
||||
["ambient-light-sensor", "sensors"],
|
||||
["accelerometer", "sensors"],
|
||||
["gyroscope", "sensors"],
|
||||
["magnetometer", "sensors"],
|
||||
["clipboard-read", "clipboardReadWrite"],
|
||||
["clipboard-write", "clipboardSanitizedWrite"],
|
||||
["payment-handler", "paymentHandler"],
|
||||
// chrome-specific permissions we have.
|
||||
["midi-sysex", "midiSysex"],
|
||||
["storage-access", "storageAccess"],
|
||||
["local-fonts", "localFonts"],
|
||||
["local-network-access", "localNetworkAccess"]
|
||||
]);
|
||||
const filtered = permissions.map((permission) => {
|
||||
const protocolPermission = webPermissionToProtocol.get(permission);
|
||||
if (!protocolPermission)
|
||||
throw new Error("Unknown permission: " + permission);
|
||||
return protocolPermission;
|
||||
});
|
||||
await this._browser._session.send("Browser.grantPermissions", { origin: origin === "*" ? void 0 : origin, browserContextId: this._browserContextId, permissions: filtered });
|
||||
}
|
||||
async doClearPermissions() {
|
||||
await this._browser._session.send("Browser.resetPermissions", { browserContextId: this._browserContextId });
|
||||
}
|
||||
async setGeolocation(geolocation) {
|
||||
(0, import_browserContext.verifyGeolocation)(geolocation);
|
||||
this._options.geolocation = geolocation;
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateGeolocation();
|
||||
}
|
||||
async doUpdateExtraHTTPHeaders() {
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateExtraHTTPHeaders();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await sw.updateExtraHTTPHeaders();
|
||||
}
|
||||
async setUserAgent(userAgent) {
|
||||
this._options.userAgent = userAgent;
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateUserAgent();
|
||||
}
|
||||
async doUpdateOffline() {
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateOffline();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await sw.updateOffline();
|
||||
}
|
||||
async doSetHTTPCredentials(httpCredentials) {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateHttpCredentials();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await sw.updateHttpCredentials();
|
||||
}
|
||||
async doAddInitScript(initScript) {
|
||||
for (const page of this.pages())
|
||||
await page.delegate.addInitScript(initScript);
|
||||
}
|
||||
async doRemoveInitScripts(initScripts) {
|
||||
for (const page of this.pages())
|
||||
await page.delegate.removeInitScripts(initScripts);
|
||||
}
|
||||
async doUpdateRequestInterception() {
|
||||
for (const page of this.pages())
|
||||
await page.delegate.updateRequestInterception();
|
||||
for (const sw of this.serviceWorkers())
|
||||
await sw.updateRequestInterception();
|
||||
}
|
||||
async doUpdateDefaultViewport() {
|
||||
}
|
||||
async doUpdateDefaultEmulatedMedia() {
|
||||
}
|
||||
async doExposePlaywrightBinding() {
|
||||
for (const page of this._crPages())
|
||||
await page.exposePlaywrightBinding();
|
||||
}
|
||||
async doClose(reason) {
|
||||
await this.dialogManager.closeBeforeUnloadDialogs();
|
||||
if (!this._browserContextId) {
|
||||
await this.stopVideoRecording();
|
||||
await this._browser.close({ reason });
|
||||
return;
|
||||
}
|
||||
await this._browser._session.send("Target.disposeBrowserContext", { browserContextId: this._browserContextId });
|
||||
this._browser._contexts.delete(this._browserContextId);
|
||||
for (const [targetId, serviceWorker] of this._browser._serviceWorkers) {
|
||||
if (serviceWorker.browserContext !== this)
|
||||
continue;
|
||||
serviceWorker.didClose();
|
||||
this._browser._serviceWorkers.delete(targetId);
|
||||
}
|
||||
}
|
||||
async stopVideoRecording() {
|
||||
await Promise.all(this._crPages().map((crPage) => crPage._mainFrameSession._stopVideoRecording()));
|
||||
}
|
||||
onClosePersistent() {
|
||||
}
|
||||
async clearCache() {
|
||||
for (const page of this._crPages())
|
||||
await page._networkManager.clearCache();
|
||||
}
|
||||
async cancelDownload(guid) {
|
||||
await this._browser._session.send("Browser.cancelDownload", {
|
||||
guid,
|
||||
browserContextId: this._browserContextId
|
||||
});
|
||||
}
|
||||
serviceWorkers() {
|
||||
return Array.from(this._browser._serviceWorkers.values()).filter((serviceWorker) => serviceWorker.browserContext === this);
|
||||
}
|
||||
async newCDPSession(page) {
|
||||
let targetId = null;
|
||||
if (page instanceof import_page.Page) {
|
||||
targetId = page.delegate._targetId;
|
||||
} else if (page instanceof import_frames.Frame) {
|
||||
const session = page._page.delegate._sessions.get(page._id);
|
||||
if (!session)
|
||||
throw new Error(`This frame does not have a separate CDP session, it is a part of the parent frame's session`);
|
||||
targetId = session._targetId;
|
||||
} else {
|
||||
throw new Error("page: expected Page or Frame");
|
||||
}
|
||||
const rootSession = await this._browser._clientRootSession();
|
||||
return rootSession.attachToTarget(targetId);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRBrowser,
|
||||
CRBrowserContext
|
||||
});
|
||||
202
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crConnection.js
generated
vendored
Normal file
202
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crConnection.js
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crConnection_exports = {};
|
||||
__export(crConnection_exports, {
|
||||
CDPSession: () => CDPSession,
|
||||
CRConnection: () => CRConnection,
|
||||
CRSession: () => CRSession,
|
||||
ConnectionEvents: () => ConnectionEvents,
|
||||
kBrowserCloseMessageId: () => kBrowserCloseMessageId
|
||||
});
|
||||
module.exports = __toCommonJS(crConnection_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_helper = require("../helper");
|
||||
var import_protocolError = require("../protocolError");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
const ConnectionEvents = {
|
||||
Disconnected: Symbol("ConnectionEvents.Disconnected")
|
||||
};
|
||||
const kBrowserCloseMessageId = -9999;
|
||||
class CRConnection extends import_instrumentation.SdkObject {
|
||||
constructor(parent, transport, protocolLogger, browserLogsCollector) {
|
||||
super(parent, "cr-connection");
|
||||
this._lastId = 0;
|
||||
this._sessions = /* @__PURE__ */ new Map();
|
||||
this._closed = false;
|
||||
this.setMaxListeners(0);
|
||||
this._transport = transport;
|
||||
this._protocolLogger = protocolLogger;
|
||||
this._browserLogsCollector = browserLogsCollector;
|
||||
this.rootSession = new CRSession(this, null, "");
|
||||
this._sessions.set("", this.rootSession);
|
||||
this._transport.onmessage = this._onMessage.bind(this);
|
||||
this._transport.onclose = this._onClose.bind(this);
|
||||
}
|
||||
_rawSend(sessionId, method, params) {
|
||||
const id = ++this._lastId;
|
||||
const message = { id, method, params };
|
||||
if (sessionId)
|
||||
message.sessionId = sessionId;
|
||||
this._protocolLogger("send", message);
|
||||
this._transport.send(message);
|
||||
return id;
|
||||
}
|
||||
async _onMessage(message) {
|
||||
this._protocolLogger("receive", message);
|
||||
if (message.id === kBrowserCloseMessageId)
|
||||
return;
|
||||
const session = this._sessions.get(message.sessionId || "");
|
||||
if (session)
|
||||
session._onMessage(message);
|
||||
}
|
||||
_onClose(reason) {
|
||||
this._closed = true;
|
||||
this._transport.onmessage = void 0;
|
||||
this._transport.onclose = void 0;
|
||||
this._browserDisconnectedLogs = import_helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs(), reason);
|
||||
this.rootSession.dispose();
|
||||
Promise.resolve().then(() => this.emit(ConnectionEvents.Disconnected));
|
||||
}
|
||||
close() {
|
||||
if (!this._closed)
|
||||
this._transport.close();
|
||||
}
|
||||
async createBrowserSession() {
|
||||
const { sessionId } = await this.rootSession.send("Target.attachToBrowserTarget");
|
||||
return new CDPSession(this.rootSession, sessionId);
|
||||
}
|
||||
}
|
||||
class CRSession extends import_instrumentation.SdkObject {
|
||||
constructor(connection, parentSession, sessionId, eventListener) {
|
||||
super(connection, "cr-session");
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._crashed = false;
|
||||
this._closed = false;
|
||||
this.setMaxListeners(0);
|
||||
this._connection = connection;
|
||||
this._parentSession = parentSession;
|
||||
this._sessionId = sessionId;
|
||||
this._eventListener = eventListener;
|
||||
this.on = super.on;
|
||||
this.addListener = super.addListener;
|
||||
this.off = super.removeListener;
|
||||
this.removeListener = super.removeListener;
|
||||
this.once = super.once;
|
||||
}
|
||||
_markAsCrashed() {
|
||||
this._crashed = true;
|
||||
}
|
||||
createChildSession(sessionId, eventListener) {
|
||||
const session = new CRSession(this._connection, this, sessionId, eventListener);
|
||||
this._connection._sessions.set(sessionId, session);
|
||||
return session;
|
||||
}
|
||||
async send(method, params) {
|
||||
if (this._crashed || this._closed || this._connection._closed || this._connection._browserDisconnectedLogs)
|
||||
throw new import_protocolError.ProtocolError(this._crashed ? "crashed" : "closed", void 0, this._connection._browserDisconnectedLogs);
|
||||
const id = this._connection._rawSend(this._sessionId, method, params);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject, error: new import_protocolError.ProtocolError("error", method) });
|
||||
});
|
||||
}
|
||||
_sendMayFail(method, params) {
|
||||
return this.send(method, params).catch((error) => import_debugLogger.debugLogger.log("error", error));
|
||||
}
|
||||
_onMessage(object) {
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error) {
|
||||
callback.error.setMessage(object.error.message);
|
||||
callback.reject(callback.error);
|
||||
} else {
|
||||
callback.resolve(object.result);
|
||||
}
|
||||
} else if (object.id && object.error?.code === -32001) {
|
||||
} else {
|
||||
(0, import_utils.assert)(!object.id, object?.error?.message || void 0);
|
||||
Promise.resolve().then(() => {
|
||||
if (this._eventListener)
|
||||
this._eventListener(object.method, object.params);
|
||||
this.emit(object.method, object.params);
|
||||
});
|
||||
}
|
||||
}
|
||||
async detach() {
|
||||
if (this._closed)
|
||||
throw new Error(`Session already detached. Most likely the page has been closed.`);
|
||||
if (!this._parentSession)
|
||||
throw new Error("Root session cannot be closed");
|
||||
await this._sendMayFail("Runtime.runIfWaitingForDebugger");
|
||||
await this._parentSession.send("Target.detachFromTarget", { sessionId: this._sessionId });
|
||||
this.dispose();
|
||||
}
|
||||
dispose() {
|
||||
this._closed = true;
|
||||
this._connection._sessions.delete(this._sessionId);
|
||||
for (const callback of this._callbacks.values()) {
|
||||
callback.error.setMessage(`Internal server error, session closed.`);
|
||||
callback.error.type = this._crashed ? "crashed" : "closed";
|
||||
callback.error.logs = this._connection._browserDisconnectedLogs;
|
||||
callback.reject(callback.error);
|
||||
}
|
||||
this._callbacks.clear();
|
||||
}
|
||||
}
|
||||
class CDPSession extends import_instrumentation.SdkObject {
|
||||
constructor(parentSession, sessionId) {
|
||||
super(parentSession, "cdp-session");
|
||||
this._listeners = [];
|
||||
this._session = parentSession.createChildSession(sessionId, (method, params) => this.emit(CDPSession.Events.Event, { method, params }));
|
||||
this._listeners = [import_utils.eventsHelper.addEventListener(parentSession, "Target.detachedFromTarget", (event) => {
|
||||
if (event.sessionId === sessionId)
|
||||
this._onClose();
|
||||
})];
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Event: "event",
|
||||
Closed: "close"
|
||||
};
|
||||
}
|
||||
async send(method, params) {
|
||||
return await this._session.send(method, params);
|
||||
}
|
||||
async detach() {
|
||||
return await this._session.detach();
|
||||
}
|
||||
async attachToTarget(targetId) {
|
||||
const { sessionId } = await this.send("Target.attachToTarget", { targetId, flatten: true });
|
||||
return new CDPSession(this._session, sessionId);
|
||||
}
|
||||
_onClose() {
|
||||
import_utils.eventsHelper.removeEventListeners(this._listeners);
|
||||
this._session.dispose();
|
||||
this.emit(CDPSession.Events.Closed);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CDPSession,
|
||||
CRConnection,
|
||||
CRSession,
|
||||
ConnectionEvents,
|
||||
kBrowserCloseMessageId
|
||||
});
|
||||
235
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crCoverage.js
generated
vendored
Normal file
235
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crCoverage.js
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crCoverage_exports = {};
|
||||
__export(crCoverage_exports, {
|
||||
CRCoverage: () => CRCoverage
|
||||
});
|
||||
module.exports = __toCommonJS(crCoverage_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_progress = require("../progress");
|
||||
class CRCoverage {
|
||||
constructor(client) {
|
||||
this._jsCoverage = new JSCoverage(client);
|
||||
this._cssCoverage = new CSSCoverage(client);
|
||||
}
|
||||
async startJSCoverage(progress, options) {
|
||||
await (0, import_progress.raceUncancellableOperationWithCleanup)(progress, () => this._jsCoverage.start(options), () => this._jsCoverage.stop());
|
||||
}
|
||||
async stopJSCoverage() {
|
||||
return await this._jsCoverage.stop();
|
||||
}
|
||||
async startCSSCoverage(progress, options) {
|
||||
await (0, import_progress.raceUncancellableOperationWithCleanup)(progress, () => this._cssCoverage.start(options), () => this._cssCoverage.stop());
|
||||
}
|
||||
async stopCSSCoverage() {
|
||||
return await this._cssCoverage.stop();
|
||||
}
|
||||
}
|
||||
class JSCoverage {
|
||||
constructor(client) {
|
||||
this._reportAnonymousScripts = false;
|
||||
this._client = client;
|
||||
this._enabled = false;
|
||||
this._scriptIds = /* @__PURE__ */ new Set();
|
||||
this._scriptSources = /* @__PURE__ */ new Map();
|
||||
this._eventListeners = [];
|
||||
this._resetOnNavigation = false;
|
||||
}
|
||||
async start(options) {
|
||||
(0, import_utils.assert)(!this._enabled, "JSCoverage is already enabled");
|
||||
const {
|
||||
resetOnNavigation = true,
|
||||
reportAnonymousScripts = false
|
||||
} = options;
|
||||
this._resetOnNavigation = resetOnNavigation;
|
||||
this._reportAnonymousScripts = reportAnonymousScripts;
|
||||
this._enabled = true;
|
||||
this._scriptIds.clear();
|
||||
this._scriptSources.clear();
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._client, "Debugger.scriptParsed", this._onScriptParsed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._client, "Debugger.paused", this._onDebuggerPaused.bind(this))
|
||||
];
|
||||
await Promise.all([
|
||||
this._client.send("Profiler.enable"),
|
||||
this._client.send("Profiler.startPreciseCoverage", { callCount: true, detailed: true }),
|
||||
this._client.send("Debugger.enable"),
|
||||
this._client.send("Debugger.setSkipAllPauses", { skip: true })
|
||||
]);
|
||||
}
|
||||
_onDebuggerPaused() {
|
||||
this._client.send("Debugger.resume");
|
||||
}
|
||||
_onExecutionContextsCleared() {
|
||||
if (!this._resetOnNavigation)
|
||||
return;
|
||||
this._scriptIds.clear();
|
||||
this._scriptSources.clear();
|
||||
}
|
||||
async _onScriptParsed(event) {
|
||||
this._scriptIds.add(event.scriptId);
|
||||
if (!event.url && !this._reportAnonymousScripts)
|
||||
return;
|
||||
const response = await this._client._sendMayFail("Debugger.getScriptSource", { scriptId: event.scriptId });
|
||||
if (response)
|
||||
this._scriptSources.set(event.scriptId, response.scriptSource);
|
||||
}
|
||||
async stop() {
|
||||
if (!this._enabled)
|
||||
return { entries: [] };
|
||||
const [profileResponse] = await Promise.all([
|
||||
this._client.send("Profiler.takePreciseCoverage"),
|
||||
this._client.send("Profiler.stopPreciseCoverage"),
|
||||
this._client.send("Profiler.disable"),
|
||||
this._client.send("Debugger.disable")
|
||||
]);
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
this._enabled = false;
|
||||
const coverage = { entries: [] };
|
||||
for (const entry of profileResponse.result) {
|
||||
if (!this._scriptIds.has(entry.scriptId))
|
||||
continue;
|
||||
if (!entry.url && !this._reportAnonymousScripts)
|
||||
continue;
|
||||
const source = this._scriptSources.get(entry.scriptId);
|
||||
if (source)
|
||||
coverage.entries.push({ ...entry, source });
|
||||
else
|
||||
coverage.entries.push(entry);
|
||||
}
|
||||
return coverage;
|
||||
}
|
||||
}
|
||||
class CSSCoverage {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
this._enabled = false;
|
||||
this._stylesheetURLs = /* @__PURE__ */ new Map();
|
||||
this._stylesheetSources = /* @__PURE__ */ new Map();
|
||||
this._eventListeners = [];
|
||||
this._resetOnNavigation = false;
|
||||
}
|
||||
async start(options) {
|
||||
(0, import_utils.assert)(!this._enabled, "CSSCoverage is already enabled");
|
||||
const { resetOnNavigation = true } = options;
|
||||
this._resetOnNavigation = resetOnNavigation;
|
||||
this._enabled = true;
|
||||
this._stylesheetURLs.clear();
|
||||
this._stylesheetSources.clear();
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._client, "CSS.styleSheetAdded", this._onStyleSheet.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._client, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this))
|
||||
];
|
||||
await Promise.all([
|
||||
this._client.send("DOM.enable"),
|
||||
this._client.send("CSS.enable"),
|
||||
this._client.send("CSS.startRuleUsageTracking")
|
||||
]);
|
||||
}
|
||||
_onExecutionContextsCleared() {
|
||||
if (!this._resetOnNavigation)
|
||||
return;
|
||||
this._stylesheetURLs.clear();
|
||||
this._stylesheetSources.clear();
|
||||
}
|
||||
async _onStyleSheet(event) {
|
||||
const header = event.header;
|
||||
if (!header.sourceURL)
|
||||
return;
|
||||
const response = await this._client._sendMayFail("CSS.getStyleSheetText", { styleSheetId: header.styleSheetId });
|
||||
if (response) {
|
||||
this._stylesheetURLs.set(header.styleSheetId, header.sourceURL);
|
||||
this._stylesheetSources.set(header.styleSheetId, response.text);
|
||||
}
|
||||
}
|
||||
async stop() {
|
||||
if (!this._enabled)
|
||||
return { entries: [] };
|
||||
const ruleTrackingResponse = await this._client.send("CSS.stopRuleUsageTracking");
|
||||
await Promise.all([
|
||||
this._client.send("CSS.disable"),
|
||||
this._client.send("DOM.disable")
|
||||
]);
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
this._enabled = false;
|
||||
const styleSheetIdToCoverage = /* @__PURE__ */ new Map();
|
||||
for (const entry of ruleTrackingResponse.ruleUsage) {
|
||||
let ranges = styleSheetIdToCoverage.get(entry.styleSheetId);
|
||||
if (!ranges) {
|
||||
ranges = [];
|
||||
styleSheetIdToCoverage.set(entry.styleSheetId, ranges);
|
||||
}
|
||||
ranges.push({
|
||||
startOffset: entry.startOffset,
|
||||
endOffset: entry.endOffset,
|
||||
count: entry.used ? 1 : 0
|
||||
});
|
||||
}
|
||||
const coverage = { entries: [] };
|
||||
for (const styleSheetId of this._stylesheetURLs.keys()) {
|
||||
const url = this._stylesheetURLs.get(styleSheetId);
|
||||
const text = this._stylesheetSources.get(styleSheetId);
|
||||
const ranges = convertToDisjointRanges(styleSheetIdToCoverage.get(styleSheetId) || []);
|
||||
coverage.entries.push({ url, ranges, text });
|
||||
}
|
||||
return coverage;
|
||||
}
|
||||
}
|
||||
function convertToDisjointRanges(nestedRanges) {
|
||||
const points = [];
|
||||
for (const range of nestedRanges) {
|
||||
points.push({ offset: range.startOffset, type: 0, range });
|
||||
points.push({ offset: range.endOffset, type: 1, range });
|
||||
}
|
||||
points.sort((a, b) => {
|
||||
if (a.offset !== b.offset)
|
||||
return a.offset - b.offset;
|
||||
if (a.type !== b.type)
|
||||
return b.type - a.type;
|
||||
const aLength = a.range.endOffset - a.range.startOffset;
|
||||
const bLength = b.range.endOffset - b.range.startOffset;
|
||||
if (a.type === 0)
|
||||
return bLength - aLength;
|
||||
return aLength - bLength;
|
||||
});
|
||||
const hitCountStack = [];
|
||||
const results = [];
|
||||
let lastOffset = 0;
|
||||
for (const point of points) {
|
||||
if (hitCountStack.length && lastOffset < point.offset && hitCountStack[hitCountStack.length - 1] > 0) {
|
||||
const lastResult = results.length ? results[results.length - 1] : null;
|
||||
if (lastResult && lastResult.end === lastOffset)
|
||||
lastResult.end = point.offset;
|
||||
else
|
||||
results.push({ start: lastOffset, end: point.offset });
|
||||
}
|
||||
lastOffset = point.offset;
|
||||
if (point.type === 0)
|
||||
hitCountStack.push(point.range.count);
|
||||
else
|
||||
hitCountStack.pop();
|
||||
}
|
||||
return results.filter((range) => range.end - range.start > 1);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRCoverage
|
||||
});
|
||||
113
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crDevTools.js
generated
vendored
Normal file
113
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crDevTools.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crDevTools_exports = {};
|
||||
__export(crDevTools_exports, {
|
||||
CRDevTools: () => CRDevTools
|
||||
});
|
||||
module.exports = __toCommonJS(crDevTools_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
const kBindingName = "__pw_devtools__";
|
||||
class CRDevTools {
|
||||
constructor(preferencesPath) {
|
||||
this._preferencesPath = preferencesPath;
|
||||
this._savePromise = Promise.resolve();
|
||||
}
|
||||
install(session) {
|
||||
session.on("Runtime.bindingCalled", async (event) => {
|
||||
if (event.name !== kBindingName)
|
||||
return;
|
||||
const parsed = JSON.parse(event.payload);
|
||||
let result = void 0;
|
||||
if (this.__testHookOnBinding)
|
||||
this.__testHookOnBinding(parsed);
|
||||
if (parsed.method === "getPreferences") {
|
||||
if (this._prefs === void 0) {
|
||||
try {
|
||||
const json = await import_fs.default.promises.readFile(this._preferencesPath, "utf8");
|
||||
this._prefs = JSON.parse(json);
|
||||
} catch (e) {
|
||||
this._prefs = {};
|
||||
}
|
||||
}
|
||||
result = this._prefs;
|
||||
} else if (parsed.method === "setPreference") {
|
||||
this._prefs[parsed.params[0]] = parsed.params[1];
|
||||
this._save();
|
||||
} else if (parsed.method === "removePreference") {
|
||||
delete this._prefs[parsed.params[0]];
|
||||
this._save();
|
||||
} else if (parsed.method === "clearPreferences") {
|
||||
this._prefs = {};
|
||||
this._save();
|
||||
}
|
||||
session.send("Runtime.evaluate", {
|
||||
expression: `window.DevToolsAPI.embedderMessageAck(${parsed.id}, ${JSON.stringify(result)})`,
|
||||
contextId: event.executionContextId
|
||||
}).catch((e) => null);
|
||||
});
|
||||
Promise.all([
|
||||
session.send("Runtime.enable"),
|
||||
session.send("Runtime.addBinding", { name: kBindingName }),
|
||||
session.send("Page.enable"),
|
||||
session.send("Page.addScriptToEvaluateOnNewDocument", { source: `
|
||||
(() => {
|
||||
const init = () => {
|
||||
// Lazy init happens when InspectorFrontendHost is initialized.
|
||||
// At this point DevToolsHost is ready to be used.
|
||||
const host = window.DevToolsHost;
|
||||
const old = host.sendMessageToEmbedder.bind(host);
|
||||
host.sendMessageToEmbedder = message => {
|
||||
if (['getPreferences', 'setPreference', 'removePreference', 'clearPreferences'].includes(JSON.parse(message).method))
|
||||
window.${kBindingName}(message);
|
||||
else
|
||||
old(message);
|
||||
};
|
||||
};
|
||||
let value;
|
||||
Object.defineProperty(window, 'InspectorFrontendHost', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() { return value; },
|
||||
set(v) { value = v; init(); },
|
||||
});
|
||||
})()
|
||||
` }),
|
||||
session.send("Runtime.runIfWaitingForDebugger")
|
||||
]).catch((e) => null);
|
||||
}
|
||||
_save() {
|
||||
this._savePromise = this._savePromise.then(async () => {
|
||||
await import_fs.default.promises.writeFile(this._preferencesPath, JSON.stringify(this._prefs)).catch((e) => null);
|
||||
});
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRDevTools
|
||||
});
|
||||
131
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crDragDrop.js
generated
vendored
Normal file
131
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crDragDrop.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crDragDrop_exports = {};
|
||||
__export(crDragDrop_exports, {
|
||||
DragManager: () => DragManager
|
||||
});
|
||||
module.exports = __toCommonJS(crDragDrop_exports);
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
var import_utils = require("../../utils");
|
||||
class DragManager {
|
||||
constructor(page) {
|
||||
this._dragState = null;
|
||||
this._lastPosition = { x: 0, y: 0 };
|
||||
this._crPage = page;
|
||||
}
|
||||
async cancelDrag() {
|
||||
if (!this._dragState)
|
||||
return false;
|
||||
await this._crPage._mainFrameSession._client.send("Input.dispatchDragEvent", {
|
||||
type: "dragCancel",
|
||||
x: this._lastPosition.x,
|
||||
y: this._lastPosition.y,
|
||||
data: {
|
||||
items: [],
|
||||
dragOperationsMask: 65535
|
||||
}
|
||||
});
|
||||
this._dragState = null;
|
||||
return true;
|
||||
}
|
||||
async interceptDragCausedByMove(progress, x, y, button, buttons, modifiers, moveCallback) {
|
||||
this._lastPosition = { x, y };
|
||||
if (this._dragState) {
|
||||
await progress.race(this._crPage._mainFrameSession._client.send("Input.dispatchDragEvent", {
|
||||
type: "dragOver",
|
||||
x,
|
||||
y,
|
||||
data: this._dragState,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers)
|
||||
}));
|
||||
return;
|
||||
}
|
||||
if (button !== "left")
|
||||
return moveCallback();
|
||||
const client = this._crPage._mainFrameSession._client;
|
||||
let onDragIntercepted;
|
||||
const dragInterceptedPromise = new Promise((x2) => onDragIntercepted = x2);
|
||||
function setupDragListeners() {
|
||||
let didStartDrag = Promise.resolve(false);
|
||||
let dragEvent = null;
|
||||
const dragListener = (event) => dragEvent = event;
|
||||
const mouseListener = () => {
|
||||
didStartDrag = new Promise((callback) => {
|
||||
window.addEventListener("dragstart", dragListener, { once: true, capture: true });
|
||||
setTimeout(() => callback(dragEvent ? !dragEvent.defaultPrevented : false), 0);
|
||||
});
|
||||
};
|
||||
window.addEventListener("mousemove", mouseListener, { once: true, capture: true });
|
||||
window.__cleanupDrag = async () => {
|
||||
const val = await didStartDrag;
|
||||
window.removeEventListener("mousemove", mouseListener, { capture: true });
|
||||
window.removeEventListener("dragstart", dragListener, { capture: true });
|
||||
delete window.__cleanupDrag;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
try {
|
||||
let expectingDrag = false;
|
||||
await progress.race(this._crPage._page.safeNonStallingEvaluateInAllFrames(`(${setupDragListeners.toString()})()`, "utility"));
|
||||
client.on("Input.dragIntercepted", onDragIntercepted);
|
||||
await client.send("Input.setInterceptDrags", { enabled: true });
|
||||
try {
|
||||
await progress.race(moveCallback());
|
||||
expectingDrag = (await Promise.all(this._crPage._page.frames().map(async (frame) => {
|
||||
return frame.nonStallingEvaluateInExistingContext("window.__cleanupDrag?.()", "utility").catch(() => false);
|
||||
}))).some((x2) => x2);
|
||||
} finally {
|
||||
client.off("Input.dragIntercepted", onDragIntercepted);
|
||||
await client.send("Input.setInterceptDrags", { enabled: false });
|
||||
}
|
||||
this._dragState = expectingDrag ? (await dragInterceptedPromise).data : null;
|
||||
} catch (error) {
|
||||
this._crPage._page.safeNonStallingEvaluateInAllFrames("window.__cleanupDrag?.()", "utility").catch(() => {
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
if (this._dragState) {
|
||||
await progress.race(this._crPage._mainFrameSession._client.send("Input.dispatchDragEvent", {
|
||||
type: "dragEnter",
|
||||
x,
|
||||
y,
|
||||
data: this._dragState,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers)
|
||||
}));
|
||||
}
|
||||
}
|
||||
isDragging() {
|
||||
return !!this._dragState;
|
||||
}
|
||||
async drop(progress, x, y, modifiers) {
|
||||
(0, import_utils.assert)(this._dragState, "missing drag state");
|
||||
await progress.race(this._crPage._mainFrameSession._client.send("Input.dispatchDragEvent", {
|
||||
type: "drop",
|
||||
x,
|
||||
y,
|
||||
data: this._dragState,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers)
|
||||
}));
|
||||
this._dragState = null;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DragManager
|
||||
});
|
||||
146
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crExecutionContext.js
generated
vendored
Normal file
146
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crExecutionContext.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crExecutionContext_exports = {};
|
||||
__export(crExecutionContext_exports, {
|
||||
CRExecutionContext: () => CRExecutionContext,
|
||||
createHandle: () => createHandle
|
||||
});
|
||||
module.exports = __toCommonJS(crExecutionContext_exports);
|
||||
var import_assert = require("../../utils/isomorphic/assert");
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
||||
var import_utilityScriptSerializers = require("../../utils/isomorphic/utilityScriptSerializers");
|
||||
var js = __toESM(require("../javascript"));
|
||||
var dom = __toESM(require("../dom"));
|
||||
var import_protocolError = require("../protocolError");
|
||||
class CRExecutionContext {
|
||||
constructor(client, contextPayload) {
|
||||
this._client = client;
|
||||
this._contextId = contextPayload.id;
|
||||
}
|
||||
async rawEvaluateJSON(expression) {
|
||||
const { exceptionDetails, result: remoteObject } = await this._client.send("Runtime.evaluate", {
|
||||
expression,
|
||||
contextId: this._contextId,
|
||||
returnByValue: true
|
||||
}).catch(rewriteError);
|
||||
if (exceptionDetails)
|
||||
throw new js.JavaScriptErrorInEvaluate((0, import_crProtocolHelper.getExceptionMessage)(exceptionDetails));
|
||||
return remoteObject.value;
|
||||
}
|
||||
async rawEvaluateHandle(context, expression) {
|
||||
const { exceptionDetails, result: remoteObject } = await this._client.send("Runtime.evaluate", {
|
||||
expression,
|
||||
contextId: this._contextId
|
||||
}).catch(rewriteError);
|
||||
if (exceptionDetails)
|
||||
throw new js.JavaScriptErrorInEvaluate((0, import_crProtocolHelper.getExceptionMessage)(exceptionDetails));
|
||||
return createHandle(context, remoteObject);
|
||||
}
|
||||
async evaluateWithArguments(expression, returnByValue, utilityScript, values, handles) {
|
||||
const { exceptionDetails, result: remoteObject } = await this._client.send("Runtime.callFunctionOn", {
|
||||
functionDeclaration: expression,
|
||||
objectId: utilityScript._objectId,
|
||||
arguments: [
|
||||
{ objectId: utilityScript._objectId },
|
||||
...values.map((value) => ({ value })),
|
||||
...handles.map((handle) => ({ objectId: handle._objectId }))
|
||||
],
|
||||
returnByValue,
|
||||
awaitPromise: true,
|
||||
userGesture: true
|
||||
}).catch(rewriteError);
|
||||
if (exceptionDetails)
|
||||
throw new js.JavaScriptErrorInEvaluate((0, import_crProtocolHelper.getExceptionMessage)(exceptionDetails));
|
||||
return returnByValue ? (0, import_utilityScriptSerializers.parseEvaluationResultValue)(remoteObject.value) : createHandle(utilityScript._context, remoteObject);
|
||||
}
|
||||
async getProperties(object) {
|
||||
const response = await this._client.send("Runtime.getProperties", {
|
||||
objectId: object._objectId,
|
||||
ownProperties: true
|
||||
});
|
||||
const result = /* @__PURE__ */ new Map();
|
||||
for (const property of response.result) {
|
||||
if (!property.enumerable || !property.value)
|
||||
continue;
|
||||
result.set(property.name, createHandle(object._context, property.value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async releaseHandle(handle) {
|
||||
if (!handle._objectId)
|
||||
return;
|
||||
await (0, import_crProtocolHelper.releaseObject)(this._client, handle._objectId);
|
||||
}
|
||||
}
|
||||
function rewriteError(error) {
|
||||
if (error.message.includes("Object reference chain is too long"))
|
||||
throw new Error("Cannot serialize result: object reference chain is too long.");
|
||||
if (error.message.includes("Object couldn't be returned by value"))
|
||||
return { result: { type: "undefined" } };
|
||||
if (error instanceof TypeError && error.message.startsWith("Converting circular structure to JSON"))
|
||||
(0, import_stackTrace.rewriteErrorMessage)(error, error.message + " Are you passing a nested JSHandle?");
|
||||
if (!js.isJavaScriptErrorInEvaluate(error) && !(0, import_protocolError.isSessionClosedError)(error))
|
||||
throw new Error("Execution context was destroyed, most likely because of a navigation.");
|
||||
throw error;
|
||||
}
|
||||
function potentiallyUnserializableValue(remoteObject) {
|
||||
const value = remoteObject.value;
|
||||
const unserializableValue = remoteObject.unserializableValue;
|
||||
return unserializableValue ? js.parseUnserializableValue(unserializableValue) : value;
|
||||
}
|
||||
function renderPreview(object) {
|
||||
if (object.type === "undefined")
|
||||
return "undefined";
|
||||
if ("value" in object)
|
||||
return String(object.value);
|
||||
if (object.unserializableValue)
|
||||
return String(object.unserializableValue);
|
||||
if (object.description === "Object" && object.preview) {
|
||||
const tokens = [];
|
||||
for (const { name, value } of object.preview.properties)
|
||||
tokens.push(`${name}: ${value}`);
|
||||
return `{${tokens.join(", ")}}`;
|
||||
}
|
||||
if (object.subtype === "array" && object.preview)
|
||||
return js.sparseArrayToString(object.preview.properties);
|
||||
return object.description;
|
||||
}
|
||||
function createHandle(context, remoteObject) {
|
||||
if (remoteObject.subtype === "node") {
|
||||
(0, import_assert.assert)(context instanceof dom.FrameExecutionContext);
|
||||
return new dom.ElementHandle(context, remoteObject.objectId);
|
||||
}
|
||||
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRExecutionContext,
|
||||
createHandle
|
||||
});
|
||||
187
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crInput.js
generated
vendored
Normal file
187
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crInput.js
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crInput_exports = {};
|
||||
__export(crInput_exports, {
|
||||
RawKeyboardImpl: () => RawKeyboardImpl,
|
||||
RawMouseImpl: () => RawMouseImpl,
|
||||
RawTouchscreenImpl: () => RawTouchscreenImpl
|
||||
});
|
||||
module.exports = __toCommonJS(crInput_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var input = __toESM(require("../input"));
|
||||
var import_macEditingCommands = require("../macEditingCommands");
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
class RawKeyboardImpl {
|
||||
constructor(_client, _isMac, _dragManger) {
|
||||
this._client = _client;
|
||||
this._isMac = _isMac;
|
||||
this._dragManger = _dragManger;
|
||||
}
|
||||
_commandsForCode(code, modifiers) {
|
||||
if (!this._isMac)
|
||||
return [];
|
||||
const parts = [];
|
||||
for (const modifier of ["Shift", "Control", "Alt", "Meta"]) {
|
||||
if (modifiers.has(modifier))
|
||||
parts.push(modifier);
|
||||
}
|
||||
parts.push(code);
|
||||
const shortcut = parts.join("+");
|
||||
let commands = import_macEditingCommands.macEditingCommands[shortcut] || [];
|
||||
if ((0, import_utils.isString)(commands))
|
||||
commands = [commands];
|
||||
commands = commands.filter((x) => !x.startsWith("insert"));
|
||||
return commands.map((c) => c.substring(0, c.length - 1));
|
||||
}
|
||||
async keydown(progress, modifiers, keyName, description, autoRepeat) {
|
||||
const { code, key, location, text } = description;
|
||||
if (code === "Escape" && await progress.race(this._dragManger.cancelDrag()))
|
||||
return;
|
||||
const commands = this._commandsForCode(code, modifiers);
|
||||
await progress.race(this._client.send("Input.dispatchKeyEvent", {
|
||||
type: text ? "keyDown" : "rawKeyDown",
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
commands,
|
||||
key,
|
||||
text,
|
||||
unmodifiedText: text,
|
||||
autoRepeat,
|
||||
location,
|
||||
isKeypad: location === input.keypadLocation
|
||||
}));
|
||||
}
|
||||
async keyup(progress, modifiers, keyName, description) {
|
||||
const { code, key, location } = description;
|
||||
await progress.race(this._client.send("Input.dispatchKeyEvent", {
|
||||
type: "keyUp",
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
key,
|
||||
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
location
|
||||
}));
|
||||
}
|
||||
async sendText(progress, text) {
|
||||
await progress.race(this._client.send("Input.insertText", { text }));
|
||||
}
|
||||
}
|
||||
class RawMouseImpl {
|
||||
constructor(page, client, dragManager) {
|
||||
this._page = page;
|
||||
this._client = client;
|
||||
this._dragManager = dragManager;
|
||||
}
|
||||
async move(progress, x, y, button, buttons, modifiers, forClick) {
|
||||
const actualMove = async () => {
|
||||
await progress.race(this._client.send("Input.dispatchMouseEvent", {
|
||||
type: "mouseMoved",
|
||||
button,
|
||||
buttons: (0, import_crProtocolHelper.toButtonsMask)(buttons),
|
||||
x,
|
||||
y,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
force: buttons.size > 0 ? 0.5 : 0
|
||||
}));
|
||||
};
|
||||
if (forClick) {
|
||||
await actualMove();
|
||||
return;
|
||||
}
|
||||
await this._dragManager.interceptDragCausedByMove(progress, x, y, button, buttons, modifiers, actualMove);
|
||||
}
|
||||
async down(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
if (this._dragManager.isDragging())
|
||||
return;
|
||||
await progress.race(this._client.send("Input.dispatchMouseEvent", {
|
||||
type: "mousePressed",
|
||||
button,
|
||||
buttons: (0, import_crProtocolHelper.toButtonsMask)(buttons),
|
||||
x,
|
||||
y,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
clickCount,
|
||||
force: buttons.size > 0 ? 0.5 : 0
|
||||
}));
|
||||
}
|
||||
async up(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
if (this._dragManager.isDragging()) {
|
||||
await this._dragManager.drop(progress, x, y, modifiers);
|
||||
return;
|
||||
}
|
||||
await progress.race(this._client.send("Input.dispatchMouseEvent", {
|
||||
type: "mouseReleased",
|
||||
button,
|
||||
buttons: (0, import_crProtocolHelper.toButtonsMask)(buttons),
|
||||
x,
|
||||
y,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
clickCount
|
||||
}));
|
||||
}
|
||||
async wheel(progress, x, y, buttons, modifiers, deltaX, deltaY) {
|
||||
await progress.race(this._client.send("Input.dispatchMouseEvent", {
|
||||
type: "mouseWheel",
|
||||
x,
|
||||
y,
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
deltaX,
|
||||
deltaY
|
||||
}));
|
||||
}
|
||||
}
|
||||
class RawTouchscreenImpl {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
}
|
||||
async tap(progress, x, y, modifiers) {
|
||||
await progress.race(Promise.all([
|
||||
this._client.send("Input.dispatchTouchEvent", {
|
||||
type: "touchStart",
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
touchPoints: [{
|
||||
x,
|
||||
y
|
||||
}]
|
||||
}),
|
||||
this._client.send("Input.dispatchTouchEvent", {
|
||||
type: "touchEnd",
|
||||
modifiers: (0, import_crProtocolHelper.toModifiersMask)(modifiers),
|
||||
touchPoints: []
|
||||
})
|
||||
]));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
RawKeyboardImpl,
|
||||
RawMouseImpl,
|
||||
RawTouchscreenImpl
|
||||
});
|
||||
666
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crNetworkManager.js
generated
vendored
Normal file
666
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crNetworkManager.js
generated
vendored
Normal file
@@ -0,0 +1,666 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crNetworkManager_exports = {};
|
||||
__export(crNetworkManager_exports, {
|
||||
CRNetworkManager: () => CRNetworkManager
|
||||
});
|
||||
module.exports = __toCommonJS(crNetworkManager_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_helper = require("../helper");
|
||||
var network = __toESM(require("../network"));
|
||||
var import_protocolError = require("../protocolError");
|
||||
class CRNetworkManager {
|
||||
constructor(page, serviceWorker) {
|
||||
this._requestIdToRequest = /* @__PURE__ */ new Map();
|
||||
this._requestIdToRequestWillBeSentEvent = /* @__PURE__ */ new Map();
|
||||
this._credentials = null;
|
||||
this._attemptedAuthentications = /* @__PURE__ */ new Set();
|
||||
this._userRequestInterceptionEnabled = false;
|
||||
this._protocolRequestInterceptionEnabled = false;
|
||||
this._offline = false;
|
||||
this._extraHTTPHeaders = [];
|
||||
this._requestIdToRequestPausedEvent = /* @__PURE__ */ new Map();
|
||||
this._responseExtraInfoTracker = new ResponseExtraInfoTracker();
|
||||
this._sessions = /* @__PURE__ */ new Map();
|
||||
this._page = page;
|
||||
this._serviceWorker = serviceWorker;
|
||||
}
|
||||
async addSession(session, workerFrame, isMain) {
|
||||
const sessionInfo = { session, isMain, workerFrame, eventListeners: [] };
|
||||
sessionInfo.eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Fetch.requestPaused", this._onRequestPaused.bind(this, sessionInfo)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Fetch.authRequired", this._onAuthRequired.bind(this, sessionInfo)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestWillBeSent", this._onRequestWillBeSent.bind(this, sessionInfo)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestWillBeSentExtraInfo", this._onRequestWillBeSentExtraInfo.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestServedFromCache", this._onRequestServedFromCache.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.responseReceived", this._onResponseReceived.bind(this, sessionInfo)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.responseReceivedExtraInfo", this._onResponseReceivedExtraInfo.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.loadingFinished", this._onLoadingFinished.bind(this, sessionInfo)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.loadingFailed", this._onLoadingFailed.bind(this, sessionInfo))
|
||||
];
|
||||
if (this._page) {
|
||||
sessionInfo.eventListeners.push(...[
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketCreated", (e) => this._page.frameManager.onWebSocketCreated(e.requestId, e.url)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketWillSendHandshakeRequest", (e) => this._page.frameManager.onWebSocketRequest(e.requestId)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketHandshakeResponseReceived", (e) => this._page.frameManager.onWebSocketResponse(e.requestId, e.response.status, e.response.statusText)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketFrameSent", (e) => e.response.payloadData && this._page.frameManager.onWebSocketFrameSent(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketFrameReceived", (e) => e.response.payloadData && this._page.frameManager.webSocketFrameReceived(e.requestId, e.response.opcode, e.response.payloadData)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketClosed", (e) => this._page.frameManager.webSocketClosed(e.requestId)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.webSocketFrameError", (e) => this._page.frameManager.webSocketError(e.requestId, e.errorMessage))
|
||||
]);
|
||||
}
|
||||
this._sessions.set(session, sessionInfo);
|
||||
await Promise.all([
|
||||
session.send("Network.enable"),
|
||||
this._updateProtocolRequestInterceptionForSession(
|
||||
sessionInfo,
|
||||
true
|
||||
/* initial */
|
||||
),
|
||||
this._setOfflineForSession(
|
||||
sessionInfo,
|
||||
true
|
||||
/* initial */
|
||||
),
|
||||
this._setExtraHTTPHeadersForSession(
|
||||
sessionInfo,
|
||||
true
|
||||
/* initial */
|
||||
)
|
||||
]);
|
||||
}
|
||||
removeSession(session) {
|
||||
const info = this._sessions.get(session);
|
||||
if (info)
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(info.eventListeners);
|
||||
this._sessions.delete(session);
|
||||
}
|
||||
async _forEachSession(cb) {
|
||||
await Promise.all([...this._sessions.values()].map((info) => {
|
||||
if (info.isMain)
|
||||
return cb(info);
|
||||
return cb(info).catch((e) => {
|
||||
if ((0, import_protocolError.isSessionClosedError)(e))
|
||||
return;
|
||||
throw e;
|
||||
});
|
||||
}));
|
||||
}
|
||||
async authenticate(credentials) {
|
||||
this._credentials = credentials;
|
||||
await this._updateProtocolRequestInterception();
|
||||
}
|
||||
async setOffline(offline) {
|
||||
if (offline === this._offline)
|
||||
return;
|
||||
this._offline = offline;
|
||||
await this._forEachSession((info) => this._setOfflineForSession(info));
|
||||
}
|
||||
async _setOfflineForSession(info, initial) {
|
||||
if (initial && !this._offline)
|
||||
return;
|
||||
if (info.workerFrame)
|
||||
return;
|
||||
await info.session.send("Network.emulateNetworkConditions", {
|
||||
offline: this._offline,
|
||||
// values of 0 remove any active throttling. crbug.com/456324#c9
|
||||
latency: 0,
|
||||
downloadThroughput: -1,
|
||||
uploadThroughput: -1
|
||||
});
|
||||
}
|
||||
async setRequestInterception(value) {
|
||||
this._userRequestInterceptionEnabled = value;
|
||||
await this._updateProtocolRequestInterception();
|
||||
}
|
||||
async _updateProtocolRequestInterception() {
|
||||
const enabled = this._userRequestInterceptionEnabled || !!this._credentials;
|
||||
if (enabled === this._protocolRequestInterceptionEnabled)
|
||||
return;
|
||||
this._protocolRequestInterceptionEnabled = enabled;
|
||||
await this._forEachSession((info) => this._updateProtocolRequestInterceptionForSession(info));
|
||||
}
|
||||
async _updateProtocolRequestInterceptionForSession(info, initial) {
|
||||
const enabled = this._protocolRequestInterceptionEnabled;
|
||||
if (initial && !enabled)
|
||||
return;
|
||||
const cachePromise = info.session.send("Network.setCacheDisabled", { cacheDisabled: enabled });
|
||||
let fetchPromise = Promise.resolve(void 0);
|
||||
if (!info.workerFrame) {
|
||||
if (enabled)
|
||||
fetchPromise = info.session.send("Fetch.enable", { handleAuthRequests: true, patterns: [{ urlPattern: "*", requestStage: "Request" }] });
|
||||
else
|
||||
fetchPromise = info.session.send("Fetch.disable");
|
||||
}
|
||||
await Promise.all([cachePromise, fetchPromise]);
|
||||
}
|
||||
async setExtraHTTPHeaders(extraHTTPHeaders) {
|
||||
if (!this._extraHTTPHeaders.length && !extraHTTPHeaders.length)
|
||||
return;
|
||||
this._extraHTTPHeaders = extraHTTPHeaders;
|
||||
await this._forEachSession((info) => this._setExtraHTTPHeadersForSession(info));
|
||||
}
|
||||
async _setExtraHTTPHeadersForSession(info, initial) {
|
||||
if (initial && !this._extraHTTPHeaders.length)
|
||||
return;
|
||||
await info.session.send("Network.setExtraHTTPHeaders", { headers: (0, import_utils.headersArrayToObject)(
|
||||
this._extraHTTPHeaders,
|
||||
false
|
||||
/* lowerCase */
|
||||
) });
|
||||
}
|
||||
async clearCache() {
|
||||
await this._forEachSession(async (info) => {
|
||||
await info.session.send("Network.setCacheDisabled", { cacheDisabled: true });
|
||||
if (!this._protocolRequestInterceptionEnabled)
|
||||
await info.session.send("Network.setCacheDisabled", { cacheDisabled: false });
|
||||
if (!info.workerFrame)
|
||||
await info.session.send("Network.clearBrowserCache");
|
||||
});
|
||||
}
|
||||
_onRequestWillBeSent(sessionInfo, event) {
|
||||
if (this._protocolRequestInterceptionEnabled && !event.request.url.startsWith("data:")) {
|
||||
const requestId = event.requestId;
|
||||
const requestPausedEvent = this._requestIdToRequestPausedEvent.get(requestId);
|
||||
if (requestPausedEvent) {
|
||||
this._onRequest(sessionInfo, event, requestPausedEvent.sessionInfo, requestPausedEvent.event);
|
||||
this._requestIdToRequestPausedEvent.delete(requestId);
|
||||
} else {
|
||||
this._requestIdToRequestWillBeSentEvent.set(event.requestId, { sessionInfo, event });
|
||||
}
|
||||
} else {
|
||||
this._onRequest(sessionInfo, event, void 0, void 0);
|
||||
}
|
||||
}
|
||||
_onRequestServedFromCache(event) {
|
||||
this._responseExtraInfoTracker.requestServedFromCache(event);
|
||||
}
|
||||
_onRequestWillBeSentExtraInfo(event) {
|
||||
this._responseExtraInfoTracker.requestWillBeSentExtraInfo(event);
|
||||
}
|
||||
_onAuthRequired(sessionInfo, event) {
|
||||
let response = "Default";
|
||||
const shouldProvideCredentials = this._shouldProvideCredentials(event.request.url);
|
||||
if (this._attemptedAuthentications.has(event.requestId)) {
|
||||
response = "CancelAuth";
|
||||
} else if (shouldProvideCredentials) {
|
||||
response = "ProvideCredentials";
|
||||
this._attemptedAuthentications.add(event.requestId);
|
||||
}
|
||||
const { username, password } = shouldProvideCredentials && this._credentials ? this._credentials : { username: void 0, password: void 0 };
|
||||
sessionInfo.session._sendMayFail("Fetch.continueWithAuth", {
|
||||
requestId: event.requestId,
|
||||
authChallengeResponse: { response, username, password }
|
||||
});
|
||||
}
|
||||
_shouldProvideCredentials(url) {
|
||||
if (!this._credentials)
|
||||
return false;
|
||||
return !this._credentials.origin || new URL(url).origin.toLowerCase() === this._credentials.origin.toLowerCase();
|
||||
}
|
||||
_onRequestPaused(sessionInfo, event) {
|
||||
if (!event.networkId) {
|
||||
sessionInfo.session._sendMayFail("Fetch.continueRequest", { requestId: event.requestId });
|
||||
return;
|
||||
}
|
||||
if (event.request.url.startsWith("data:"))
|
||||
return;
|
||||
const requestId = event.networkId;
|
||||
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(requestId);
|
||||
if (requestWillBeSentEvent) {
|
||||
this._onRequest(requestWillBeSentEvent.sessionInfo, requestWillBeSentEvent.event, sessionInfo, event);
|
||||
this._requestIdToRequestWillBeSentEvent.delete(requestId);
|
||||
} else {
|
||||
const existingRequest = this._requestIdToRequest.get(requestId);
|
||||
const alreadyContinuedParams = existingRequest?._route?._alreadyContinuedParams;
|
||||
if (alreadyContinuedParams && !event.redirectedRequestId) {
|
||||
sessionInfo.session._sendMayFail("Fetch.continueRequest", {
|
||||
...alreadyContinuedParams,
|
||||
requestId: event.requestId
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._requestIdToRequestPausedEvent.set(requestId, { sessionInfo, event });
|
||||
}
|
||||
}
|
||||
_onRequest(requestWillBeSentSessionInfo, requestWillBeSentEvent, requestPausedSessionInfo, requestPausedEvent) {
|
||||
if (requestWillBeSentEvent.request.url.startsWith("data:"))
|
||||
return;
|
||||
let redirectedFrom = null;
|
||||
if (requestWillBeSentEvent.redirectResponse) {
|
||||
const request2 = this._requestIdToRequest.get(requestWillBeSentEvent.requestId);
|
||||
if (request2) {
|
||||
this._handleRequestRedirect(request2, requestWillBeSentEvent.redirectResponse, requestWillBeSentEvent.timestamp, requestWillBeSentEvent.redirectHasExtraInfo);
|
||||
redirectedFrom = request2;
|
||||
}
|
||||
}
|
||||
let frame = requestWillBeSentEvent.frameId ? this._page?.frameManager.frame(requestWillBeSentEvent.frameId) : requestWillBeSentSessionInfo.workerFrame;
|
||||
if (!frame && this._page && requestPausedEvent && requestPausedEvent.frameId)
|
||||
frame = this._page.frameManager.frame(requestPausedEvent.frameId);
|
||||
if (!frame && this._page && requestWillBeSentEvent.frameId === (this._page?.delegate)._targetId) {
|
||||
frame = this._page.frameManager.frameAttached(requestWillBeSentEvent.frameId, null);
|
||||
}
|
||||
const isInterceptedOptionsPreflight = !!requestPausedEvent && requestPausedEvent.request.method === "OPTIONS" && requestWillBeSentEvent.initiator.type === "preflight";
|
||||
if (isInterceptedOptionsPreflight && (this._page || this._serviceWorker).needsRequestInterception()) {
|
||||
const requestHeaders = requestPausedEvent.request.headers;
|
||||
const responseHeaders = [
|
||||
{ name: "Access-Control-Allow-Origin", value: requestHeaders["Origin"] || "*" },
|
||||
{ name: "Access-Control-Allow-Methods", value: requestHeaders["Access-Control-Request-Method"] || "GET, POST, OPTIONS, DELETE" },
|
||||
{ name: "Access-Control-Allow-Credentials", value: "true" }
|
||||
];
|
||||
if (requestHeaders["Access-Control-Request-Headers"])
|
||||
responseHeaders.push({ name: "Access-Control-Allow-Headers", value: requestHeaders["Access-Control-Request-Headers"] });
|
||||
requestPausedSessionInfo.session._sendMayFail("Fetch.fulfillRequest", {
|
||||
requestId: requestPausedEvent.requestId,
|
||||
responseCode: 204,
|
||||
responsePhrase: network.statusText(204),
|
||||
responseHeaders,
|
||||
body: ""
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!frame && !this._serviceWorker) {
|
||||
if (requestPausedEvent)
|
||||
requestPausedSessionInfo.session._sendMayFail("Fetch.continueRequest", { requestId: requestPausedEvent.requestId });
|
||||
return;
|
||||
}
|
||||
let route = null;
|
||||
let headersOverride;
|
||||
if (requestPausedEvent) {
|
||||
if (redirectedFrom || !this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled) {
|
||||
headersOverride = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers;
|
||||
requestPausedSessionInfo.session._sendMayFail("Fetch.continueRequest", { requestId: requestPausedEvent.requestId, headers: headersOverride });
|
||||
} else {
|
||||
route = new RouteImpl(requestPausedSessionInfo.session, requestPausedEvent.requestId);
|
||||
}
|
||||
}
|
||||
const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === "Document";
|
||||
const documentId = isNavigationRequest ? requestWillBeSentEvent.loaderId : void 0;
|
||||
const request = new InterceptableRequest({
|
||||
session: requestWillBeSentSessionInfo.session,
|
||||
context: (this._page || this._serviceWorker).browserContext,
|
||||
frame: frame || null,
|
||||
serviceWorker: this._serviceWorker || null,
|
||||
documentId,
|
||||
route,
|
||||
requestWillBeSentEvent,
|
||||
requestPausedEvent,
|
||||
redirectedFrom,
|
||||
headersOverride: headersOverride || null
|
||||
});
|
||||
this._requestIdToRequest.set(requestWillBeSentEvent.requestId, request);
|
||||
if (route) {
|
||||
request.request.setRawRequestHeaders((0, import_utils.headersObjectToArray)(requestPausedEvent.request.headers, "\n"));
|
||||
}
|
||||
(this._page?.frameManager || this._serviceWorker).requestStarted(request.request, route || void 0);
|
||||
}
|
||||
_createResponse(request, responsePayload, hasExtraInfo) {
|
||||
const getResponseBody = async () => {
|
||||
const contentLengthHeader = Object.entries(responsePayload.headers).find((header) => header[0].toLowerCase() === "content-length");
|
||||
const expectedLength = contentLengthHeader ? +contentLengthHeader[1] : void 0;
|
||||
const session = request.session;
|
||||
const response2 = await session.send("Network.getResponseBody", { requestId: request._requestId });
|
||||
if (response2.body || !expectedLength)
|
||||
return Buffer.from(response2.body, response2.base64Encoded ? "base64" : "utf8");
|
||||
if (request._route?._fulfilled)
|
||||
return Buffer.from("");
|
||||
const resource = await session.send("Network.loadNetworkResource", { url: request.request.url(), frameId: this._serviceWorker ? void 0 : request.request.frame()._id, options: { disableCache: false, includeCredentials: true } });
|
||||
const chunks = [];
|
||||
while (resource.resource.stream) {
|
||||
const chunk = await session.send("IO.read", { handle: resource.resource.stream });
|
||||
chunks.push(Buffer.from(chunk.data, chunk.base64Encoded ? "base64" : "utf-8"));
|
||||
if (chunk.eof) {
|
||||
await session.send("IO.close", { handle: resource.resource.stream });
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Buffer.concat(chunks);
|
||||
};
|
||||
const timingPayload = responsePayload.timing;
|
||||
let timing;
|
||||
if (timingPayload && !this._responseExtraInfoTracker.servedFromCache(request._requestId)) {
|
||||
timing = {
|
||||
startTime: (timingPayload.requestTime - request._timestamp + request._wallTime) * 1e3,
|
||||
domainLookupStart: timingPayload.dnsStart,
|
||||
domainLookupEnd: timingPayload.dnsEnd,
|
||||
connectStart: timingPayload.connectStart,
|
||||
secureConnectionStart: timingPayload.sslStart,
|
||||
connectEnd: timingPayload.connectEnd,
|
||||
requestStart: timingPayload.sendStart,
|
||||
responseStart: timingPayload.receiveHeadersEnd
|
||||
};
|
||||
} else {
|
||||
timing = {
|
||||
startTime: request._wallTime * 1e3,
|
||||
domainLookupStart: -1,
|
||||
domainLookupEnd: -1,
|
||||
connectStart: -1,
|
||||
secureConnectionStart: -1,
|
||||
connectEnd: -1,
|
||||
requestStart: -1,
|
||||
responseStart: -1
|
||||
};
|
||||
}
|
||||
const response = new network.Response(request.request, responsePayload.status, responsePayload.statusText, (0, import_utils.headersObjectToArray)(responsePayload.headers), timing, getResponseBody, !!responsePayload.fromServiceWorker, responsePayload.protocol);
|
||||
if (responsePayload?.remoteIPAddress && typeof responsePayload?.remotePort === "number") {
|
||||
response._serverAddrFinished({
|
||||
ipAddress: responsePayload.remoteIPAddress,
|
||||
port: responsePayload.remotePort
|
||||
});
|
||||
} else {
|
||||
response._serverAddrFinished();
|
||||
}
|
||||
response._securityDetailsFinished({
|
||||
protocol: responsePayload?.securityDetails?.protocol,
|
||||
subjectName: responsePayload?.securityDetails?.subjectName,
|
||||
issuer: responsePayload?.securityDetails?.issuer,
|
||||
validFrom: responsePayload?.securityDetails?.validFrom,
|
||||
validTo: responsePayload?.securityDetails?.validTo
|
||||
});
|
||||
this._responseExtraInfoTracker.processResponse(request._requestId, response, hasExtraInfo);
|
||||
return response;
|
||||
}
|
||||
_deleteRequest(request) {
|
||||
this._requestIdToRequest.delete(request._requestId);
|
||||
if (request._interceptionId)
|
||||
this._attemptedAuthentications.delete(request._interceptionId);
|
||||
}
|
||||
_handleRequestRedirect(request, responsePayload, timestamp, hasExtraInfo) {
|
||||
const response = this._createResponse(request, responsePayload, hasExtraInfo);
|
||||
response.setTransferSize(null);
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished((timestamp - request._timestamp) * 1e3);
|
||||
this._deleteRequest(request);
|
||||
(this._page?.frameManager || this._serviceWorker).requestReceivedResponse(response);
|
||||
(this._page?.frameManager || this._serviceWorker).reportRequestFinished(request.request, response);
|
||||
}
|
||||
_onResponseReceivedExtraInfo(event) {
|
||||
this._responseExtraInfoTracker.responseReceivedExtraInfo(event);
|
||||
}
|
||||
_onResponseReceived(sessionInfo, event) {
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
if (!request && event.response.fromServiceWorker) {
|
||||
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(event.requestId);
|
||||
if (requestWillBeSentEvent) {
|
||||
this._requestIdToRequestWillBeSentEvent.delete(event.requestId);
|
||||
this._onRequest(sessionInfo, requestWillBeSentEvent.event, void 0, void 0);
|
||||
request = this._requestIdToRequest.get(event.requestId);
|
||||
}
|
||||
}
|
||||
if (!request)
|
||||
return;
|
||||
const response = this._createResponse(request, event.response, event.hasExtraInfo);
|
||||
(this._page?.frameManager || this._serviceWorker).requestReceivedResponse(response);
|
||||
}
|
||||
_onLoadingFinished(sessionInfo, event) {
|
||||
this._responseExtraInfoTracker.loadingFinished(event);
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
this._maybeUpdateRequestSession(sessionInfo, request);
|
||||
const response = request.request._existingResponse();
|
||||
if (response) {
|
||||
response.setTransferSize(event.encodedDataLength);
|
||||
response.responseHeadersSize().then((size) => response.setEncodedBodySize(event.encodedDataLength - size));
|
||||
response._requestFinished(import_helper.helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
||||
}
|
||||
this._deleteRequest(request);
|
||||
(this._page?.frameManager || this._serviceWorker).reportRequestFinished(request.request, response);
|
||||
}
|
||||
_onLoadingFailed(sessionInfo, event) {
|
||||
this._responseExtraInfoTracker.loadingFailed(event);
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
if (!request) {
|
||||
const requestWillBeSentEvent = this._requestIdToRequestWillBeSentEvent.get(event.requestId);
|
||||
if (requestWillBeSentEvent) {
|
||||
this._requestIdToRequestWillBeSentEvent.delete(event.requestId);
|
||||
this._onRequest(sessionInfo, requestWillBeSentEvent.event, void 0, void 0);
|
||||
request = this._requestIdToRequest.get(event.requestId);
|
||||
}
|
||||
}
|
||||
if (!request)
|
||||
return;
|
||||
this._maybeUpdateRequestSession(sessionInfo, request);
|
||||
const response = request.request._existingResponse();
|
||||
if (response) {
|
||||
response.setTransferSize(null);
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished(import_helper.helper.secondsToRoundishMillis(event.timestamp - request._timestamp));
|
||||
} else {
|
||||
request.request.setRawRequestHeaders(null);
|
||||
}
|
||||
this._deleteRequest(request);
|
||||
request.request._setFailureText(event.errorText || event.blockedReason || "");
|
||||
(this._page?.frameManager || this._serviceWorker).requestFailed(request.request, !!event.canceled);
|
||||
}
|
||||
_maybeUpdateRequestSession(sessionInfo, request) {
|
||||
if (request.session !== sessionInfo.session && !sessionInfo.isMain && (request._documentId === request._requestId || sessionInfo.workerFrame))
|
||||
request.session = sessionInfo.session;
|
||||
}
|
||||
}
|
||||
class InterceptableRequest {
|
||||
constructor(options) {
|
||||
const { session, context, frame, documentId, route, requestWillBeSentEvent, requestPausedEvent, redirectedFrom, serviceWorker, headersOverride } = options;
|
||||
this.session = session;
|
||||
this._timestamp = requestWillBeSentEvent.timestamp;
|
||||
this._wallTime = requestWillBeSentEvent.wallTime;
|
||||
this._requestId = requestWillBeSentEvent.requestId;
|
||||
this._interceptionId = requestPausedEvent && requestPausedEvent.requestId;
|
||||
this._documentId = documentId;
|
||||
this._route = route;
|
||||
this._originalRequestRoute = route ?? redirectedFrom?._originalRequestRoute;
|
||||
const {
|
||||
headers,
|
||||
method,
|
||||
url,
|
||||
postDataEntries = null
|
||||
} = requestPausedEvent ? requestPausedEvent.request : requestWillBeSentEvent.request;
|
||||
const type = (requestWillBeSentEvent.type || "").toLowerCase();
|
||||
let postDataBuffer = null;
|
||||
const entries = postDataEntries?.filter((entry) => entry.bytes);
|
||||
if (entries && entries.length)
|
||||
postDataBuffer = Buffer.concat(entries.map((entry) => Buffer.from(entry.bytes, "base64")));
|
||||
this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersOverride || (0, import_utils.headersObjectToArray)(headers));
|
||||
}
|
||||
}
|
||||
class RouteImpl {
|
||||
constructor(session, interceptionId) {
|
||||
this._fulfilled = false;
|
||||
this._session = session;
|
||||
this._interceptionId = interceptionId;
|
||||
}
|
||||
async continue(overrides) {
|
||||
this._alreadyContinuedParams = {
|
||||
requestId: this._interceptionId,
|
||||
url: overrides.url,
|
||||
headers: overrides.headers,
|
||||
method: overrides.method,
|
||||
postData: overrides.postData ? overrides.postData.toString("base64") : void 0
|
||||
};
|
||||
await catchDisallowedErrors(async () => {
|
||||
await this._session.send("Fetch.continueRequest", this._alreadyContinuedParams);
|
||||
});
|
||||
}
|
||||
async fulfill(response) {
|
||||
this._fulfilled = true;
|
||||
const body = response.isBase64 ? response.body : Buffer.from(response.body).toString("base64");
|
||||
const responseHeaders = splitSetCookieHeader(response.headers);
|
||||
await catchDisallowedErrors(async () => {
|
||||
await this._session.send("Fetch.fulfillRequest", {
|
||||
requestId: this._interceptionId,
|
||||
responseCode: response.status,
|
||||
responsePhrase: network.statusText(response.status),
|
||||
responseHeaders,
|
||||
body
|
||||
});
|
||||
});
|
||||
}
|
||||
async abort(errorCode = "failed") {
|
||||
const errorReason = errorReasons[errorCode];
|
||||
(0, import_utils.assert)(errorReason, "Unknown error code: " + errorCode);
|
||||
await catchDisallowedErrors(async () => {
|
||||
await this._session.send("Fetch.failRequest", {
|
||||
requestId: this._interceptionId,
|
||||
errorReason
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
async function catchDisallowedErrors(callback) {
|
||||
try {
|
||||
return await callback();
|
||||
} catch (e) {
|
||||
if ((0, import_protocolError.isProtocolError)(e) && e.message.includes("Invalid http status code or phrase"))
|
||||
throw e;
|
||||
if ((0, import_protocolError.isProtocolError)(e) && e.message.includes("Unsafe header"))
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
function splitSetCookieHeader(headers) {
|
||||
const index = headers.findIndex(({ name }) => name.toLowerCase() === "set-cookie");
|
||||
if (index === -1)
|
||||
return headers;
|
||||
const header = headers[index];
|
||||
const values = header.value.split("\n");
|
||||
if (values.length === 1)
|
||||
return headers;
|
||||
const result = headers.slice();
|
||||
result.splice(index, 1, ...values.map((value) => ({ name: header.name, value })));
|
||||
return result;
|
||||
}
|
||||
const errorReasons = {
|
||||
"aborted": "Aborted",
|
||||
"accessdenied": "AccessDenied",
|
||||
"addressunreachable": "AddressUnreachable",
|
||||
"blockedbyclient": "BlockedByClient",
|
||||
"blockedbyresponse": "BlockedByResponse",
|
||||
"connectionaborted": "ConnectionAborted",
|
||||
"connectionclosed": "ConnectionClosed",
|
||||
"connectionfailed": "ConnectionFailed",
|
||||
"connectionrefused": "ConnectionRefused",
|
||||
"connectionreset": "ConnectionReset",
|
||||
"internetdisconnected": "InternetDisconnected",
|
||||
"namenotresolved": "NameNotResolved",
|
||||
"timedout": "TimedOut",
|
||||
"failed": "Failed"
|
||||
};
|
||||
class ResponseExtraInfoTracker {
|
||||
constructor() {
|
||||
this._requests = /* @__PURE__ */ new Map();
|
||||
}
|
||||
requestWillBeSentExtraInfo(event) {
|
||||
const info = this._getOrCreateEntry(event.requestId);
|
||||
info.requestWillBeSentExtraInfo.push(event);
|
||||
this._patchHeaders(info, info.requestWillBeSentExtraInfo.length - 1);
|
||||
this._checkFinished(info);
|
||||
}
|
||||
requestServedFromCache(event) {
|
||||
const info = this._getOrCreateEntry(event.requestId);
|
||||
info.servedFromCache = true;
|
||||
}
|
||||
servedFromCache(requestId) {
|
||||
const info = this._requests.get(requestId);
|
||||
return !!info?.servedFromCache;
|
||||
}
|
||||
responseReceivedExtraInfo(event) {
|
||||
const info = this._getOrCreateEntry(event.requestId);
|
||||
info.responseReceivedExtraInfo.push(event);
|
||||
this._patchHeaders(info, info.responseReceivedExtraInfo.length - 1);
|
||||
this._checkFinished(info);
|
||||
}
|
||||
processResponse(requestId, response, hasExtraInfo) {
|
||||
let info = this._requests.get(requestId);
|
||||
if (!hasExtraInfo || info?.servedFromCache) {
|
||||
response.request().setRawRequestHeaders(null);
|
||||
response.setResponseHeadersSize(null);
|
||||
response.setRawResponseHeaders(null);
|
||||
return;
|
||||
}
|
||||
info = this._getOrCreateEntry(requestId);
|
||||
info.responses.push(response);
|
||||
this._patchHeaders(info, info.responses.length - 1);
|
||||
}
|
||||
loadingFinished(event) {
|
||||
const info = this._requests.get(event.requestId);
|
||||
if (!info)
|
||||
return;
|
||||
info.loadingFinished = event;
|
||||
this._checkFinished(info);
|
||||
}
|
||||
loadingFailed(event) {
|
||||
const info = this._requests.get(event.requestId);
|
||||
if (!info)
|
||||
return;
|
||||
info.loadingFailed = event;
|
||||
this._checkFinished(info);
|
||||
}
|
||||
_getOrCreateEntry(requestId) {
|
||||
let info = this._requests.get(requestId);
|
||||
if (!info) {
|
||||
info = {
|
||||
requestId,
|
||||
requestWillBeSentExtraInfo: [],
|
||||
responseReceivedExtraInfo: [],
|
||||
responses: []
|
||||
};
|
||||
this._requests.set(requestId, info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
_patchHeaders(info, index) {
|
||||
const response = info.responses[index];
|
||||
const requestExtraInfo = info.requestWillBeSentExtraInfo[index];
|
||||
if (response && requestExtraInfo) {
|
||||
response.request().setRawRequestHeaders((0, import_utils.headersObjectToArray)(requestExtraInfo.headers, "\n"));
|
||||
info.requestWillBeSentExtraInfo[index] = void 0;
|
||||
}
|
||||
const responseExtraInfo = info.responseReceivedExtraInfo[index];
|
||||
if (response && responseExtraInfo) {
|
||||
response.setResponseHeadersSize(responseExtraInfo.headersText?.length || 0);
|
||||
response.setRawResponseHeaders((0, import_utils.headersObjectToArray)(responseExtraInfo.headers, "\n"));
|
||||
info.responseReceivedExtraInfo[index] = void 0;
|
||||
}
|
||||
}
|
||||
_checkFinished(info) {
|
||||
if (!info.loadingFinished && !info.loadingFailed)
|
||||
return;
|
||||
if (info.responses.length <= info.responseReceivedExtraInfo.length) {
|
||||
this._stopTracking(info.requestId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_stopTracking(requestId) {
|
||||
this._requests.delete(requestId);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRNetworkManager
|
||||
});
|
||||
1069
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crPage.js
generated
vendored
Normal file
1069
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crPage.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
121
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crPdf.js
generated
vendored
Normal file
121
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crPdf.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crPdf_exports = {};
|
||||
__export(crPdf_exports, {
|
||||
CRPDF: () => CRPDF
|
||||
});
|
||||
module.exports = __toCommonJS(crPdf_exports);
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
var import_utils = require("../../utils");
|
||||
const PagePaperFormats = {
|
||||
letter: { width: 8.5, height: 11 },
|
||||
legal: { width: 8.5, height: 14 },
|
||||
tabloid: { width: 11, height: 17 },
|
||||
ledger: { width: 17, height: 11 },
|
||||
a0: { width: 33.1, height: 46.8 },
|
||||
a1: { width: 23.4, height: 33.1 },
|
||||
a2: { width: 16.54, height: 23.4 },
|
||||
a3: { width: 11.7, height: 16.54 },
|
||||
a4: { width: 8.27, height: 11.7 },
|
||||
a5: { width: 5.83, height: 8.27 },
|
||||
a6: { width: 4.13, height: 5.83 }
|
||||
};
|
||||
const unitToPixels = {
|
||||
"px": 1,
|
||||
"in": 96,
|
||||
"cm": 37.8,
|
||||
"mm": 3.78
|
||||
};
|
||||
function convertPrintParameterToInches(text) {
|
||||
if (text === void 0)
|
||||
return void 0;
|
||||
let unit = text.substring(text.length - 2).toLowerCase();
|
||||
let valueText = "";
|
||||
if (unitToPixels.hasOwnProperty(unit)) {
|
||||
valueText = text.substring(0, text.length - 2);
|
||||
} else {
|
||||
unit = "px";
|
||||
valueText = text;
|
||||
}
|
||||
const value = Number(valueText);
|
||||
(0, import_utils.assert)(!isNaN(value), "Failed to parse parameter value: " + text);
|
||||
const pixels = value * unitToPixels[unit];
|
||||
return pixels / 96;
|
||||
}
|
||||
class CRPDF {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
}
|
||||
async generate(options) {
|
||||
const {
|
||||
scale = 1,
|
||||
displayHeaderFooter = false,
|
||||
headerTemplate = "",
|
||||
footerTemplate = "",
|
||||
printBackground = false,
|
||||
landscape = false,
|
||||
pageRanges = "",
|
||||
preferCSSPageSize = false,
|
||||
margin = {},
|
||||
tagged = false,
|
||||
outline = false
|
||||
} = options;
|
||||
let paperWidth = 8.5;
|
||||
let paperHeight = 11;
|
||||
if (options.format) {
|
||||
const format = PagePaperFormats[options.format.toLowerCase()];
|
||||
(0, import_utils.assert)(format, "Unknown paper format: " + options.format);
|
||||
paperWidth = format.width;
|
||||
paperHeight = format.height;
|
||||
} else {
|
||||
paperWidth = convertPrintParameterToInches(options.width) || paperWidth;
|
||||
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
|
||||
}
|
||||
const marginTop = convertPrintParameterToInches(margin.top) || 0;
|
||||
const marginLeft = convertPrintParameterToInches(margin.left) || 0;
|
||||
const marginBottom = convertPrintParameterToInches(margin.bottom) || 0;
|
||||
const marginRight = convertPrintParameterToInches(margin.right) || 0;
|
||||
const generateDocumentOutline = outline;
|
||||
const generateTaggedPDF = tagged;
|
||||
const result = await this._client.send("Page.printToPDF", {
|
||||
transferMode: "ReturnAsStream",
|
||||
landscape,
|
||||
displayHeaderFooter,
|
||||
headerTemplate,
|
||||
footerTemplate,
|
||||
printBackground,
|
||||
scale,
|
||||
paperWidth,
|
||||
paperHeight,
|
||||
marginTop,
|
||||
marginBottom,
|
||||
marginLeft,
|
||||
marginRight,
|
||||
pageRanges,
|
||||
preferCSSPageSize,
|
||||
generateTaggedPDF,
|
||||
generateDocumentOutline
|
||||
});
|
||||
return await (0, import_crProtocolHelper.readProtocolStream)(this._client, result.stream);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRPDF
|
||||
});
|
||||
145
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crProtocolHelper.js
generated
vendored
Normal file
145
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crProtocolHelper.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crProtocolHelper_exports = {};
|
||||
__export(crProtocolHelper_exports, {
|
||||
exceptionToError: () => exceptionToError,
|
||||
getExceptionMessage: () => getExceptionMessage,
|
||||
readProtocolStream: () => readProtocolStream,
|
||||
releaseObject: () => releaseObject,
|
||||
saveProtocolStream: () => saveProtocolStream,
|
||||
toButtonsMask: () => toButtonsMask,
|
||||
toConsoleMessageLocation: () => toConsoleMessageLocation,
|
||||
toModifiersMask: () => toModifiersMask
|
||||
});
|
||||
module.exports = __toCommonJS(crProtocolHelper_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
||||
var import_fileUtils = require("../utils/fileUtils");
|
||||
function getExceptionMessage(exceptionDetails) {
|
||||
if (exceptionDetails.exception)
|
||||
return exceptionDetails.exception.description || String(exceptionDetails.exception.value);
|
||||
let message = exceptionDetails.text;
|
||||
if (exceptionDetails.stackTrace) {
|
||||
for (const callframe of exceptionDetails.stackTrace.callFrames) {
|
||||
const location = callframe.url + ":" + callframe.lineNumber + ":" + callframe.columnNumber;
|
||||
const functionName = callframe.functionName || "<anonymous>";
|
||||
message += `
|
||||
at ${functionName} (${location})`;
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
async function releaseObject(client, objectId) {
|
||||
await client.send("Runtime.releaseObject", { objectId }).catch((error) => {
|
||||
});
|
||||
}
|
||||
async function saveProtocolStream(client, handle, path) {
|
||||
let eof = false;
|
||||
await (0, import_fileUtils.mkdirIfNeeded)(path);
|
||||
const fd = await import_fs.default.promises.open(path, "w");
|
||||
while (!eof) {
|
||||
const response = await client.send("IO.read", { handle });
|
||||
eof = response.eof;
|
||||
const buf = Buffer.from(response.data, response.base64Encoded ? "base64" : void 0);
|
||||
await fd.write(buf);
|
||||
}
|
||||
await fd.close();
|
||||
await client.send("IO.close", { handle });
|
||||
}
|
||||
async function readProtocolStream(client, handle) {
|
||||
let eof = false;
|
||||
const chunks = [];
|
||||
while (!eof) {
|
||||
const response = await client.send("IO.read", { handle });
|
||||
eof = response.eof;
|
||||
const buf = Buffer.from(response.data, response.base64Encoded ? "base64" : void 0);
|
||||
chunks.push(buf);
|
||||
}
|
||||
await client.send("IO.close", { handle });
|
||||
return Buffer.concat(chunks);
|
||||
}
|
||||
function toConsoleMessageLocation(stackTrace) {
|
||||
return stackTrace && stackTrace.callFrames.length ? {
|
||||
url: stackTrace.callFrames[0].url,
|
||||
lineNumber: stackTrace.callFrames[0].lineNumber,
|
||||
columnNumber: stackTrace.callFrames[0].columnNumber
|
||||
} : { url: "", lineNumber: 0, columnNumber: 0 };
|
||||
}
|
||||
function exceptionToError(exceptionDetails) {
|
||||
const messageWithStack = getExceptionMessage(exceptionDetails);
|
||||
const lines = messageWithStack.split("\n");
|
||||
const firstStackTraceLine = lines.findIndex((line) => line.startsWith(" at"));
|
||||
let messageWithName = "";
|
||||
let stack = "";
|
||||
if (firstStackTraceLine === -1) {
|
||||
messageWithName = messageWithStack;
|
||||
} else {
|
||||
messageWithName = lines.slice(0, firstStackTraceLine).join("\n");
|
||||
stack = messageWithStack;
|
||||
}
|
||||
const { name, message } = (0, import_stackTrace.splitErrorMessage)(messageWithName);
|
||||
const err = new Error(message);
|
||||
err.stack = stack;
|
||||
const nameOverride = exceptionDetails.exception?.preview?.properties.find((o) => o.name === "name");
|
||||
err.name = nameOverride ? nameOverride.value ?? "Error" : name;
|
||||
return err;
|
||||
}
|
||||
function toModifiersMask(modifiers) {
|
||||
let mask = 0;
|
||||
if (modifiers.has("Alt"))
|
||||
mask |= 1;
|
||||
if (modifiers.has("Control"))
|
||||
mask |= 2;
|
||||
if (modifiers.has("Meta"))
|
||||
mask |= 4;
|
||||
if (modifiers.has("Shift"))
|
||||
mask |= 8;
|
||||
return mask;
|
||||
}
|
||||
function toButtonsMask(buttons) {
|
||||
let mask = 0;
|
||||
if (buttons.has("left"))
|
||||
mask |= 1;
|
||||
if (buttons.has("right"))
|
||||
mask |= 2;
|
||||
if (buttons.has("middle"))
|
||||
mask |= 4;
|
||||
return mask;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
exceptionToError,
|
||||
getExceptionMessage,
|
||||
readProtocolStream,
|
||||
releaseObject,
|
||||
saveProtocolStream,
|
||||
toButtonsMask,
|
||||
toConsoleMessageLocation,
|
||||
toModifiersMask
|
||||
});
|
||||
136
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crServiceWorker.js
generated
vendored
Normal file
136
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/crServiceWorker.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var crServiceWorker_exports = {};
|
||||
__export(crServiceWorker_exports, {
|
||||
CRServiceWorker: () => CRServiceWorker
|
||||
});
|
||||
module.exports = __toCommonJS(crServiceWorker_exports);
|
||||
var import_page = require("../page");
|
||||
var import_crExecutionContext = require("./crExecutionContext");
|
||||
var import_crNetworkManager = require("./crNetworkManager");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var network = __toESM(require("../network"));
|
||||
var import_console = require("../console");
|
||||
var import_crProtocolHelper = require("./crProtocolHelper");
|
||||
class CRServiceWorker extends import_page.Worker {
|
||||
constructor(browserContext, session, url) {
|
||||
super(browserContext, url);
|
||||
this._session = session;
|
||||
this.browserContext = browserContext;
|
||||
if (!process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_NETWORK)
|
||||
this._networkManager = new import_crNetworkManager.CRNetworkManager(null, this);
|
||||
session.once("Runtime.executionContextCreated", (event) => {
|
||||
this.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, event.context));
|
||||
});
|
||||
if (this.browserContext._browser.majorVersion() >= 143)
|
||||
session.on("Inspector.workerScriptLoaded", () => this.workerScriptLoaded());
|
||||
else
|
||||
this.workerScriptLoaded();
|
||||
if (this._networkManager && this._isNetworkInspectionEnabled()) {
|
||||
this.updateRequestInterception();
|
||||
this.updateExtraHTTPHeaders();
|
||||
this.updateHttpCredentials();
|
||||
this.updateOffline();
|
||||
this._networkManager.addSession(
|
||||
session,
|
||||
void 0,
|
||||
true
|
||||
/* isMain */
|
||||
).catch(() => {
|
||||
});
|
||||
}
|
||||
session.on("Runtime.consoleAPICalled", (event) => {
|
||||
if (!this.existingExecutionContext || process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_CONSOLE)
|
||||
return;
|
||||
const args = event.args.map((o) => (0, import_crExecutionContext.createHandle)(this.existingExecutionContext, o));
|
||||
const message = new import_console.ConsoleMessage(null, this, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
||||
this.browserContext.emit(import_browserContext.BrowserContext.Events.Console, message);
|
||||
});
|
||||
session.send("Runtime.enable", {}).catch((e) => {
|
||||
});
|
||||
session.send("Runtime.runIfWaitingForDebugger").catch((e) => {
|
||||
});
|
||||
session.on("Inspector.targetReloadedAfterCrash", () => {
|
||||
session._sendMayFail("Runtime.runIfWaitingForDebugger", {});
|
||||
});
|
||||
}
|
||||
didClose() {
|
||||
this._networkManager?.removeSession(this._session);
|
||||
this._session.dispose();
|
||||
super.didClose();
|
||||
}
|
||||
async updateOffline() {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.setOffline(!!this.browserContext._options.offline).catch(() => {
|
||||
});
|
||||
}
|
||||
async updateHttpCredentials() {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.authenticate(this.browserContext._options.httpCredentials || null).catch(() => {
|
||||
});
|
||||
}
|
||||
async updateExtraHTTPHeaders() {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.setExtraHTTPHeaders(this.browserContext._options.extraHTTPHeaders || []).catch(() => {
|
||||
});
|
||||
}
|
||||
async updateRequestInterception() {
|
||||
if (!this._isNetworkInspectionEnabled())
|
||||
return;
|
||||
await this._networkManager?.setRequestInterception(this.needsRequestInterception()).catch(() => {
|
||||
});
|
||||
}
|
||||
needsRequestInterception() {
|
||||
return this._isNetworkInspectionEnabled() && this.browserContext.requestInterceptors.length > 0;
|
||||
}
|
||||
reportRequestFinished(request, response) {
|
||||
this.browserContext.emit(import_browserContext.BrowserContext.Events.RequestFinished, { request, response });
|
||||
}
|
||||
requestFailed(request, _canceled) {
|
||||
this.browserContext.emit(import_browserContext.BrowserContext.Events.RequestFailed, request);
|
||||
}
|
||||
requestReceivedResponse(response) {
|
||||
this.browserContext.emit(import_browserContext.BrowserContext.Events.Response, response);
|
||||
}
|
||||
requestStarted(request, route) {
|
||||
this.browserContext.emit(import_browserContext.BrowserContext.Events.Request, request);
|
||||
if (route)
|
||||
new network.Route(request, route).handle(this.browserContext.requestInterceptors);
|
||||
}
|
||||
_isNetworkInspectionEnabled() {
|
||||
return this.browserContext._options.serviceWorkers !== "block";
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CRServiceWorker
|
||||
});
|
||||
162
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/defaultFontFamilies.js
generated
vendored
Normal file
162
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/defaultFontFamilies.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var defaultFontFamilies_exports = {};
|
||||
__export(defaultFontFamilies_exports, {
|
||||
platformToFontFamilies: () => platformToFontFamilies
|
||||
});
|
||||
module.exports = __toCommonJS(defaultFontFamilies_exports);
|
||||
const platformToFontFamilies = {
|
||||
"linux": {
|
||||
"fontFamilies": {
|
||||
"standard": "Times New Roman",
|
||||
"fixed": "Monospace",
|
||||
"serif": "Times New Roman",
|
||||
"sansSerif": "Arial",
|
||||
"cursive": "Comic Sans MS",
|
||||
"fantasy": "Impact"
|
||||
}
|
||||
},
|
||||
"mac": {
|
||||
"fontFamilies": {
|
||||
"standard": "Times",
|
||||
"fixed": "Courier",
|
||||
"serif": "Times",
|
||||
"sansSerif": "Helvetica",
|
||||
"cursive": "Apple Chancery",
|
||||
"fantasy": "Papyrus"
|
||||
},
|
||||
"forScripts": [
|
||||
{
|
||||
"script": "jpan",
|
||||
"fontFamilies": {
|
||||
"standard": "Hiragino Kaku Gothic ProN",
|
||||
"fixed": "Osaka-Mono",
|
||||
"serif": "Hiragino Mincho ProN",
|
||||
"sansSerif": "Hiragino Kaku Gothic ProN"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hang",
|
||||
"fontFamilies": {
|
||||
"standard": "Apple SD Gothic Neo",
|
||||
"serif": "AppleMyungjo",
|
||||
"sansSerif": "Apple SD Gothic Neo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hans",
|
||||
"fontFamilies": {
|
||||
"standard": ",PingFang SC,STHeiti",
|
||||
"serif": "Songti SC",
|
||||
"sansSerif": ",PingFang SC,STHeiti",
|
||||
"cursive": "Kaiti SC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hant",
|
||||
"fontFamilies": {
|
||||
"standard": ",PingFang TC,Heiti TC",
|
||||
"serif": "Songti TC",
|
||||
"sansSerif": ",PingFang TC,Heiti TC",
|
||||
"cursive": "Kaiti TC"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"win": {
|
||||
"fontFamilies": {
|
||||
"standard": "Times New Roman",
|
||||
"fixed": "Consolas",
|
||||
"serif": "Times New Roman",
|
||||
"sansSerif": "Arial",
|
||||
"cursive": "Comic Sans MS",
|
||||
"fantasy": "Impact"
|
||||
},
|
||||
"forScripts": [
|
||||
{
|
||||
"script": "cyrl",
|
||||
"fontFamilies": {
|
||||
"standard": "Times New Roman",
|
||||
"fixed": "Courier New",
|
||||
"serif": "Times New Roman",
|
||||
"sansSerif": "Arial"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "arab",
|
||||
"fontFamilies": {
|
||||
"fixed": "Courier New",
|
||||
"sansSerif": "Segoe UI"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "grek",
|
||||
"fontFamilies": {
|
||||
"standard": "Times New Roman",
|
||||
"fixed": "Courier New",
|
||||
"serif": "Times New Roman",
|
||||
"sansSerif": "Arial"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "jpan",
|
||||
"fontFamilies": {
|
||||
"standard": ",Meiryo,Yu Gothic",
|
||||
"fixed": "MS Gothic",
|
||||
"serif": ",Yu Mincho,MS PMincho",
|
||||
"sansSerif": ",Meiryo,Yu Gothic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hang",
|
||||
"fontFamilies": {
|
||||
"standard": "Malgun Gothic",
|
||||
"fixed": "Gulimche",
|
||||
"serif": "Batang",
|
||||
"sansSerif": "Malgun Gothic",
|
||||
"cursive": "Gungsuh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hans",
|
||||
"fontFamilies": {
|
||||
"standard": "Microsoft YaHei",
|
||||
"fixed": "NSimsun",
|
||||
"serif": "Simsun",
|
||||
"sansSerif": "Microsoft YaHei",
|
||||
"cursive": "KaiTi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": "hant",
|
||||
"fontFamilies": {
|
||||
"standard": "Microsoft JhengHei",
|
||||
"fixed": "MingLiU",
|
||||
"serif": "PMingLiU",
|
||||
"sansSerif": "Microsoft JhengHei",
|
||||
"cursive": "DFKai-SB"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
platformToFontFamilies
|
||||
});
|
||||
16
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/protocol.d.js
generated
vendored
Normal file
16
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/protocol.d.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var protocol_d_exports = {};
|
||||
module.exports = __toCommonJS(protocol_d_exports);
|
||||
115
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/videoRecorder.js
generated
vendored
Normal file
115
.playwright-mcp/node_modules/playwright-core/lib/server/chromium/videoRecorder.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var videoRecorder_exports = {};
|
||||
__export(videoRecorder_exports, {
|
||||
VideoRecorder: () => VideoRecorder
|
||||
});
|
||||
module.exports = __toCommonJS(videoRecorder_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_page = require("../page");
|
||||
var import_processLauncher = require("../utils/processLauncher");
|
||||
const fps = 25;
|
||||
class VideoRecorder {
|
||||
constructor(page, ffmpegPath) {
|
||||
this._process = null;
|
||||
this._gracefullyClose = null;
|
||||
this._lastWritePromise = Promise.resolve();
|
||||
this._firstFrameTimestamp = 0;
|
||||
this._lastFrame = null;
|
||||
this._lastWriteNodeTime = 0;
|
||||
this._frameQueue = [];
|
||||
this._isStopped = false;
|
||||
this._ffmpegPath = ffmpegPath;
|
||||
page.on(import_page.Page.Events.ScreencastFrame, (frame) => this.writeFrame(frame.buffer, frame.frameSwapWallTime / 1e3));
|
||||
}
|
||||
static async launch(page, ffmpegPath, options) {
|
||||
if (!options.outputFile.endsWith(".webm"))
|
||||
throw new Error("File must have .webm extension");
|
||||
const recorder = new VideoRecorder(page, ffmpegPath);
|
||||
await recorder._launch(options);
|
||||
return recorder;
|
||||
}
|
||||
async _launch(options) {
|
||||
const w = options.width;
|
||||
const h = options.height;
|
||||
const args = `-loglevel error -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i pipe:0 -y -an -r ${fps} -c:v vp8 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 -vf pad=${w}:${h}:0:0:gray,crop=${w}:${h}:0:0`.split(" ");
|
||||
args.push(options.outputFile);
|
||||
const { launchedProcess, gracefullyClose } = await (0, import_processLauncher.launchProcess)({
|
||||
command: this._ffmpegPath,
|
||||
args,
|
||||
stdio: "stdin",
|
||||
log: (message) => import_utils.debugLogger.log("browser", message),
|
||||
tempDirectories: [],
|
||||
attemptToGracefullyClose: async () => {
|
||||
import_utils.debugLogger.log("browser", "Closing stdin...");
|
||||
launchedProcess.stdin.end();
|
||||
},
|
||||
onExit: (exitCode, signal) => {
|
||||
import_utils.debugLogger.log("browser", `ffmpeg onkill exitCode=${exitCode} signal=${signal}`);
|
||||
}
|
||||
});
|
||||
launchedProcess.stdin.on("finish", () => {
|
||||
import_utils.debugLogger.log("browser", "ffmpeg finished input.");
|
||||
});
|
||||
launchedProcess.stdin.on("error", () => {
|
||||
import_utils.debugLogger.log("browser", "ffmpeg error.");
|
||||
});
|
||||
this._process = launchedProcess;
|
||||
this._gracefullyClose = gracefullyClose;
|
||||
}
|
||||
writeFrame(frame, timestamp) {
|
||||
(0, import_utils.assert)(this._process);
|
||||
if (this._isStopped)
|
||||
return;
|
||||
if (!this._firstFrameTimestamp)
|
||||
this._firstFrameTimestamp = timestamp;
|
||||
const frameNumber = Math.floor((timestamp - this._firstFrameTimestamp) * fps);
|
||||
if (this._lastFrame) {
|
||||
const repeatCount = frameNumber - this._lastFrame.frameNumber;
|
||||
for (let i = 0; i < repeatCount; ++i)
|
||||
this._frameQueue.push(this._lastFrame.buffer);
|
||||
this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames());
|
||||
}
|
||||
this._lastFrame = { buffer: frame, timestamp, frameNumber };
|
||||
this._lastWriteNodeTime = (0, import_utils.monotonicTime)();
|
||||
}
|
||||
async _sendFrames() {
|
||||
while (this._frameQueue.length)
|
||||
await this._sendFrame(this._frameQueue.shift());
|
||||
}
|
||||
async _sendFrame(frame) {
|
||||
return new Promise((f) => this._process.stdin.write(frame, f)).then((error) => {
|
||||
if (error)
|
||||
import_utils.debugLogger.log("browser", `ffmpeg failed to write: ${String(error)}`);
|
||||
});
|
||||
}
|
||||
async stop() {
|
||||
if (this._isStopped || !this._lastFrame)
|
||||
return;
|
||||
const addTime = Math.max(((0, import_utils.monotonicTime)() - this._lastWriteNodeTime) / 1e3, 1);
|
||||
this.writeFrame(Buffer.from([]), this._lastFrame.timestamp + addTime);
|
||||
this._isStopped = true;
|
||||
await this._lastWritePromise;
|
||||
await this._gracefullyClose();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
VideoRecorder
|
||||
});
|
||||
149
.playwright-mcp/node_modules/playwright-core/lib/server/clock.js
generated
vendored
Normal file
149
.playwright-mcp/node_modules/playwright-core/lib/server/clock.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var clock_exports = {};
|
||||
__export(clock_exports, {
|
||||
Clock: () => Clock
|
||||
});
|
||||
module.exports = __toCommonJS(clock_exports);
|
||||
var rawClockSource = __toESM(require("../generated/clockSource"));
|
||||
class Clock {
|
||||
constructor(browserContext) {
|
||||
this._initScripts = [];
|
||||
this._browserContext = browserContext;
|
||||
}
|
||||
async uninstall(progress) {
|
||||
await progress.race(this._browserContext.removeInitScripts(this._initScripts));
|
||||
this._initScripts = [];
|
||||
}
|
||||
async fastForward(progress, ticks) {
|
||||
await this._installIfNeeded(progress);
|
||||
const ticksMillis = parseTicks(ticks);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('fastForward', ${Date.now()}, ${ticksMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`));
|
||||
}
|
||||
async install(progress, time) {
|
||||
await this._installIfNeeded(progress);
|
||||
const timeMillis = time !== void 0 ? parseTime(time) : Date.now();
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('install', ${Date.now()}, ${timeMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`));
|
||||
}
|
||||
async pauseAt(progress, ticks) {
|
||||
await this._installIfNeeded(progress);
|
||||
const timeMillis = parseTime(ticks);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`));
|
||||
}
|
||||
resumeNoReply() {
|
||||
if (!this._initScripts.length)
|
||||
return;
|
||||
const doResume = async () => {
|
||||
this._initScripts.push(await this._browserContext.addInitScript(void 0, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
|
||||
await this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`);
|
||||
};
|
||||
doResume().catch(() => {
|
||||
});
|
||||
}
|
||||
async resume(progress) {
|
||||
await this._installIfNeeded(progress);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('resume', ${Date.now()})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.resume()`));
|
||||
}
|
||||
async setFixedTime(progress, time) {
|
||||
await this._installIfNeeded(progress);
|
||||
const timeMillis = parseTime(time);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setFixedTime', ${Date.now()}, ${timeMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setFixedTime(${timeMillis})`));
|
||||
}
|
||||
async setSystemTime(progress, time) {
|
||||
await this._installIfNeeded(progress);
|
||||
const timeMillis = parseTime(time);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('setSystemTime', ${Date.now()}, ${timeMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.setSystemTime(${timeMillis})`));
|
||||
}
|
||||
async runFor(progress, ticks) {
|
||||
await this._installIfNeeded(progress);
|
||||
const ticksMillis = parseTicks(ticks);
|
||||
this._initScripts.push(await this._browserContext.addInitScript(progress, `globalThis.__pwClock.controller.log('runFor', ${Date.now()}, ${ticksMillis})`));
|
||||
await progress.race(this._evaluateInFrames(`globalThis.__pwClock.controller.runFor(${ticksMillis})`));
|
||||
}
|
||||
async _installIfNeeded(progress) {
|
||||
if (this._initScripts.length)
|
||||
return;
|
||||
const script = `(() => {
|
||||
const module = {};
|
||||
${rawClockSource.source}
|
||||
if (!globalThis.__pwClock)
|
||||
globalThis.__pwClock = (module.exports.inject())(globalThis);
|
||||
})();`;
|
||||
const initScript = await this._browserContext.addInitScript(progress, script);
|
||||
await progress.race(this._evaluateInFrames(script));
|
||||
this._initScripts.push(initScript);
|
||||
}
|
||||
async _evaluateInFrames(script) {
|
||||
await this._browserContext.safeNonStallingEvaluateInAllFrames(script, "main", { throwOnJSErrors: true });
|
||||
}
|
||||
}
|
||||
function parseTicks(value) {
|
||||
if (typeof value === "number")
|
||||
return value;
|
||||
if (!value)
|
||||
return 0;
|
||||
const str = value;
|
||||
const strings = str.split(":");
|
||||
const l = strings.length;
|
||||
let i = l;
|
||||
let ms = 0;
|
||||
let parsed;
|
||||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
||||
throw new Error(
|
||||
`Clock only understands numbers, 'mm:ss' and 'hh:mm:ss'`
|
||||
);
|
||||
}
|
||||
while (i--) {
|
||||
parsed = parseInt(strings[i], 10);
|
||||
if (parsed >= 60)
|
||||
throw new Error(`Invalid time ${str}`);
|
||||
ms += parsed * Math.pow(60, l - i - 1);
|
||||
}
|
||||
return ms * 1e3;
|
||||
}
|
||||
function parseTime(epoch) {
|
||||
if (!epoch)
|
||||
return 0;
|
||||
if (typeof epoch === "number")
|
||||
return epoch;
|
||||
const parsed = new Date(epoch);
|
||||
if (!isFinite(parsed.getTime()))
|
||||
throw new Error(`Invalid date: ${epoch}`);
|
||||
return parsed.getTime();
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Clock
|
||||
});
|
||||
327
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/csharp.js
generated
vendored
Normal file
327
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/csharp.js
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var csharp_exports = {};
|
||||
__export(csharp_exports, {
|
||||
CSharpLanguageGenerator: () => CSharpLanguageGenerator
|
||||
});
|
||||
module.exports = __toCommonJS(csharp_exports);
|
||||
var import_language = require("./language");
|
||||
var import_utils = require("../../utils");
|
||||
var import_deviceDescriptors = require("../deviceDescriptors");
|
||||
class CSharpLanguageGenerator {
|
||||
constructor(mode) {
|
||||
this.groupName = ".NET C#";
|
||||
this.highlighter = "csharp";
|
||||
if (mode === "library") {
|
||||
this.name = "Library";
|
||||
this.id = "csharp";
|
||||
} else if (mode === "mstest") {
|
||||
this.name = "MSTest";
|
||||
this.id = "csharp-mstest";
|
||||
} else if (mode === "nunit") {
|
||||
this.name = "NUnit";
|
||||
this.id = "csharp-nunit";
|
||||
} else {
|
||||
throw new Error(`Unknown C# language mode: ${mode}`);
|
||||
}
|
||||
this._mode = mode;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = this._generateActionInner(actionInContext);
|
||||
if (action)
|
||||
return action;
|
||||
return "";
|
||||
}
|
||||
_generateActionInner(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._mode !== "library" && (action.name === "openPage" || action.name === "closePage"))
|
||||
return "";
|
||||
const pageAlias = this._formatPageAlias(actionInContext.frame.pageAlias);
|
||||
const formatter = new CSharpFormatter(this._mode === "library" ? 0 : 8);
|
||||
if (action.name === "openPage") {
|
||||
formatter.add(`var ${pageAlias} = await context.NewPageAsync();`);
|
||||
if (action.url && action.url !== "about:blank" && action.url !== "chrome://newtab/")
|
||||
formatter.add(`await ${pageAlias}.GotoAsync(${quote(action.url)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map((selector) => `.${this._asLocator(selector)}.ContentFrame`);
|
||||
const subject = `${pageAlias}${locators.join("")}`;
|
||||
const signals = (0, import_language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` void ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler(object sender, IDialog dialog)
|
||||
{
|
||||
Console.WriteLine($"Dialog message: {dialog.Message}");
|
||||
dialog.DismissAsync();
|
||||
${pageAlias}.Dialog -= ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;
|
||||
}
|
||||
${pageAlias}.Dialog += ${pageAlias}_Dialog${signals.dialog.dialogAlias}_EventHandler;`);
|
||||
}
|
||||
const lines = [];
|
||||
lines.push(this._generateActionCall(subject, actionInContext));
|
||||
if (signals.download) {
|
||||
lines.unshift(`var download${signals.download.downloadAlias} = await ${pageAlias}.RunAndWaitForDownloadAsync(async () =>
|
||||
{`);
|
||||
lines.push(`});`);
|
||||
}
|
||||
if (signals.popup) {
|
||||
lines.unshift(`var ${this._formatPageAlias(signals.popup.popupAlias)} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>
|
||||
{`);
|
||||
lines.push(`});`);
|
||||
}
|
||||
for (const line of lines)
|
||||
formatter.add(line);
|
||||
return formatter.format();
|
||||
}
|
||||
_formatPageAlias(pageAlias) {
|
||||
if (this._mode === "library")
|
||||
return pageAlias;
|
||||
if (pageAlias === "page")
|
||||
return "Page";
|
||||
return pageAlias;
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case "openPage":
|
||||
throw Error("Not reached");
|
||||
case "closePage":
|
||||
return `await ${subject}.CloseAsync();`;
|
||||
case "click": {
|
||||
let method = "Click";
|
||||
if (action.clickCount === 2)
|
||||
method = "DblClick";
|
||||
const options = (0, import_language.toClickOptionsForSourceCode)(action);
|
||||
if (!Object.entries(options).length)
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.${method}Async();`;
|
||||
const optionsString = formatObject(options, " ");
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.${method}Async(${optionsString});`;
|
||||
}
|
||||
case "hover": {
|
||||
const optionsString = action.position ? formatObject({ position: action.position }, " ") : "";
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.HoverAsync(${optionsString});`;
|
||||
}
|
||||
case "check":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.CheckAsync();`;
|
||||
case "uncheck":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.UncheckAsync();`;
|
||||
case "fill":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.FillAsync(${quote(action.text)});`;
|
||||
case "setInputFiles":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.SetInputFilesAsync(${formatObject(action.files)});`;
|
||||
case "press": {
|
||||
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join("+");
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.PressAsync(${quote(shortcut)});`;
|
||||
}
|
||||
case "navigate":
|
||||
return `await ${subject}.GotoAsync(${quote(action.url)});`;
|
||||
case "select":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.SelectOptionAsync(${formatObject(action.options)});`;
|
||||
case "assertText":
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "ToContainTextAsync" : "ToHaveTextAsync"}(${quote(action.text)});`;
|
||||
case "assertChecked":
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)})${action.checked ? "" : ".Not"}.ToBeCheckedAsync();`;
|
||||
case "assertVisible":
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToBeVisibleAsync();`;
|
||||
case "assertValue": {
|
||||
const assertion = action.value ? `ToHaveValueAsync(${quote(action.value)})` : `ToBeEmptyAsync()`;
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case "assertSnapshot":
|
||||
return `await Expect(${subject}.${this._asLocator(action.selector)}).ToMatchAriaSnapshotAsync(${quote(action.ariaSnapshot)});`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, import_utils.asLocator)("csharp", selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
if (this._mode === "library")
|
||||
return this.generateStandaloneHeader(options);
|
||||
return this.generateTestRunnerHeader(options);
|
||||
}
|
||||
generateStandaloneHeader(options) {
|
||||
const formatter = new CSharpFormatter(0);
|
||||
formatter.add(`
|
||||
using Microsoft.Playwright;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using var playwright = await Playwright.CreateAsync();
|
||||
await using var browser = await playwright.${toPascal(options.browserName)}.LaunchAsync(${formatObject(options.launchOptions, " ")});
|
||||
var context = await browser.NewContextAsync(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
||||
if (options.contextOptions.recordHar) {
|
||||
const url = options.contextOptions.recordHar.urlFilter;
|
||||
formatter.add(` await context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
|
||||
}
|
||||
formatter.newLine();
|
||||
return formatter.format();
|
||||
}
|
||||
generateTestRunnerHeader(options) {
|
||||
const formatter = new CSharpFormatter(0);
|
||||
formatter.add(`
|
||||
using Microsoft.Playwright.${this._mode === "nunit" ? "NUnit" : "MSTest"};
|
||||
using Microsoft.Playwright;
|
||||
|
||||
${this._mode === "nunit" ? `[Parallelizable(ParallelScope.Self)]
|
||||
[TestFixture]` : "[TestClass]"}
|
||||
public class Tests : PageTest
|
||||
{`);
|
||||
const formattedContextOptions = formatContextOptions(options.contextOptions, options.deviceName);
|
||||
if (formattedContextOptions) {
|
||||
formatter.add(`public override BrowserNewContextOptions ContextOptions()
|
||||
{
|
||||
return ${formattedContextOptions};
|
||||
}`);
|
||||
formatter.newLine();
|
||||
}
|
||||
formatter.add(` [${this._mode === "nunit" ? "Test" : "TestMethod"}]
|
||||
public async Task MyTest()
|
||||
{`);
|
||||
if (options.contextOptions.recordHar) {
|
||||
const url = options.contextOptions.recordHar.urlFilter;
|
||||
formatter.add(` await Context.RouteFromHARAsync(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatObject({ url }, " ")}` : ""});`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
const offset = this._mode === "library" ? "" : " ";
|
||||
let storageStateLine = saveStorage ? `
|
||||
${offset}await context.StorageStateAsync(new()
|
||||
${offset}{
|
||||
${offset} Path = ${quote(saveStorage)}
|
||||
${offset}});
|
||||
` : "";
|
||||
if (this._mode !== "library")
|
||||
storageStateLine += ` }
|
||||
}
|
||||
`;
|
||||
return storageStateLine;
|
||||
}
|
||||
}
|
||||
function formatObject(value, indent = " ", name = "") {
|
||||
if (typeof value === "string") {
|
||||
if (["colorScheme", "modifiers", "button", "recordHarContent", "recordHarMode", "serviceWorkers"].includes(name))
|
||||
return `${getEnumName(name)}.${toPascal(value)}`;
|
||||
return quote(value);
|
||||
}
|
||||
if (Array.isArray(value))
|
||||
return `new[] { ${value.map((o) => formatObject(o, indent, name)).join(", ")} }`;
|
||||
if (typeof value === "object") {
|
||||
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
||||
if (!keys.length)
|
||||
return `new()`;
|
||||
const tokens = [];
|
||||
for (const key of keys) {
|
||||
const property = getPropertyName(key);
|
||||
tokens.push(`${property} = ${formatObject(value[key], indent, key)},`);
|
||||
}
|
||||
return `new()
|
||||
{
|
||||
${indent}${tokens.join(`
|
||||
${indent}`)}
|
||||
${indent}}`;
|
||||
}
|
||||
if (name === "latitude" || name === "longitude")
|
||||
return String(value) + "m";
|
||||
return String(value);
|
||||
}
|
||||
function getEnumName(value) {
|
||||
switch (value) {
|
||||
case "modifiers":
|
||||
return "KeyboardModifier";
|
||||
case "button":
|
||||
return "MouseButton";
|
||||
case "recordHarMode":
|
||||
return "HarMode";
|
||||
case "recordHarContent":
|
||||
return "HarContentPolicy";
|
||||
case "serviceWorkers":
|
||||
return "ServiceWorkerPolicy";
|
||||
default:
|
||||
return toPascal(value);
|
||||
}
|
||||
}
|
||||
function getPropertyName(key) {
|
||||
switch (key) {
|
||||
case "storageState":
|
||||
return "StorageStatePath";
|
||||
case "viewport":
|
||||
return "ViewportSize";
|
||||
default:
|
||||
return toPascal(key);
|
||||
}
|
||||
}
|
||||
function toPascal(value) {
|
||||
return value[0].toUpperCase() + value.slice(1);
|
||||
}
|
||||
function formatContextOptions(contextOptions, deviceName) {
|
||||
const options = { ...contextOptions };
|
||||
delete options.recordHar;
|
||||
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
|
||||
if (!device) {
|
||||
if (!Object.entries(options).length)
|
||||
return "";
|
||||
return formatObject(options, " ");
|
||||
}
|
||||
if (!Object.entries((0, import_language.sanitizeDeviceOptions)(device, options)).length)
|
||||
return `playwright.Devices[${quote(deviceName)}]`;
|
||||
delete options["defaultBrowserType"];
|
||||
return formatObject(options, " ");
|
||||
}
|
||||
class CSharpFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._lines = [];
|
||||
this._baseIndent = " ".repeat(4);
|
||||
this._baseOffset = " ".repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
this._lines = text.trim().split("\n").map((line) => line.trim()).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
this._lines.push(...text.trim().split("\n").map((line) => line.trim()));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push("");
|
||||
}
|
||||
format() {
|
||||
let spaces = "";
|
||||
let previousLine = "";
|
||||
return this._lines.map((line) => {
|
||||
if (line === "")
|
||||
return line;
|
||||
if (line.startsWith("}") || line.startsWith("]") || line.includes("});") || line === ");")
|
||||
spaces = spaces.substring(this._baseIndent.length);
|
||||
const extraSpaces = /^(for|while|if).*\(.*\)$/.test(previousLine) ? this._baseIndent : "";
|
||||
previousLine = line;
|
||||
line = spaces + extraSpaces + line;
|
||||
if (line.endsWith("{") || line.endsWith("[") || line.endsWith("("))
|
||||
spaces += this._baseIndent;
|
||||
if (line.endsWith("));"))
|
||||
spaces = spaces.substring(this._baseIndent.length);
|
||||
return this._baseOffset + line;
|
||||
}).join("\n");
|
||||
}
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, import_utils.escapeWithQuotes)(text, '"');
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CSharpLanguageGenerator
|
||||
});
|
||||
274
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/java.js
generated
vendored
Normal file
274
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/java.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var java_exports = {};
|
||||
__export(java_exports, {
|
||||
JavaLanguageGenerator: () => JavaLanguageGenerator
|
||||
});
|
||||
module.exports = __toCommonJS(java_exports);
|
||||
var import_language = require("./language");
|
||||
var import_deviceDescriptors = require("../deviceDescriptors");
|
||||
var import_javascript = require("./javascript");
|
||||
var import_utils = require("../../utils");
|
||||
class JavaLanguageGenerator {
|
||||
constructor(mode) {
|
||||
this.groupName = "Java";
|
||||
this.highlighter = "java";
|
||||
if (mode === "library") {
|
||||
this.name = "Library";
|
||||
this.id = "java";
|
||||
} else if (mode === "junit") {
|
||||
this.name = "JUnit";
|
||||
this.id = "java-junit";
|
||||
} else {
|
||||
throw new Error(`Unknown Java language mode: ${mode}`);
|
||||
}
|
||||
this._mode = mode;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const offset = this._mode === "junit" ? 4 : 6;
|
||||
const formatter = new import_javascript.JavaScriptFormatter(offset);
|
||||
if (this._mode !== "library" && (action.name === "openPage" || action.name === "closePage"))
|
||||
return "";
|
||||
if (action.name === "openPage") {
|
||||
formatter.add(`Page ${pageAlias} = context.newPage();`);
|
||||
if (action.url && action.url !== "about:blank" && action.url !== "chrome://newtab/")
|
||||
formatter.add(`${pageAlias}.navigate(${quote(action.url)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map((selector) => `.${this._asLocator(selector, false)}.contentFrame()`);
|
||||
const subject = `${pageAlias}${locators.join("")}`;
|
||||
const signals = (0, import_language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` ${pageAlias}.onceDialog(dialog -> {
|
||||
System.out.println(String.format("Dialog message: %s", dialog.message()));
|
||||
dialog.dismiss();
|
||||
});`);
|
||||
}
|
||||
let code = this._generateActionCall(subject, actionInContext, !!actionInContext.frame.framePath.length);
|
||||
if (signals.popup) {
|
||||
code = `Page ${signals.popup.popupAlias} = ${pageAlias}.waitForPopup(() -> {
|
||||
${code}
|
||||
});`;
|
||||
}
|
||||
if (signals.download) {
|
||||
code = `Download download${signals.download.downloadAlias} = ${pageAlias}.waitForDownload(() -> {
|
||||
${code}
|
||||
});`;
|
||||
}
|
||||
formatter.add(code);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext, inFrameLocator) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case "openPage":
|
||||
throw Error("Not reached");
|
||||
case "closePage":
|
||||
return `${subject}.close();`;
|
||||
case "click": {
|
||||
let method = "click";
|
||||
if (action.clickCount === 2)
|
||||
method = "dblclick";
|
||||
const options = (0, import_language.toClickOptionsForSourceCode)(action);
|
||||
const optionsText = formatClickOptions(options);
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.${method}(${optionsText});`;
|
||||
}
|
||||
case "hover": {
|
||||
const optionsText = action.position ? `new Locator.HoverOptions().setPosition(${action.position.x}, ${action.position.y})` : "";
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.hover(${optionsText});`;
|
||||
}
|
||||
case "check":
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.check();`;
|
||||
case "uncheck":
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.uncheck();`;
|
||||
case "fill":
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.fill(${quote(action.text)});`;
|
||||
case "setInputFiles":
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.setInputFiles(${formatPath(action.files.length === 1 ? action.files[0] : action.files)});`;
|
||||
case "press": {
|
||||
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join("+");
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.press(${quote(shortcut)});`;
|
||||
}
|
||||
case "navigate":
|
||||
return `${subject}.navigate(${quote(action.url)});`;
|
||||
case "select":
|
||||
return `${subject}.${this._asLocator(action.selector, inFrameLocator)}.selectOption(${formatSelectOption(action.options.length === 1 ? action.options[0] : action.options)});`;
|
||||
case "assertText":
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).${action.substring ? "containsText" : "hasText"}(${quote(action.text)});`;
|
||||
case "assertChecked":
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)})${action.checked ? "" : ".not()"}.isChecked();`;
|
||||
case "assertVisible":
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).isVisible();`;
|
||||
case "assertValue": {
|
||||
const assertion = action.value ? `hasValue(${quote(action.value)})` : `isEmpty()`;
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).${assertion};`;
|
||||
}
|
||||
case "assertSnapshot":
|
||||
return `assertThat(${subject}.${this._asLocator(action.selector, inFrameLocator)}).matchesAriaSnapshot(${quote(action.ariaSnapshot)});`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector, inFrameLocator) {
|
||||
return (0, import_utils.asLocator)("java", selector, inFrameLocator);
|
||||
}
|
||||
generateHeader(options) {
|
||||
const formatter = new import_javascript.JavaScriptFormatter();
|
||||
if (this._mode === "junit") {
|
||||
formatter.add(`
|
||||
import com.microsoft.playwright.junit.UsePlaywright;
|
||||
import com.microsoft.playwright.Page;
|
||||
import com.microsoft.playwright.options.*;
|
||||
|
||||
${options.contextOptions.recordHar ? `import java.nio.file.Paths;
|
||||
` : ""}import org.junit.jupiter.api.*;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.*;
|
||||
|
||||
@UsePlaywright
|
||||
public class TestExample {
|
||||
@Test
|
||||
void test(Page page) {`);
|
||||
if (options.contextOptions.recordHar) {
|
||||
const url = options.contextOptions.recordHar.urlFilter;
|
||||
const recordHarOptions = typeof url === "string" ? `, new Page.RouteFromHAROptions()
|
||||
.setUrl(${quote(url)})` : "";
|
||||
formatter.add(` page.routeFromHAR(Paths.get(${quote(options.contextOptions.recordHar.path)})${recordHarOptions});`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
formatter.add(`
|
||||
import com.microsoft.playwright.*;
|
||||
import com.microsoft.playwright.options.*;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
|
||||
${options.contextOptions.recordHar ? `import java.nio.file.Paths;
|
||||
` : ""}import java.util.*;
|
||||
|
||||
public class Example {
|
||||
public static void main(String[] args) {
|
||||
try (Playwright playwright = Playwright.create()) {
|
||||
Browser browser = playwright.${options.browserName}().launch(${formatLaunchOptions(options.launchOptions)});
|
||||
BrowserContext context = browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName)});`);
|
||||
if (options.contextOptions.recordHar) {
|
||||
const url = options.contextOptions.recordHar.urlFilter;
|
||||
const recordHarOptions = typeof url === "string" ? `, new BrowserContext.RouteFromHAROptions()
|
||||
.setUrl(${quote(url)})` : "";
|
||||
formatter.add(` context.routeFromHAR(Paths.get(${quote(options.contextOptions.recordHar.path)})${recordHarOptions});`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
const storageStateLine = saveStorage ? `
|
||||
context.storageState(new BrowserContext.StorageStateOptions().setPath(${quote(saveStorage)}));
|
||||
` : "";
|
||||
if (this._mode === "junit") {
|
||||
return `${storageStateLine} }
|
||||
}`;
|
||||
}
|
||||
return `${storageStateLine} }
|
||||
}
|
||||
}`;
|
||||
}
|
||||
}
|
||||
function formatPath(files) {
|
||||
if (Array.isArray(files)) {
|
||||
if (files.length === 0)
|
||||
return "new Path[0]";
|
||||
return `new Path[] {${files.map((s) => "Paths.get(" + quote(s) + ")").join(", ")}}`;
|
||||
}
|
||||
return `Paths.get(${quote(files)})`;
|
||||
}
|
||||
function formatSelectOption(options) {
|
||||
if (Array.isArray(options)) {
|
||||
if (options.length === 0)
|
||||
return "new String[0]";
|
||||
return `new String[] {${options.map((s) => quote(s)).join(", ")}}`;
|
||||
}
|
||||
return quote(options);
|
||||
}
|
||||
function formatLaunchOptions(options) {
|
||||
const lines = [];
|
||||
if (!Object.keys(options).filter((key) => options[key] !== void 0).length)
|
||||
return "";
|
||||
lines.push("new BrowserType.LaunchOptions()");
|
||||
if (options.channel)
|
||||
lines.push(` .setChannel(${quote(options.channel)})`);
|
||||
if (typeof options.headless === "boolean")
|
||||
lines.push(` .setHeadless(false)`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
function formatContextOptions(contextOptions, deviceName) {
|
||||
const lines = [];
|
||||
if (!Object.keys(contextOptions).length && !deviceName)
|
||||
return "";
|
||||
const device = deviceName ? import_deviceDescriptors.deviceDescriptors[deviceName] : {};
|
||||
const options = { ...device, ...contextOptions };
|
||||
lines.push("new Browser.NewContextOptions()");
|
||||
if (options.acceptDownloads)
|
||||
lines.push(` .setAcceptDownloads(true)`);
|
||||
if (options.bypassCSP)
|
||||
lines.push(` .setBypassCSP(true)`);
|
||||
if (options.colorScheme)
|
||||
lines.push(` .setColorScheme(ColorScheme.${options.colorScheme.toUpperCase()})`);
|
||||
if (options.deviceScaleFactor)
|
||||
lines.push(` .setDeviceScaleFactor(${options.deviceScaleFactor})`);
|
||||
if (options.geolocation)
|
||||
lines.push(` .setGeolocation(${options.geolocation.latitude}, ${options.geolocation.longitude})`);
|
||||
if (options.hasTouch)
|
||||
lines.push(` .setHasTouch(${options.hasTouch})`);
|
||||
if (options.isMobile)
|
||||
lines.push(` .setIsMobile(${options.isMobile})`);
|
||||
if (options.locale)
|
||||
lines.push(` .setLocale(${quote(options.locale)})`);
|
||||
if (options.proxy)
|
||||
lines.push(` .setProxy(new Proxy(${quote(options.proxy.server)}))`);
|
||||
if (options.serviceWorkers)
|
||||
lines.push(` .setServiceWorkers(ServiceWorkerPolicy.${options.serviceWorkers.toUpperCase()})`);
|
||||
if (options.storageState)
|
||||
lines.push(` .setStorageStatePath(Paths.get(${quote(options.storageState)}))`);
|
||||
if (options.timezoneId)
|
||||
lines.push(` .setTimezoneId(${quote(options.timezoneId)})`);
|
||||
if (options.userAgent)
|
||||
lines.push(` .setUserAgent(${quote(options.userAgent)})`);
|
||||
if (options.viewport)
|
||||
lines.push(` .setViewportSize(${options.viewport.width}, ${options.viewport.height})`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
function formatClickOptions(options) {
|
||||
const lines = [];
|
||||
if (options.button)
|
||||
lines.push(` .setButton(MouseButton.${options.button.toUpperCase()})`);
|
||||
if (options.modifiers)
|
||||
lines.push(` .setModifiers(Arrays.asList(${options.modifiers.map((m) => `KeyboardModifier.${m.toUpperCase()}`).join(", ")}))`);
|
||||
if (options.clickCount)
|
||||
lines.push(` .setClickCount(${options.clickCount})`);
|
||||
if (options.position)
|
||||
lines.push(` .setPosition(${options.position.x}, ${options.position.y})`);
|
||||
if (!lines.length)
|
||||
return "";
|
||||
lines.unshift(`new Locator.ClickOptions()`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, import_utils.escapeWithQuotes)(text, '"');
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JavaLanguageGenerator
|
||||
});
|
||||
270
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/javascript.js
generated
vendored
Normal file
270
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/javascript.js
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var javascript_exports = {};
|
||||
__export(javascript_exports, {
|
||||
JavaScriptFormatter: () => JavaScriptFormatter,
|
||||
JavaScriptLanguageGenerator: () => JavaScriptLanguageGenerator,
|
||||
quoteMultiline: () => quoteMultiline
|
||||
});
|
||||
module.exports = __toCommonJS(javascript_exports);
|
||||
var import_language = require("./language");
|
||||
var import_utils = require("../../utils");
|
||||
var import_deviceDescriptors = require("../deviceDescriptors");
|
||||
class JavaScriptLanguageGenerator {
|
||||
constructor(isTest) {
|
||||
this.groupName = "Node.js";
|
||||
this.highlighter = "javascript";
|
||||
this.id = isTest ? "playwright-test" : "javascript";
|
||||
this.name = isTest ? "Test Runner" : "Library";
|
||||
this._isTest = isTest;
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._isTest && (action.name === "openPage" || action.name === "closePage"))
|
||||
return "";
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const formatter = new JavaScriptFormatter(2);
|
||||
if (action.name === "openPage") {
|
||||
formatter.add(`const ${pageAlias} = await context.newPage();`);
|
||||
if (action.url && action.url !== "about:blank" && action.url !== "chrome://newtab/")
|
||||
formatter.add(`await ${pageAlias}.goto(${quote(action.url)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map((selector) => `.${this._asLocator(selector)}.contentFrame()`);
|
||||
const subject = `${pageAlias}${locators.join("")}`;
|
||||
const signals = (0, import_language.toSignalMap)(action);
|
||||
if (signals.dialog) {
|
||||
formatter.add(` ${pageAlias}.once('dialog', dialog => {
|
||||
console.log(\`Dialog message: \${dialog.message()}\`);
|
||||
dialog.dismiss().catch(() => {});
|
||||
});`);
|
||||
}
|
||||
if (signals.popup)
|
||||
formatter.add(`const ${signals.popup.popupAlias}Promise = ${pageAlias}.waitForEvent('popup');`);
|
||||
if (signals.download)
|
||||
formatter.add(`const download${signals.download.downloadAlias}Promise = ${pageAlias}.waitForEvent('download');`);
|
||||
formatter.add(wrapWithStep(actionInContext.description, this._generateActionCall(subject, actionInContext)));
|
||||
if (signals.popup)
|
||||
formatter.add(`const ${signals.popup.popupAlias} = await ${signals.popup.popupAlias}Promise;`);
|
||||
if (signals.download)
|
||||
formatter.add(`const download${signals.download.downloadAlias} = await download${signals.download.downloadAlias}Promise;`);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case "openPage":
|
||||
throw Error("Not reached");
|
||||
case "closePage":
|
||||
return `await ${subject}.close();`;
|
||||
case "click": {
|
||||
let method = "click";
|
||||
if (action.clickCount === 2)
|
||||
method = "dblclick";
|
||||
const options = (0, import_language.toClickOptionsForSourceCode)(action);
|
||||
const optionsString = formatOptions(options, false);
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.${method}(${optionsString});`;
|
||||
}
|
||||
case "hover":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.hover(${formatOptions({ position: action.position }, false)});`;
|
||||
case "check":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.check();`;
|
||||
case "uncheck":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.uncheck();`;
|
||||
case "fill":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)});`;
|
||||
case "setInputFiles":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.setInputFiles(${formatObject(action.files.length === 1 ? action.files[0] : action.files)});`;
|
||||
case "press": {
|
||||
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join("+");
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.press(${quote(shortcut)});`;
|
||||
}
|
||||
case "navigate":
|
||||
return `await ${subject}.goto(${quote(action.url)});`;
|
||||
case "select":
|
||||
return `await ${subject}.${this._asLocator(action.selector)}.selectOption(${formatObject(action.options.length === 1 ? action.options[0] : action.options)});`;
|
||||
case "assertText":
|
||||
return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "toContainText" : "toHaveText"}(${quote(action.text)});`;
|
||||
case "assertChecked":
|
||||
return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)})${action.checked ? "" : ".not"}.toBeChecked();`;
|
||||
case "assertVisible":
|
||||
return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)}).toBeVisible();`;
|
||||
case "assertValue": {
|
||||
const assertion = action.value ? `toHaveValue(${quote(action.value)})` : `toBeEmpty()`;
|
||||
return `${this._isTest ? "" : "// "}await expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case "assertSnapshot": {
|
||||
const commentIfNeeded = this._isTest ? "" : "// ";
|
||||
return `${commentIfNeeded}await expect(${subject}.${this._asLocator(action.selector)}).toMatchAriaSnapshot(${quoteMultiline(action.ariaSnapshot, `${commentIfNeeded} `)});`;
|
||||
}
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, import_utils.asLocator)("javascript", selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
if (this._isTest)
|
||||
return this.generateTestHeader(options);
|
||||
return this.generateStandaloneHeader(options);
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
if (this._isTest)
|
||||
return this.generateTestFooter(saveStorage);
|
||||
return this.generateStandaloneFooter(saveStorage);
|
||||
}
|
||||
generateTestHeader(options) {
|
||||
const formatter = new JavaScriptFormatter();
|
||||
const useText = formatContextOptions(options.contextOptions, options.deviceName, this._isTest);
|
||||
formatter.add(`
|
||||
import { test, expect${options.deviceName ? ", devices" : ""} } from '@playwright/test';
|
||||
${useText ? "\ntest.use(" + useText + ");\n" : ""}
|
||||
test('test', async ({ page }) => {`);
|
||||
if (options.contextOptions.recordHar) {
|
||||
const url = options.contextOptions.recordHar.urlFilter;
|
||||
formatter.add(` await page.routeFromHAR(${quote(options.contextOptions.recordHar.path)}${url ? `, ${formatOptions({ url }, false)}` : ""});`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
generateTestFooter(saveStorage) {
|
||||
return `});`;
|
||||
}
|
||||
generateStandaloneHeader(options) {
|
||||
const formatter = new JavaScriptFormatter();
|
||||
formatter.add(`
|
||||
const { ${options.browserName}${options.deviceName ? ", devices" : ""} } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await ${options.browserName}.launch(${formatObjectOrVoid(options.launchOptions)});
|
||||
const context = await browser.newContext(${formatContextOptions(options.contextOptions, options.deviceName, false)});`);
|
||||
if (options.contextOptions.recordHar)
|
||||
formatter.add(` await context.routeFromHAR(${quote(options.contextOptions.recordHar.path)});`);
|
||||
return formatter.format();
|
||||
}
|
||||
generateStandaloneFooter(saveStorage) {
|
||||
const storageStateLine = saveStorage ? `
|
||||
await context.storageState({ path: ${quote(saveStorage)} });` : "";
|
||||
return `
|
||||
// ---------------------${storageStateLine}
|
||||
await context.close();
|
||||
await browser.close();
|
||||
})();`;
|
||||
}
|
||||
}
|
||||
function formatOptions(value, hasArguments) {
|
||||
const keys = Object.keys(value).filter((key) => value[key] !== void 0);
|
||||
if (!keys.length)
|
||||
return "";
|
||||
return (hasArguments ? ", " : "") + formatObject(value);
|
||||
}
|
||||
function formatObject(value, indent = " ") {
|
||||
if (typeof value === "string")
|
||||
return quote(value);
|
||||
if (Array.isArray(value))
|
||||
return `[${value.map((o) => formatObject(o)).join(", ")}]`;
|
||||
if (typeof value === "object") {
|
||||
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
||||
if (!keys.length)
|
||||
return "{}";
|
||||
const tokens = [];
|
||||
for (const key of keys)
|
||||
tokens.push(`${key}: ${formatObject(value[key])}`);
|
||||
return `{
|
||||
${indent}${tokens.join(`,
|
||||
${indent}`)}
|
||||
}`;
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
function formatObjectOrVoid(value, indent = " ") {
|
||||
const result = formatObject(value, indent);
|
||||
return result === "{}" ? "" : result;
|
||||
}
|
||||
function formatContextOptions(options, deviceName, isTest) {
|
||||
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
|
||||
options = { ...options, recordHar: void 0 };
|
||||
if (!device)
|
||||
return formatObjectOrVoid(options);
|
||||
let serializedObject = formatObjectOrVoid((0, import_language.sanitizeDeviceOptions)(device, options));
|
||||
if (!serializedObject)
|
||||
serializedObject = "{\n}";
|
||||
const lines = serializedObject.split("\n");
|
||||
lines.splice(1, 0, `...devices[${quote(deviceName)}],`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
class JavaScriptFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._lines = [];
|
||||
this._baseIndent = " ".repeat(2);
|
||||
this._baseOffset = " ".repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
const trim = isMultilineString(text) ? (line) => line : (line) => line.trim();
|
||||
this._lines = text.trim().split("\n").map(trim).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
const trim = isMultilineString(text) ? (line) => line : (line) => line.trim();
|
||||
this._lines.push(...text.trim().split("\n").map(trim));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push("");
|
||||
}
|
||||
format() {
|
||||
let spaces = "";
|
||||
let previousLine = "";
|
||||
return this._lines.map((line) => {
|
||||
if (line === "")
|
||||
return line;
|
||||
if (line.startsWith("}") || line.startsWith("]"))
|
||||
spaces = spaces.substring(this._baseIndent.length);
|
||||
const extraSpaces = /^(for|while|if|try).*\(.*\)$/.test(previousLine) ? this._baseIndent : "";
|
||||
previousLine = line;
|
||||
const callCarryOver = line.startsWith(".set");
|
||||
line = spaces + extraSpaces + (callCarryOver ? this._baseIndent : "") + line;
|
||||
if (line.endsWith("{") || line.endsWith("["))
|
||||
spaces += this._baseIndent;
|
||||
return this._baseOffset + line;
|
||||
}).join("\n");
|
||||
}
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, import_utils.escapeWithQuotes)(text, "'");
|
||||
}
|
||||
function wrapWithStep(description, body) {
|
||||
return description ? `await test.step(\`${description}\`, async () => {
|
||||
${body}
|
||||
});` : body;
|
||||
}
|
||||
function quoteMultiline(text, indent = " ") {
|
||||
const escape = (text2) => text2.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
||||
const lines = text.split("\n");
|
||||
if (lines.length === 1)
|
||||
return "`" + escape(text) + "`";
|
||||
return "`\n" + lines.map((line) => indent + escape(line).replace(/\${/g, "\\${")).join("\n") + `
|
||||
${indent}\``;
|
||||
}
|
||||
function isMultilineString(text) {
|
||||
return text.match(/`[\S\s]*`/)?.[0].includes("\n");
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JavaScriptFormatter,
|
||||
JavaScriptLanguageGenerator,
|
||||
quoteMultiline
|
||||
});
|
||||
52
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/jsonl.js
generated
vendored
Normal file
52
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/jsonl.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var jsonl_exports = {};
|
||||
__export(jsonl_exports, {
|
||||
JsonlLanguageGenerator: () => JsonlLanguageGenerator
|
||||
});
|
||||
module.exports = __toCommonJS(jsonl_exports);
|
||||
var import_utils = require("../../utils");
|
||||
class JsonlLanguageGenerator {
|
||||
constructor() {
|
||||
this.id = "jsonl";
|
||||
this.groupName = "";
|
||||
this.name = "JSONL";
|
||||
this.highlighter = "javascript";
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const locator = actionInContext.action.selector ? JSON.parse((0, import_utils.asLocator)("jsonl", actionInContext.action.selector)) : void 0;
|
||||
const entry = {
|
||||
...actionInContext.action,
|
||||
...actionInContext.frame,
|
||||
locator,
|
||||
ariaSnapshot: void 0
|
||||
};
|
||||
return JSON.stringify(entry);
|
||||
}
|
||||
generateHeader(options) {
|
||||
return JSON.stringify(options);
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JsonlLanguageGenerator
|
||||
});
|
||||
132
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/language.js
generated
vendored
Normal file
132
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/language.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var language_exports = {};
|
||||
__export(language_exports, {
|
||||
fromKeyboardModifiers: () => fromKeyboardModifiers,
|
||||
generateCode: () => generateCode,
|
||||
sanitizeDeviceOptions: () => sanitizeDeviceOptions,
|
||||
toClickOptionsForSourceCode: () => toClickOptionsForSourceCode,
|
||||
toKeyboardModifiers: () => toKeyboardModifiers,
|
||||
toSignalMap: () => toSignalMap
|
||||
});
|
||||
module.exports = __toCommonJS(language_exports);
|
||||
function generateCode(actions, languageGenerator, options) {
|
||||
const header = languageGenerator.generateHeader(options);
|
||||
const footer = languageGenerator.generateFooter(options.saveStorage);
|
||||
const actionTexts = actions.map((a) => generateActionText(languageGenerator, a, !!options.generateAutoExpect)).filter(Boolean);
|
||||
const text = [header, ...actionTexts, footer].join("\n");
|
||||
return { header, footer, actionTexts, text };
|
||||
}
|
||||
function generateActionText(generator, action, generateAutoExpect) {
|
||||
let text = generator.generateAction(action);
|
||||
if (!text)
|
||||
return;
|
||||
if (generateAutoExpect && action.action.preconditionSelector) {
|
||||
const expectAction = {
|
||||
frame: action.frame,
|
||||
startTime: action.startTime,
|
||||
endTime: action.startTime,
|
||||
action: {
|
||||
name: "assertVisible",
|
||||
selector: action.action.preconditionSelector,
|
||||
signals: []
|
||||
}
|
||||
};
|
||||
const expectText = generator.generateAction(expectAction);
|
||||
if (expectText)
|
||||
text = expectText + "\n\n" + text;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
function sanitizeDeviceOptions(device, options) {
|
||||
const cleanedOptions = {};
|
||||
for (const property in options) {
|
||||
if (JSON.stringify(device[property]) !== JSON.stringify(options[property]))
|
||||
cleanedOptions[property] = options[property];
|
||||
}
|
||||
return cleanedOptions;
|
||||
}
|
||||
function toSignalMap(action) {
|
||||
let popup;
|
||||
let download;
|
||||
let dialog;
|
||||
for (const signal of action.signals) {
|
||||
if (signal.name === "popup")
|
||||
popup = signal;
|
||||
else if (signal.name === "download")
|
||||
download = signal;
|
||||
else if (signal.name === "dialog")
|
||||
dialog = signal;
|
||||
}
|
||||
return {
|
||||
popup,
|
||||
download,
|
||||
dialog
|
||||
};
|
||||
}
|
||||
function toKeyboardModifiers(modifiers) {
|
||||
const result = [];
|
||||
if (modifiers & 1)
|
||||
result.push("Alt");
|
||||
if (modifiers & 2)
|
||||
result.push("ControlOrMeta");
|
||||
if (modifiers & 4)
|
||||
result.push("ControlOrMeta");
|
||||
if (modifiers & 8)
|
||||
result.push("Shift");
|
||||
return result;
|
||||
}
|
||||
function fromKeyboardModifiers(modifiers) {
|
||||
let result = 0;
|
||||
if (!modifiers)
|
||||
return result;
|
||||
if (modifiers.includes("Alt"))
|
||||
result |= 1;
|
||||
if (modifiers.includes("Control"))
|
||||
result |= 2;
|
||||
if (modifiers.includes("ControlOrMeta"))
|
||||
result |= 2;
|
||||
if (modifiers.includes("Meta"))
|
||||
result |= 4;
|
||||
if (modifiers.includes("Shift"))
|
||||
result |= 8;
|
||||
return result;
|
||||
}
|
||||
function toClickOptionsForSourceCode(action) {
|
||||
const modifiers = toKeyboardModifiers(action.modifiers);
|
||||
const options = {};
|
||||
if (action.button !== "left")
|
||||
options.button = action.button;
|
||||
if (modifiers.length)
|
||||
options.modifiers = modifiers;
|
||||
if (action.clickCount > 2)
|
||||
options.clickCount = action.clickCount;
|
||||
if (action.position)
|
||||
options.position = action.position;
|
||||
return options;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
fromKeyboardModifiers,
|
||||
generateCode,
|
||||
sanitizeDeviceOptions,
|
||||
toClickOptionsForSourceCode,
|
||||
toKeyboardModifiers,
|
||||
toSignalMap
|
||||
});
|
||||
68
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/languages.js
generated
vendored
Normal file
68
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/languages.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var languages_exports = {};
|
||||
__export(languages_exports, {
|
||||
languageSet: () => languageSet
|
||||
});
|
||||
module.exports = __toCommonJS(languages_exports);
|
||||
var import_csharp = require("./csharp");
|
||||
var import_java = require("./java");
|
||||
var import_javascript = require("./javascript");
|
||||
var import_jsonl = require("./jsonl");
|
||||
var import_python = require("./python");
|
||||
function languageSet() {
|
||||
return /* @__PURE__ */ new Set([
|
||||
new import_javascript.JavaScriptLanguageGenerator(
|
||||
/* isPlaywrightTest */
|
||||
true
|
||||
),
|
||||
new import_javascript.JavaScriptLanguageGenerator(
|
||||
/* isPlaywrightTest */
|
||||
false
|
||||
),
|
||||
new import_python.PythonLanguageGenerator(
|
||||
/* isAsync */
|
||||
false,
|
||||
/* isPytest */
|
||||
true
|
||||
),
|
||||
new import_python.PythonLanguageGenerator(
|
||||
/* isAsync */
|
||||
false,
|
||||
/* isPytest */
|
||||
false
|
||||
),
|
||||
new import_python.PythonLanguageGenerator(
|
||||
/* isAsync */
|
||||
true,
|
||||
/* isPytest */
|
||||
false
|
||||
),
|
||||
new import_csharp.CSharpLanguageGenerator("mstest"),
|
||||
new import_csharp.CSharpLanguageGenerator("nunit"),
|
||||
new import_csharp.CSharpLanguageGenerator("library"),
|
||||
new import_java.JavaLanguageGenerator("junit"),
|
||||
new import_java.JavaLanguageGenerator("library"),
|
||||
new import_jsonl.JsonlLanguageGenerator()
|
||||
]);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
languageSet
|
||||
});
|
||||
279
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/python.js
generated
vendored
Normal file
279
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/python.js
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var python_exports = {};
|
||||
__export(python_exports, {
|
||||
PythonLanguageGenerator: () => PythonLanguageGenerator
|
||||
});
|
||||
module.exports = __toCommonJS(python_exports);
|
||||
var import_language = require("./language");
|
||||
var import_utils = require("../../utils");
|
||||
var import_deviceDescriptors = require("../deviceDescriptors");
|
||||
class PythonLanguageGenerator {
|
||||
constructor(isAsync, isPyTest) {
|
||||
this.groupName = "Python";
|
||||
this.highlighter = "python";
|
||||
this.id = isPyTest ? "python-pytest" : isAsync ? "python-async" : "python";
|
||||
this.name = isPyTest ? "Pytest" : isAsync ? "Library Async" : "Library";
|
||||
this._isAsync = isAsync;
|
||||
this._isPyTest = isPyTest;
|
||||
this._awaitPrefix = isAsync ? "await " : "";
|
||||
this._asyncPrefix = isAsync ? "async " : "";
|
||||
}
|
||||
generateAction(actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
if (this._isPyTest && (action.name === "openPage" || action.name === "closePage"))
|
||||
return "";
|
||||
const pageAlias = actionInContext.frame.pageAlias;
|
||||
const formatter = new PythonFormatter(4);
|
||||
if (action.name === "openPage") {
|
||||
formatter.add(`${pageAlias} = ${this._awaitPrefix}context.new_page()`);
|
||||
if (action.url && action.url !== "about:blank" && action.url !== "chrome://newtab/")
|
||||
formatter.add(`${this._awaitPrefix}${pageAlias}.goto(${quote(action.url)})`);
|
||||
return formatter.format();
|
||||
}
|
||||
const locators = actionInContext.frame.framePath.map((selector) => `.${this._asLocator(selector)}.content_frame`);
|
||||
const subject = `${pageAlias}${locators.join("")}`;
|
||||
const signals = (0, import_language.toSignalMap)(action);
|
||||
if (signals.dialog)
|
||||
formatter.add(` ${pageAlias}.once("dialog", lambda dialog: dialog.dismiss())`);
|
||||
let code = `${this._awaitPrefix}${this._generateActionCall(subject, actionInContext)}`;
|
||||
if (signals.popup) {
|
||||
code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as ${signals.popup.popupAlias}_info {
|
||||
${code}
|
||||
}
|
||||
${signals.popup.popupAlias} = ${this._awaitPrefix}${signals.popup.popupAlias}_info.value`;
|
||||
}
|
||||
if (signals.download) {
|
||||
code = `${this._asyncPrefix}with ${pageAlias}.expect_download() as download${signals.download.downloadAlias}_info {
|
||||
${code}
|
||||
}
|
||||
download${signals.download.downloadAlias} = ${this._awaitPrefix}download${signals.download.downloadAlias}_info.value`;
|
||||
}
|
||||
formatter.add(code);
|
||||
return formatter.format();
|
||||
}
|
||||
_generateActionCall(subject, actionInContext) {
|
||||
const action = actionInContext.action;
|
||||
switch (action.name) {
|
||||
case "openPage":
|
||||
throw Error("Not reached");
|
||||
case "closePage":
|
||||
return `${subject}.close()`;
|
||||
case "click": {
|
||||
let method = "click";
|
||||
if (action.clickCount === 2)
|
||||
method = "dblclick";
|
||||
const options = (0, import_language.toClickOptionsForSourceCode)(action);
|
||||
const optionsString = formatOptions(options, false);
|
||||
return `${subject}.${this._asLocator(action.selector)}.${method}(${optionsString})`;
|
||||
}
|
||||
case "hover":
|
||||
return `${subject}.${this._asLocator(action.selector)}.hover(${formatOptions({ position: action.position }, false)})`;
|
||||
case "check":
|
||||
return `${subject}.${this._asLocator(action.selector)}.check()`;
|
||||
case "uncheck":
|
||||
return `${subject}.${this._asLocator(action.selector)}.uncheck()`;
|
||||
case "fill":
|
||||
return `${subject}.${this._asLocator(action.selector)}.fill(${quote(action.text)})`;
|
||||
case "setInputFiles":
|
||||
return `${subject}.${this._asLocator(action.selector)}.set_input_files(${formatValue(action.files.length === 1 ? action.files[0] : action.files)})`;
|
||||
case "press": {
|
||||
const modifiers = (0, import_language.toKeyboardModifiers)(action.modifiers);
|
||||
const shortcut = [...modifiers, action.key].join("+");
|
||||
return `${subject}.${this._asLocator(action.selector)}.press(${quote(shortcut)})`;
|
||||
}
|
||||
case "navigate":
|
||||
return `${subject}.goto(${quote(action.url)})`;
|
||||
case "select":
|
||||
return `${subject}.${this._asLocator(action.selector)}.select_option(${formatValue(action.options.length === 1 ? action.options[0] : action.options)})`;
|
||||
case "assertText":
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${action.substring ? "to_contain_text" : "to_have_text"}(${quote(action.text)})`;
|
||||
case "assertChecked":
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${action.checked ? "to_be_checked()" : "not_to_be_checked()"}`;
|
||||
case "assertVisible":
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).to_be_visible()`;
|
||||
case "assertValue": {
|
||||
const assertion = action.value ? `to_have_value(${quote(action.value)})` : `to_be_empty()`;
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).${assertion};`;
|
||||
}
|
||||
case "assertSnapshot":
|
||||
return `expect(${subject}.${this._asLocator(action.selector)}).to_match_aria_snapshot(${quote(action.ariaSnapshot)})`;
|
||||
}
|
||||
}
|
||||
_asLocator(selector) {
|
||||
return (0, import_utils.asLocator)("python", selector);
|
||||
}
|
||||
generateHeader(options) {
|
||||
const formatter = new PythonFormatter();
|
||||
const recordHar = options.contextOptions.recordHar;
|
||||
if (this._isPyTest) {
|
||||
const contextOptions = formatContextOptions(
|
||||
options.contextOptions,
|
||||
options.deviceName,
|
||||
true
|
||||
/* asDict */
|
||||
);
|
||||
const fixture = contextOptions ? `
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def browser_context_args(browser_context_args, playwright) {
|
||||
return {${contextOptions}}
|
||||
}
|
||||
` : "";
|
||||
formatter.add(`${options.deviceName || contextOptions ? "import pytest\n" : ""}import re
|
||||
from playwright.sync_api import Page, expect
|
||||
${fixture}
|
||||
|
||||
def test_example(page: Page) -> None {`);
|
||||
if (recordHar)
|
||||
formatter.add(` page.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
|
||||
} else if (this._isAsync) {
|
||||
formatter.add(`
|
||||
import asyncio
|
||||
import re
|
||||
from playwright.async_api import Playwright, async_playwright, expect
|
||||
|
||||
|
||||
async def run(playwright: Playwright) -> None {
|
||||
browser = await playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})
|
||||
context = await browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);
|
||||
if (recordHar)
|
||||
formatter.add(` await context.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
|
||||
} else {
|
||||
formatter.add(`
|
||||
import re
|
||||
from playwright.sync_api import Playwright, sync_playwright, expect
|
||||
|
||||
|
||||
def run(playwright: Playwright) -> None {
|
||||
browser = playwright.${options.browserName}.launch(${formatOptions(options.launchOptions, false)})
|
||||
context = browser.new_context(${formatContextOptions(options.contextOptions, options.deviceName)})`);
|
||||
if (recordHar)
|
||||
formatter.add(` context.route_from_har(${quote(recordHar.path)}${typeof recordHar.urlFilter === "string" ? `, url=${quote(recordHar.urlFilter)}` : ""})`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
generateFooter(saveStorage) {
|
||||
if (this._isPyTest) {
|
||||
return "";
|
||||
} else if (this._isAsync) {
|
||||
const storageStateLine = saveStorage ? `
|
||||
await context.storage_state(path=${quote(saveStorage)})` : "";
|
||||
return `
|
||||
# ---------------------${storageStateLine}
|
||||
await context.close()
|
||||
await browser.close()
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with async_playwright() as playwright:
|
||||
await run(playwright)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
`;
|
||||
} else {
|
||||
const storageStateLine = saveStorage ? `
|
||||
context.storage_state(path=${quote(saveStorage)})` : "";
|
||||
return `
|
||||
# ---------------------${storageStateLine}
|
||||
context.close()
|
||||
browser.close()
|
||||
|
||||
|
||||
with sync_playwright() as playwright:
|
||||
run(playwright)
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
function formatValue(value) {
|
||||
if (value === false)
|
||||
return "False";
|
||||
if (value === true)
|
||||
return "True";
|
||||
if (value === void 0)
|
||||
return "None";
|
||||
if (Array.isArray(value))
|
||||
return `[${value.map(formatValue).join(", ")}]`;
|
||||
if (typeof value === "string")
|
||||
return quote(value);
|
||||
if (typeof value === "object")
|
||||
return JSON.stringify(value);
|
||||
return String(value);
|
||||
}
|
||||
function formatOptions(value, hasArguments, asDict) {
|
||||
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
||||
if (!keys.length)
|
||||
return "";
|
||||
return (hasArguments ? ", " : "") + keys.map((key) => {
|
||||
if (asDict)
|
||||
return `"${(0, import_utils.toSnakeCase)(key)}": ${formatValue(value[key])}`;
|
||||
return `${(0, import_utils.toSnakeCase)(key)}=${formatValue(value[key])}`;
|
||||
}).join(", ");
|
||||
}
|
||||
function formatContextOptions(options, deviceName, asDict) {
|
||||
options = { ...options, recordHar: void 0 };
|
||||
const device = deviceName && import_deviceDescriptors.deviceDescriptors[deviceName];
|
||||
if (!device)
|
||||
return formatOptions(options, false, asDict);
|
||||
return `**playwright.devices[${quote(deviceName)}]` + formatOptions((0, import_language.sanitizeDeviceOptions)(device, options), true, asDict);
|
||||
}
|
||||
class PythonFormatter {
|
||||
constructor(offset = 0) {
|
||||
this._lines = [];
|
||||
this._baseIndent = " ".repeat(4);
|
||||
this._baseOffset = " ".repeat(offset);
|
||||
}
|
||||
prepend(text) {
|
||||
this._lines = text.trim().split("\n").map((line) => line.trim()).concat(this._lines);
|
||||
}
|
||||
add(text) {
|
||||
this._lines.push(...text.trim().split("\n").map((line) => line.trim()));
|
||||
}
|
||||
newLine() {
|
||||
this._lines.push("");
|
||||
}
|
||||
format() {
|
||||
let spaces = "";
|
||||
const lines = [];
|
||||
this._lines.forEach((line) => {
|
||||
if (line === "")
|
||||
return lines.push(line);
|
||||
if (line === "}") {
|
||||
spaces = spaces.substring(this._baseIndent.length);
|
||||
return;
|
||||
}
|
||||
line = spaces + line;
|
||||
if (line.endsWith("{")) {
|
||||
spaces += this._baseIndent;
|
||||
line = line.substring(0, line.length - 1).trimEnd() + ":";
|
||||
}
|
||||
return lines.push(this._baseOffset + line);
|
||||
});
|
||||
return lines.join("\n");
|
||||
}
|
||||
}
|
||||
function quote(text) {
|
||||
return (0, import_utils.escapeWithQuotes)(text, '"');
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
PythonLanguageGenerator
|
||||
});
|
||||
16
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/types.js
generated
vendored
Normal file
16
.playwright-mcp/node_modules/playwright-core/lib/server/codegen/types.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var types_exports = {};
|
||||
module.exports = __toCommonJS(types_exports);
|
||||
57
.playwright-mcp/node_modules/playwright-core/lib/server/console.js
generated
vendored
Normal file
57
.playwright-mcp/node_modules/playwright-core/lib/server/console.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var console_exports = {};
|
||||
__export(console_exports, {
|
||||
ConsoleMessage: () => ConsoleMessage
|
||||
});
|
||||
module.exports = __toCommonJS(console_exports);
|
||||
class ConsoleMessage {
|
||||
constructor(page, worker, type, text, args, location) {
|
||||
this._page = page;
|
||||
this._worker = worker;
|
||||
this._type = type;
|
||||
this._text = text;
|
||||
this._args = args;
|
||||
this._location = location || { url: "", lineNumber: 0, columnNumber: 0 };
|
||||
}
|
||||
page() {
|
||||
return this._page;
|
||||
}
|
||||
worker() {
|
||||
return this._worker;
|
||||
}
|
||||
type() {
|
||||
return this._type;
|
||||
}
|
||||
text() {
|
||||
if (this._text === void 0)
|
||||
this._text = this._args.map((arg) => arg.preview()).join(" ");
|
||||
return this._text;
|
||||
}
|
||||
args() {
|
||||
return this._args;
|
||||
}
|
||||
location() {
|
||||
return this._location;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ConsoleMessage
|
||||
});
|
||||
206
.playwright-mcp/node_modules/playwright-core/lib/server/cookieStore.js
generated
vendored
Normal file
206
.playwright-mcp/node_modules/playwright-core/lib/server/cookieStore.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var cookieStore_exports = {};
|
||||
__export(cookieStore_exports, {
|
||||
Cookie: () => Cookie,
|
||||
CookieStore: () => CookieStore,
|
||||
domainMatches: () => domainMatches,
|
||||
parseRawCookie: () => parseRawCookie
|
||||
});
|
||||
module.exports = __toCommonJS(cookieStore_exports);
|
||||
var import_network = require("./network");
|
||||
class Cookie {
|
||||
constructor(data) {
|
||||
this._raw = data;
|
||||
}
|
||||
name() {
|
||||
return this._raw.name;
|
||||
}
|
||||
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.4
|
||||
matches(url) {
|
||||
if (this._raw.secure && (url.protocol !== "https:" && !(0, import_network.isLocalHostname)(url.hostname)))
|
||||
return false;
|
||||
if (!domainMatches(url.hostname, this._raw.domain))
|
||||
return false;
|
||||
if (!pathMatches(url.pathname, this._raw.path))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
equals(other) {
|
||||
return this._raw.name === other._raw.name && this._raw.domain === other._raw.domain && this._raw.path === other._raw.path;
|
||||
}
|
||||
networkCookie() {
|
||||
return this._raw;
|
||||
}
|
||||
updateExpiresFrom(other) {
|
||||
this._raw.expires = other._raw.expires;
|
||||
}
|
||||
expired() {
|
||||
if (this._raw.expires === -1)
|
||||
return false;
|
||||
return this._raw.expires * 1e3 < Date.now();
|
||||
}
|
||||
}
|
||||
class CookieStore {
|
||||
constructor() {
|
||||
this._nameToCookies = /* @__PURE__ */ new Map();
|
||||
}
|
||||
addCookies(cookies) {
|
||||
for (const cookie of cookies)
|
||||
this._addCookie(new Cookie(cookie));
|
||||
}
|
||||
cookies(url) {
|
||||
const result = [];
|
||||
for (const cookie of this._cookiesIterator()) {
|
||||
if (cookie.matches(url))
|
||||
result.push(cookie.networkCookie());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
allCookies() {
|
||||
const result = [];
|
||||
for (const cookie of this._cookiesIterator())
|
||||
result.push(cookie.networkCookie());
|
||||
return result;
|
||||
}
|
||||
_addCookie(cookie) {
|
||||
let set = this._nameToCookies.get(cookie.name());
|
||||
if (!set) {
|
||||
set = /* @__PURE__ */ new Set();
|
||||
this._nameToCookies.set(cookie.name(), set);
|
||||
}
|
||||
for (const other of set) {
|
||||
if (other.equals(cookie))
|
||||
set.delete(other);
|
||||
}
|
||||
set.add(cookie);
|
||||
CookieStore.pruneExpired(set);
|
||||
}
|
||||
*_cookiesIterator() {
|
||||
for (const [name, cookies] of this._nameToCookies) {
|
||||
CookieStore.pruneExpired(cookies);
|
||||
for (const cookie of cookies)
|
||||
yield cookie;
|
||||
if (cookies.size === 0)
|
||||
this._nameToCookies.delete(name);
|
||||
}
|
||||
}
|
||||
static pruneExpired(cookies) {
|
||||
for (const cookie of cookies) {
|
||||
if (cookie.expired())
|
||||
cookies.delete(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
function parseRawCookie(header) {
|
||||
const pairs = header.split(";").filter((s) => s.trim().length > 0).map((p) => {
|
||||
let key = "";
|
||||
let value2 = "";
|
||||
const separatorPos = p.indexOf("=");
|
||||
if (separatorPos === -1) {
|
||||
key = p.trim();
|
||||
} else {
|
||||
key = p.slice(0, separatorPos).trim();
|
||||
value2 = p.slice(separatorPos + 1).trim();
|
||||
}
|
||||
return [key, value2];
|
||||
});
|
||||
if (!pairs.length)
|
||||
return null;
|
||||
const [name, value] = pairs[0];
|
||||
const cookie = {
|
||||
name,
|
||||
value
|
||||
};
|
||||
for (let i = 1; i < pairs.length; i++) {
|
||||
const [name2, value2] = pairs[i];
|
||||
switch (name2.toLowerCase()) {
|
||||
case "expires":
|
||||
const expiresMs = +new Date(value2);
|
||||
if (isFinite(expiresMs)) {
|
||||
if (expiresMs <= 0)
|
||||
cookie.expires = 0;
|
||||
else
|
||||
cookie.expires = Math.min(expiresMs / 1e3, import_network.kMaxCookieExpiresDateInSeconds);
|
||||
}
|
||||
break;
|
||||
case "max-age":
|
||||
const maxAgeSec = parseInt(value2, 10);
|
||||
if (isFinite(maxAgeSec)) {
|
||||
if (maxAgeSec <= 0)
|
||||
cookie.expires = 0;
|
||||
else
|
||||
cookie.expires = Math.min(Date.now() / 1e3 + maxAgeSec, import_network.kMaxCookieExpiresDateInSeconds);
|
||||
}
|
||||
break;
|
||||
case "domain":
|
||||
cookie.domain = value2.toLocaleLowerCase() || "";
|
||||
if (cookie.domain && !cookie.domain.startsWith(".") && cookie.domain.includes("."))
|
||||
cookie.domain = "." + cookie.domain;
|
||||
break;
|
||||
case "path":
|
||||
cookie.path = value2 || "";
|
||||
break;
|
||||
case "secure":
|
||||
cookie.secure = true;
|
||||
break;
|
||||
case "httponly":
|
||||
cookie.httpOnly = true;
|
||||
break;
|
||||
case "samesite":
|
||||
switch (value2.toLowerCase()) {
|
||||
case "none":
|
||||
cookie.sameSite = "None";
|
||||
break;
|
||||
case "lax":
|
||||
cookie.sameSite = "Lax";
|
||||
break;
|
||||
case "strict":
|
||||
cookie.sameSite = "Strict";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cookie;
|
||||
}
|
||||
function domainMatches(value, domain) {
|
||||
if (value === domain)
|
||||
return true;
|
||||
if (!domain.startsWith("."))
|
||||
return false;
|
||||
value = "." + value;
|
||||
return value.endsWith(domain);
|
||||
}
|
||||
function pathMatches(value, path) {
|
||||
if (value === path)
|
||||
return true;
|
||||
if (!value.endsWith("/"))
|
||||
value = value + "/";
|
||||
if (!path.endsWith("/"))
|
||||
path = path + "/";
|
||||
return value.startsWith(path);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Cookie,
|
||||
CookieStore,
|
||||
domainMatches,
|
||||
parseRawCookie
|
||||
});
|
||||
191
.playwright-mcp/node_modules/playwright-core/lib/server/debugController.js
generated
vendored
Normal file
191
.playwright-mcp/node_modules/playwright-core/lib/server/debugController.js
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var debugController_exports = {};
|
||||
__export(debugController_exports, {
|
||||
DebugController: () => DebugController
|
||||
});
|
||||
module.exports = __toCommonJS(debugController_exports);
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_processLauncher = require("./utils/processLauncher");
|
||||
var import_recorder = require("./recorder");
|
||||
var import_utils = require("../utils");
|
||||
var import_ariaSnapshot = require("../utils/isomorphic/ariaSnapshot");
|
||||
var import_utilsBundle = require("../utilsBundle");
|
||||
var import_locatorParser = require("../utils/isomorphic/locatorParser");
|
||||
var import_language = require("./codegen/language");
|
||||
var import_recorderUtils = require("./recorder/recorderUtils");
|
||||
var import_javascript = require("./codegen/javascript");
|
||||
class DebugController extends import_instrumentation.SdkObject {
|
||||
constructor(playwright) {
|
||||
super({ attribution: { isInternalPlaywright: true }, instrumentation: (0, import_instrumentation.createInstrumentation)() }, void 0, "DebugController");
|
||||
this._sdkLanguage = "javascript";
|
||||
this._generateAutoExpect = false;
|
||||
this._playwright = playwright;
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
StateChanged: "stateChanged",
|
||||
InspectRequested: "inspectRequested",
|
||||
SourceChanged: "sourceChanged",
|
||||
Paused: "paused",
|
||||
SetModeRequested: "setModeRequested"
|
||||
};
|
||||
}
|
||||
initialize(codegenId, sdkLanguage) {
|
||||
this._sdkLanguage = sdkLanguage;
|
||||
}
|
||||
dispose() {
|
||||
this.setReportStateChanged(false);
|
||||
}
|
||||
setReportStateChanged(enabled) {
|
||||
if (enabled && !this._trackHierarchyListener) {
|
||||
this._trackHierarchyListener = {
|
||||
onPageOpen: () => this._emitSnapshot(false),
|
||||
onPageClose: () => this._emitSnapshot(false)
|
||||
};
|
||||
this._playwright.instrumentation.addListener(this._trackHierarchyListener, null);
|
||||
this._emitSnapshot(true);
|
||||
} else if (!enabled && this._trackHierarchyListener) {
|
||||
this._playwright.instrumentation.removeListener(this._trackHierarchyListener);
|
||||
this._trackHierarchyListener = void 0;
|
||||
}
|
||||
}
|
||||
async setRecorderMode(progress, params) {
|
||||
await progress.race(this._closeBrowsersWithoutPages());
|
||||
this._generateAutoExpect = !!params.generateAutoExpect;
|
||||
if (params.mode === "none") {
|
||||
for (const recorder of await progress.race(this._allRecorders())) {
|
||||
recorder.hideHighlightedSelector();
|
||||
recorder.setMode("none");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!this._playwright.allBrowsers().length)
|
||||
await this._playwright.chromium.launch(progress, { headless: !!process.env.PW_DEBUG_CONTROLLER_HEADLESS });
|
||||
const pages = this._playwright.allPages();
|
||||
if (!pages.length) {
|
||||
const [browser] = this._playwright.allBrowsers();
|
||||
const context = await browser.newContextForReuse(progress, {});
|
||||
await context.newPage(progress);
|
||||
}
|
||||
if (params.testIdAttributeName) {
|
||||
for (const page of this._playwright.allPages())
|
||||
page.browserContext.selectors().setTestIdAttributeName(params.testIdAttributeName);
|
||||
}
|
||||
for (const recorder of await progress.race(this._allRecorders())) {
|
||||
recorder.hideHighlightedSelector();
|
||||
recorder.setMode(params.mode);
|
||||
}
|
||||
}
|
||||
async highlight(progress, params) {
|
||||
if (params.selector)
|
||||
(0, import_locatorParser.unsafeLocatorOrSelectorAsSelector)(this._sdkLanguage, params.selector, "data-testid");
|
||||
const ariaTemplate = params.ariaTemplate ? (0, import_ariaSnapshot.parseAriaSnapshotUnsafe)(import_utilsBundle.yaml, params.ariaTemplate) : void 0;
|
||||
for (const recorder of await progress.race(this._allRecorders())) {
|
||||
if (ariaTemplate)
|
||||
recorder.setHighlightedAriaTemplate(ariaTemplate);
|
||||
else if (params.selector)
|
||||
recorder.setHighlightedSelector(params.selector);
|
||||
}
|
||||
}
|
||||
async hideHighlight(progress) {
|
||||
for (const recorder of await progress.race(this._allRecorders()))
|
||||
recorder.hideHighlightedSelector();
|
||||
await Promise.all(this._playwright.allPages().map((p) => p.hideHighlight().catch(() => {
|
||||
})));
|
||||
}
|
||||
async resume(progress) {
|
||||
for (const recorder of await progress.race(this._allRecorders()))
|
||||
recorder.resume();
|
||||
}
|
||||
kill() {
|
||||
(0, import_processLauncher.gracefullyProcessExitDoNotHang)(0);
|
||||
}
|
||||
_emitSnapshot(initial) {
|
||||
const pageCount = this._playwright.allPages().length;
|
||||
if (initial && !pageCount)
|
||||
return;
|
||||
this.emit(DebugController.Events.StateChanged, { pageCount });
|
||||
}
|
||||
async _allRecorders() {
|
||||
const contexts = /* @__PURE__ */ new Set();
|
||||
for (const page of this._playwright.allPages())
|
||||
contexts.add(page.browserContext);
|
||||
const recorders = await Promise.all([...contexts].map((c) => import_recorder.Recorder.forContext(c, { omitCallTracking: true })));
|
||||
const nonNullRecorders = recorders.filter(Boolean);
|
||||
for (const recorder of recorders)
|
||||
wireListeners(recorder, this);
|
||||
return nonNullRecorders;
|
||||
}
|
||||
async _closeBrowsersWithoutPages() {
|
||||
for (const browser of this._playwright.allBrowsers()) {
|
||||
for (const context of browser.contexts()) {
|
||||
if (!context.pages().length)
|
||||
await context.close({ reason: "Browser collected" });
|
||||
}
|
||||
if (!browser.contexts())
|
||||
await browser.close({ reason: "Browser collected" });
|
||||
}
|
||||
}
|
||||
}
|
||||
const wiredSymbol = Symbol("wired");
|
||||
function wireListeners(recorder, debugController) {
|
||||
if (recorder[wiredSymbol])
|
||||
return;
|
||||
recorder[wiredSymbol] = true;
|
||||
const actions = [];
|
||||
const languageGenerator = new import_javascript.JavaScriptLanguageGenerator(
|
||||
/* isPlaywrightTest */
|
||||
true
|
||||
);
|
||||
const actionsChanged = () => {
|
||||
const aa = (0, import_recorderUtils.collapseActions)(actions);
|
||||
const { header, footer, text, actionTexts } = (0, import_language.generateCode)(aa, languageGenerator, {
|
||||
browserName: "chromium",
|
||||
launchOptions: {},
|
||||
contextOptions: {},
|
||||
generateAutoExpect: debugController._generateAutoExpect
|
||||
});
|
||||
debugController.emit(DebugController.Events.SourceChanged, { text, header, footer, actions: actionTexts });
|
||||
};
|
||||
recorder.on(import_recorder.RecorderEvent.ElementPicked, (elementInfo) => {
|
||||
const locator = (0, import_utils.asLocator)(debugController._sdkLanguage, elementInfo.selector);
|
||||
debugController.emit(DebugController.Events.InspectRequested, { selector: elementInfo.selector, locator, ariaSnapshot: elementInfo.ariaSnapshot });
|
||||
});
|
||||
recorder.on(import_recorder.RecorderEvent.PausedStateChanged, (paused) => {
|
||||
debugController.emit(DebugController.Events.Paused, { paused });
|
||||
});
|
||||
recorder.on(import_recorder.RecorderEvent.ModeChanged, (mode) => {
|
||||
debugController.emit(DebugController.Events.SetModeRequested, { mode });
|
||||
});
|
||||
recorder.on(import_recorder.RecorderEvent.ActionAdded, (action) => {
|
||||
actions.push(action);
|
||||
actionsChanged();
|
||||
});
|
||||
recorder.on(import_recorder.RecorderEvent.SignalAdded, (signal) => {
|
||||
const lastAction = actions.findLast((a) => a.frame.pageGuid === signal.frame.pageGuid);
|
||||
if (lastAction)
|
||||
lastAction.action.signals.push(signal.signal);
|
||||
actionsChanged();
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DebugController
|
||||
});
|
||||
119
.playwright-mcp/node_modules/playwright-core/lib/server/debugger.js
generated
vendored
Normal file
119
.playwright-mcp/node_modules/playwright-core/lib/server/debugger.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var debugger_exports = {};
|
||||
__export(debugger_exports, {
|
||||
Debugger: () => Debugger
|
||||
});
|
||||
module.exports = __toCommonJS(debugger_exports);
|
||||
var import_events = require("events");
|
||||
var import_utils = require("../utils");
|
||||
var import_browserContext = require("./browserContext");
|
||||
var import_protocolMetainfo = require("../utils/isomorphic/protocolMetainfo");
|
||||
const symbol = Symbol("Debugger");
|
||||
class Debugger extends import_events.EventEmitter {
|
||||
constructor(context) {
|
||||
super();
|
||||
this._pauseOnNextStatement = false;
|
||||
this._pausedCallsMetadata = /* @__PURE__ */ new Map();
|
||||
this._muted = false;
|
||||
this._context = context;
|
||||
this._context[symbol] = this;
|
||||
this._enabled = (0, import_utils.debugMode)() === "inspector";
|
||||
if (this._enabled)
|
||||
this.pauseOnNextStatement();
|
||||
context.instrumentation.addListener(this, context);
|
||||
this._context.once(import_browserContext.BrowserContext.Events.Close, () => {
|
||||
this._context.instrumentation.removeListener(this);
|
||||
});
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
PausedStateChanged: "pausedstatechanged"
|
||||
};
|
||||
}
|
||||
async setMuted(muted) {
|
||||
this._muted = muted;
|
||||
}
|
||||
async onBeforeCall(sdkObject, metadata) {
|
||||
if (this._muted)
|
||||
return;
|
||||
if (shouldPauseOnCall(sdkObject, metadata) || this._pauseOnNextStatement && shouldPauseBeforeStep(metadata))
|
||||
await this.pause(sdkObject, metadata);
|
||||
}
|
||||
async onBeforeInputAction(sdkObject, metadata) {
|
||||
if (this._muted)
|
||||
return;
|
||||
if (this._enabled && this._pauseOnNextStatement)
|
||||
await this.pause(sdkObject, metadata);
|
||||
}
|
||||
async pause(sdkObject, metadata) {
|
||||
if (this._muted)
|
||||
return;
|
||||
this._enabled = true;
|
||||
metadata.pauseStartTime = (0, import_utils.monotonicTime)();
|
||||
const result = new Promise((resolve) => {
|
||||
this._pausedCallsMetadata.set(metadata, { resolve, sdkObject });
|
||||
});
|
||||
this.emit(Debugger.Events.PausedStateChanged);
|
||||
return result;
|
||||
}
|
||||
resume(step) {
|
||||
if (!this.isPaused())
|
||||
return;
|
||||
this._pauseOnNextStatement = step;
|
||||
const endTime = (0, import_utils.monotonicTime)();
|
||||
for (const [metadata, { resolve }] of this._pausedCallsMetadata) {
|
||||
metadata.pauseEndTime = endTime;
|
||||
resolve();
|
||||
}
|
||||
this._pausedCallsMetadata.clear();
|
||||
this.emit(Debugger.Events.PausedStateChanged);
|
||||
}
|
||||
pauseOnNextStatement() {
|
||||
this._pauseOnNextStatement = true;
|
||||
}
|
||||
isPaused(metadata) {
|
||||
if (metadata)
|
||||
return this._pausedCallsMetadata.has(metadata);
|
||||
return !!this._pausedCallsMetadata.size;
|
||||
}
|
||||
pausedDetails() {
|
||||
const result = [];
|
||||
for (const [metadata, { sdkObject }] of this._pausedCallsMetadata)
|
||||
result.push({ metadata, sdkObject });
|
||||
return result;
|
||||
}
|
||||
}
|
||||
function shouldPauseOnCall(sdkObject, metadata) {
|
||||
if (sdkObject.attribution.playwright.options.isServer)
|
||||
return false;
|
||||
if (!sdkObject.attribution.browser?.options.headful && !(0, import_utils.isUnderTest)())
|
||||
return false;
|
||||
return metadata.method === "pause";
|
||||
}
|
||||
function shouldPauseBeforeStep(metadata) {
|
||||
if (metadata.internal)
|
||||
return false;
|
||||
const metainfo = import_protocolMetainfo.methodMetainfo.get(metadata.type + "." + metadata.method);
|
||||
return !!metainfo?.pausesBeforeAction;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Debugger
|
||||
});
|
||||
39
.playwright-mcp/node_modules/playwright-core/lib/server/deviceDescriptors.js
generated
vendored
Normal file
39
.playwright-mcp/node_modules/playwright-core/lib/server/deviceDescriptors.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var deviceDescriptors_exports = {};
|
||||
__export(deviceDescriptors_exports, {
|
||||
deviceDescriptors: () => deviceDescriptors
|
||||
});
|
||||
module.exports = __toCommonJS(deviceDescriptors_exports);
|
||||
var import_deviceDescriptorsSource = __toESM(require("./deviceDescriptorsSource.json"));
|
||||
const deviceDescriptors = import_deviceDescriptorsSource.default;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
deviceDescriptors
|
||||
});
|
||||
1779
.playwright-mcp/node_modules/playwright-core/lib/server/deviceDescriptorsSource.json
generated
vendored
Normal file
1779
.playwright-mcp/node_modules/playwright-core/lib/server/deviceDescriptorsSource.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
116
.playwright-mcp/node_modules/playwright-core/lib/server/dialog.js
generated
vendored
Normal file
116
.playwright-mcp/node_modules/playwright-core/lib/server/dialog.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var dialog_exports = {};
|
||||
__export(dialog_exports, {
|
||||
Dialog: () => Dialog,
|
||||
DialogManager: () => DialogManager
|
||||
});
|
||||
module.exports = __toCommonJS(dialog_exports);
|
||||
var import_utils = require("../utils");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
class Dialog extends import_instrumentation.SdkObject {
|
||||
constructor(page, type, message, onHandle, defaultValue) {
|
||||
super(page, "dialog");
|
||||
this._handled = false;
|
||||
this._page = page;
|
||||
this._type = type;
|
||||
this._message = message;
|
||||
this._onHandle = onHandle;
|
||||
this._defaultValue = defaultValue || "";
|
||||
}
|
||||
page() {
|
||||
return this._page;
|
||||
}
|
||||
type() {
|
||||
return this._type;
|
||||
}
|
||||
message() {
|
||||
return this._message;
|
||||
}
|
||||
defaultValue() {
|
||||
return this._defaultValue;
|
||||
}
|
||||
async accept(promptText) {
|
||||
(0, import_utils.assert)(!this._handled, "Cannot accept dialog which is already handled!");
|
||||
this._handled = true;
|
||||
this._page.browserContext.dialogManager.dialogWillClose(this);
|
||||
await this._onHandle(true, promptText);
|
||||
}
|
||||
async dismiss() {
|
||||
(0, import_utils.assert)(!this._handled, "Cannot dismiss dialog which is already handled!");
|
||||
this._handled = true;
|
||||
this._page.browserContext.dialogManager.dialogWillClose(this);
|
||||
await this._onHandle(false);
|
||||
}
|
||||
async close() {
|
||||
if (this._type === "beforeunload")
|
||||
await this.accept();
|
||||
else
|
||||
await this.dismiss();
|
||||
}
|
||||
}
|
||||
class DialogManager {
|
||||
constructor(instrumentation) {
|
||||
this._dialogHandlers = /* @__PURE__ */ new Set();
|
||||
this._openedDialogs = /* @__PURE__ */ new Set();
|
||||
this._instrumentation = instrumentation;
|
||||
}
|
||||
dialogDidOpen(dialog) {
|
||||
for (const frame of dialog.page().frameManager.frames())
|
||||
frame._invalidateNonStallingEvaluations("JavaScript dialog interrupted evaluation");
|
||||
this._openedDialogs.add(dialog);
|
||||
this._instrumentation.onDialog(dialog);
|
||||
let hasHandlers = false;
|
||||
for (const handler of this._dialogHandlers) {
|
||||
if (handler(dialog))
|
||||
hasHandlers = true;
|
||||
}
|
||||
if (!hasHandlers)
|
||||
dialog.close().then(() => {
|
||||
});
|
||||
}
|
||||
dialogWillClose(dialog) {
|
||||
this._openedDialogs.delete(dialog);
|
||||
}
|
||||
addDialogHandler(handler) {
|
||||
this._dialogHandlers.add(handler);
|
||||
}
|
||||
removeDialogHandler(handler) {
|
||||
this._dialogHandlers.delete(handler);
|
||||
if (!this._dialogHandlers.size) {
|
||||
for (const dialog of this._openedDialogs)
|
||||
dialog.close().catch(() => {
|
||||
});
|
||||
}
|
||||
}
|
||||
hasOpenDialogsForPage(page) {
|
||||
return [...this._openedDialogs].some((dialog) => dialog.page() === page);
|
||||
}
|
||||
async closeBeforeUnloadDialogs() {
|
||||
await Promise.all([...this._openedDialogs].map(async (dialog) => {
|
||||
if (dialog.type() === "beforeunload")
|
||||
await dialog.dismiss();
|
||||
}));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Dialog,
|
||||
DialogManager
|
||||
});
|
||||
325
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/androidDispatcher.js
generated
vendored
Normal file
325
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/androidDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var androidDispatcher_exports = {};
|
||||
__export(androidDispatcher_exports, {
|
||||
AndroidDeviceDispatcher: () => AndroidDeviceDispatcher,
|
||||
AndroidDispatcher: () => AndroidDispatcher,
|
||||
AndroidSocketDispatcher: () => AndroidSocketDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(androidDispatcher_exports);
|
||||
var import_browserContextDispatcher = require("./browserContextDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_android = require("../android/android");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
class AndroidDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, android) {
|
||||
super(scope, android, "Android", {});
|
||||
this._type_Android = true;
|
||||
}
|
||||
async devices(params, progress) {
|
||||
const devices = await this._object.devices(progress, params);
|
||||
return {
|
||||
devices: devices.map((d) => AndroidDeviceDispatcher.from(this, d))
|
||||
};
|
||||
}
|
||||
}
|
||||
class AndroidDeviceDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, device) {
|
||||
super(scope, device, "AndroidDevice", {
|
||||
model: device.model,
|
||||
serial: device.serial
|
||||
});
|
||||
this._type_EventTarget = true;
|
||||
this._type_AndroidDevice = true;
|
||||
for (const webView of device.webViews())
|
||||
this._dispatchEvent("webViewAdded", { webView });
|
||||
this.addObjectListener(import_android.AndroidDevice.Events.WebViewAdded, (webView) => this._dispatchEvent("webViewAdded", { webView }));
|
||||
this.addObjectListener(import_android.AndroidDevice.Events.WebViewRemoved, (socketName) => this._dispatchEvent("webViewRemoved", { socketName }));
|
||||
this.addObjectListener(import_android.AndroidDevice.Events.Close, () => this._dispatchEvent("close"));
|
||||
}
|
||||
static from(scope, device) {
|
||||
const result = scope.connection.existingDispatcher(device);
|
||||
return result || new AndroidDeviceDispatcher(scope, device);
|
||||
}
|
||||
async wait(params, progress) {
|
||||
await progress.race(this._object.send("wait", params));
|
||||
}
|
||||
async fill(params, progress) {
|
||||
await progress.race(this._object.send("click", { selector: params.androidSelector }));
|
||||
await progress.race(this._object.send("fill", params));
|
||||
}
|
||||
async tap(params, progress) {
|
||||
await progress.race(this._object.send("click", params));
|
||||
}
|
||||
async drag(params, progress) {
|
||||
await progress.race(this._object.send("drag", params));
|
||||
}
|
||||
async fling(params, progress) {
|
||||
await progress.race(this._object.send("fling", params));
|
||||
}
|
||||
async longTap(params, progress) {
|
||||
await progress.race(this._object.send("longClick", params));
|
||||
}
|
||||
async pinchClose(params, progress) {
|
||||
await progress.race(this._object.send("pinchClose", params));
|
||||
}
|
||||
async pinchOpen(params, progress) {
|
||||
await progress.race(this._object.send("pinchOpen", params));
|
||||
}
|
||||
async scroll(params, progress) {
|
||||
await progress.race(this._object.send("scroll", params));
|
||||
}
|
||||
async swipe(params, progress) {
|
||||
await progress.race(this._object.send("swipe", params));
|
||||
}
|
||||
async info(params, progress) {
|
||||
const info = await progress.race(this._object.send("info", params));
|
||||
fixupAndroidElementInfo(info);
|
||||
return { info };
|
||||
}
|
||||
async inputType(params, progress) {
|
||||
const text = params.text;
|
||||
const keyCodes = [];
|
||||
for (let i = 0; i < text.length; ++i) {
|
||||
const code = keyMap.get(text[i].toUpperCase());
|
||||
if (code === void 0)
|
||||
throw new Error("No mapping for " + text[i] + " found");
|
||||
keyCodes.push(code);
|
||||
}
|
||||
await progress.race(Promise.all(keyCodes.map((keyCode) => this._object.send("inputPress", { keyCode }))));
|
||||
}
|
||||
async inputPress(params, progress) {
|
||||
if (!keyMap.has(params.key))
|
||||
throw new Error("Unknown key: " + params.key);
|
||||
await progress.race(this._object.send("inputPress", { keyCode: keyMap.get(params.key) }));
|
||||
}
|
||||
async inputTap(params, progress) {
|
||||
await progress.race(this._object.send("inputClick", params));
|
||||
}
|
||||
async inputSwipe(params, progress) {
|
||||
await progress.race(this._object.send("inputSwipe", params));
|
||||
}
|
||||
async inputDrag(params, progress) {
|
||||
await progress.race(this._object.send("inputDrag", params));
|
||||
}
|
||||
async screenshot(params, progress) {
|
||||
return { binary: await progress.race(this._object.screenshot()) };
|
||||
}
|
||||
async shell(params, progress) {
|
||||
return { result: await progress.race(this._object.shell(params.command)) };
|
||||
}
|
||||
async open(params, progress) {
|
||||
const socket = await this._object.open(progress, params.command);
|
||||
return { socket: new AndroidSocketDispatcher(this, new SocketSdkObject(this._object, socket)) };
|
||||
}
|
||||
async installApk(params, progress) {
|
||||
await this._object.installApk(progress, params.file, { args: params.args });
|
||||
}
|
||||
async push(params, progress) {
|
||||
await progress.race(this._object.push(progress, params.file, params.path, params.mode));
|
||||
}
|
||||
async launchBrowser(params, progress) {
|
||||
const context = await this._object.launchBrowser(progress, params.pkg, params);
|
||||
return { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, context) };
|
||||
}
|
||||
async close(params, progress) {
|
||||
await this._object.close();
|
||||
}
|
||||
async connectToWebView(params, progress) {
|
||||
return { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, await this._object.connectToWebView(progress, params.socketName)) };
|
||||
}
|
||||
}
|
||||
class SocketSdkObject extends import_instrumentation.SdkObject {
|
||||
constructor(parent, socket) {
|
||||
super(parent, "socket");
|
||||
this._socket = socket;
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(socket, "data", (data) => this.emit("data", data)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(socket, "close", () => {
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
this.emit("close");
|
||||
})
|
||||
];
|
||||
}
|
||||
async write(data) {
|
||||
await this._socket.write(data);
|
||||
}
|
||||
close() {
|
||||
this._socket.close();
|
||||
}
|
||||
}
|
||||
class AndroidSocketDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, socket) {
|
||||
super(scope, socket, "AndroidSocket", {});
|
||||
this._type_AndroidSocket = true;
|
||||
this.addObjectListener("data", (data) => this._dispatchEvent("data", { data }));
|
||||
this.addObjectListener("close", () => {
|
||||
this._dispatchEvent("close");
|
||||
this._dispose();
|
||||
});
|
||||
}
|
||||
async write(params, progress) {
|
||||
await progress.race(this._object.write(params.data));
|
||||
}
|
||||
async close(params, progress) {
|
||||
this._object.close();
|
||||
}
|
||||
}
|
||||
const keyMap = /* @__PURE__ */ new Map([
|
||||
["Unknown", 0],
|
||||
["SoftLeft", 1],
|
||||
["SoftRight", 2],
|
||||
["Home", 3],
|
||||
["Back", 4],
|
||||
["Call", 5],
|
||||
["EndCall", 6],
|
||||
["0", 7],
|
||||
["1", 8],
|
||||
["2", 9],
|
||||
["3", 10],
|
||||
["4", 11],
|
||||
["5", 12],
|
||||
["6", 13],
|
||||
["7", 14],
|
||||
["8", 15],
|
||||
["9", 16],
|
||||
["Star", 17],
|
||||
["*", 17],
|
||||
["Pound", 18],
|
||||
["#", 18],
|
||||
["DialUp", 19],
|
||||
["DialDown", 20],
|
||||
["DialLeft", 21],
|
||||
["DialRight", 22],
|
||||
["DialCenter", 23],
|
||||
["VolumeUp", 24],
|
||||
["VolumeDown", 25],
|
||||
["Power", 26],
|
||||
["Camera", 27],
|
||||
["Clear", 28],
|
||||
["A", 29],
|
||||
["B", 30],
|
||||
["C", 31],
|
||||
["D", 32],
|
||||
["E", 33],
|
||||
["F", 34],
|
||||
["G", 35],
|
||||
["H", 36],
|
||||
["I", 37],
|
||||
["J", 38],
|
||||
["K", 39],
|
||||
["L", 40],
|
||||
["M", 41],
|
||||
["N", 42],
|
||||
["O", 43],
|
||||
["P", 44],
|
||||
["Q", 45],
|
||||
["R", 46],
|
||||
["S", 47],
|
||||
["T", 48],
|
||||
["U", 49],
|
||||
["V", 50],
|
||||
["W", 51],
|
||||
["X", 52],
|
||||
["Y", 53],
|
||||
["Z", 54],
|
||||
["Comma", 55],
|
||||
[",", 55],
|
||||
["Period", 56],
|
||||
[".", 56],
|
||||
["AltLeft", 57],
|
||||
["AltRight", 58],
|
||||
["ShiftLeft", 59],
|
||||
["ShiftRight", 60],
|
||||
["Tab", 61],
|
||||
[" ", 61],
|
||||
["Space", 62],
|
||||
[" ", 62],
|
||||
["Sym", 63],
|
||||
["Explorer", 64],
|
||||
["Envelop", 65],
|
||||
["Enter", 66],
|
||||
["Del", 67],
|
||||
["Grave", 68],
|
||||
["Minus", 69],
|
||||
["-", 69],
|
||||
["Equals", 70],
|
||||
["=", 70],
|
||||
["LeftBracket", 71],
|
||||
["(", 71],
|
||||
["RightBracket", 72],
|
||||
[")", 72],
|
||||
["Backslash", 73],
|
||||
["\\", 73],
|
||||
["Semicolon", 74],
|
||||
[";", 74],
|
||||
["Apostrophe", 75],
|
||||
["`", 75],
|
||||
["Slash", 76],
|
||||
["/", 76],
|
||||
["At", 77],
|
||||
["@", 77],
|
||||
["Num", 78],
|
||||
["HeadsetHook", 79],
|
||||
["Focus", 80],
|
||||
["Plus", 81],
|
||||
["Menu", 82],
|
||||
["Notification", 83],
|
||||
["Search", 84],
|
||||
["MediaPlayPause", 85],
|
||||
["MediaStop", 86],
|
||||
["MediaNext", 87],
|
||||
["MediaPrevious", 88],
|
||||
["MediaRewind", 89],
|
||||
["MediaFastForward", 90],
|
||||
["MediaPlay", 126],
|
||||
["MediaPause", 127],
|
||||
["MediaClose", 128],
|
||||
["MediaEject", 129],
|
||||
["MediaRecord", 130],
|
||||
["ChannelUp", 166],
|
||||
["ChannelDown", 167],
|
||||
["AppSwitch", 187],
|
||||
["Assist", 219],
|
||||
["MediaAudioTrack", 222],
|
||||
["MediaTopMenu", 226],
|
||||
["MediaSkipForward", 272],
|
||||
["MediaSkipBackward", 273],
|
||||
["MediaStepForward", 274],
|
||||
["MediaStepBackward", 275],
|
||||
["Cut", 277],
|
||||
["Copy", 278],
|
||||
["Paste", 279]
|
||||
]);
|
||||
function fixupAndroidElementInfo(info) {
|
||||
info.clazz = info.clazz || "";
|
||||
info.pkg = info.pkg || "";
|
||||
info.res = info.res || "";
|
||||
info.desc = info.desc || "";
|
||||
info.text = info.text || "";
|
||||
for (const child of info.children || [])
|
||||
fixupAndroidElementInfo(child);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
AndroidDeviceDispatcher,
|
||||
AndroidDispatcher,
|
||||
AndroidSocketDispatcher
|
||||
});
|
||||
118
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/artifactDispatcher.js
generated
vendored
Normal file
118
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/artifactDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var artifactDispatcher_exports = {};
|
||||
__export(artifactDispatcher_exports, {
|
||||
ArtifactDispatcher: () => ArtifactDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(artifactDispatcher_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_streamDispatcher = require("./streamDispatcher");
|
||||
var import_fileUtils = require("../utils/fileUtils");
|
||||
class ArtifactDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, artifact) {
|
||||
super(scope, artifact, "Artifact", {
|
||||
absolutePath: artifact.localPath()
|
||||
});
|
||||
this._type_Artifact = true;
|
||||
}
|
||||
static from(parentScope, artifact) {
|
||||
return ArtifactDispatcher.fromNullable(parentScope, artifact);
|
||||
}
|
||||
static fromNullable(parentScope, artifact) {
|
||||
if (!artifact)
|
||||
return void 0;
|
||||
const result = parentScope.connection.existingDispatcher(artifact);
|
||||
return result || new ArtifactDispatcher(parentScope, artifact);
|
||||
}
|
||||
async pathAfterFinished(params, progress) {
|
||||
const path = await progress.race(this._object.localPathAfterFinished());
|
||||
return { value: path };
|
||||
}
|
||||
async saveAs(params, progress) {
|
||||
return await progress.race(new Promise((resolve, reject) => {
|
||||
this._object.saveAs(async (localPath, error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await (0, import_fileUtils.mkdirIfNeeded)(params.path);
|
||||
await import_fs.default.promises.copyFile(localPath, params.path);
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
async saveAsStream(params, progress) {
|
||||
return await progress.race(new Promise((resolve, reject) => {
|
||||
this._object.saveAs(async (localPath, error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const readable = import_fs.default.createReadStream(localPath, { highWaterMark: 1024 * 1024 });
|
||||
const stream = new import_streamDispatcher.StreamDispatcher(this, readable);
|
||||
resolve({ stream });
|
||||
await new Promise((resolve2) => {
|
||||
readable.on("close", resolve2);
|
||||
readable.on("end", resolve2);
|
||||
readable.on("error", resolve2);
|
||||
});
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
async stream(params, progress) {
|
||||
const fileName = await progress.race(this._object.localPathAfterFinished());
|
||||
const readable = import_fs.default.createReadStream(fileName, { highWaterMark: 1024 * 1024 });
|
||||
return { stream: new import_streamDispatcher.StreamDispatcher(this, readable) };
|
||||
}
|
||||
async failure(params, progress) {
|
||||
const error = await progress.race(this._object.failureError());
|
||||
return { error: error || void 0 };
|
||||
}
|
||||
async cancel(params, progress) {
|
||||
await progress.race(this._object.cancel());
|
||||
}
|
||||
async delete(params, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await progress.race(this._object.delete());
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ArtifactDispatcher
|
||||
});
|
||||
381
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserContextDispatcher.js
generated
vendored
Normal file
381
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserContextDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserContextDispatcher_exports = {};
|
||||
__export(browserContextDispatcher_exports, {
|
||||
BrowserContextDispatcher: () => BrowserContextDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(browserContextDispatcher_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_artifactDispatcher = require("./artifactDispatcher");
|
||||
var import_cdpSessionDispatcher = require("./cdpSessionDispatcher");
|
||||
var import_dialogDispatcher = require("./dialogDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_frameDispatcher = require("./frameDispatcher");
|
||||
var import_networkDispatchers = require("./networkDispatchers");
|
||||
var import_pageDispatcher = require("./pageDispatcher");
|
||||
var import_crBrowser = require("../chromium/crBrowser");
|
||||
var import_errors = require("../errors");
|
||||
var import_tracingDispatcher = require("./tracingDispatcher");
|
||||
var import_webSocketRouteDispatcher = require("./webSocketRouteDispatcher");
|
||||
var import_writableStreamDispatcher = require("./writableStreamDispatcher");
|
||||
var import_crypto = require("../utils/crypto");
|
||||
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
||||
var import_recorder = require("../recorder");
|
||||
var import_recorderApp = require("../recorder/recorderApp");
|
||||
var import_elementHandlerDispatcher = require("./elementHandlerDispatcher");
|
||||
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
||||
class BrowserContextDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(parentScope, context) {
|
||||
const requestContext = import_networkDispatchers.APIRequestContextDispatcher.from(parentScope, context.fetchRequest);
|
||||
const tracing = import_tracingDispatcher.TracingDispatcher.from(parentScope, context.tracing);
|
||||
super(parentScope, context, "BrowserContext", {
|
||||
isChromium: context._browser.options.isChromium,
|
||||
requestContext,
|
||||
tracing,
|
||||
options: context._options
|
||||
});
|
||||
this._type_EventTarget = true;
|
||||
this._type_BrowserContext = true;
|
||||
this._subscriptions = /* @__PURE__ */ new Set();
|
||||
this._webSocketInterceptionPatterns = [];
|
||||
this._bindings = [];
|
||||
this._initScripts = [];
|
||||
this._clockPaused = false;
|
||||
this._interceptionUrlMatchers = [];
|
||||
this.adopt(requestContext);
|
||||
this.adopt(tracing);
|
||||
this._requestInterceptor = (route, request) => {
|
||||
const matchesSome = this._interceptionUrlMatchers.some((urlMatch) => (0, import_urlMatch.urlMatches)(this._context._options.baseURL, request.url(), urlMatch));
|
||||
const routeDispatcher = this.connection.existingDispatcher(route);
|
||||
if (!matchesSome || routeDispatcher) {
|
||||
route.continue({ isFallback: true }).catch(() => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._dispatchEvent("route", { route: new import_networkDispatchers.RouteDispatcher(import_networkDispatchers.RequestDispatcher.from(this, request), route) });
|
||||
};
|
||||
this._context = context;
|
||||
const onVideo = (artifact) => {
|
||||
const artifactDispatcher = import_artifactDispatcher.ArtifactDispatcher.from(parentScope, artifact);
|
||||
this._dispatchEvent("video", { artifact: artifactDispatcher });
|
||||
};
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.VideoStarted, onVideo);
|
||||
for (const video of context._browser._idToVideo.values()) {
|
||||
if (video.context === context)
|
||||
onVideo(video.artifact);
|
||||
}
|
||||
for (const page of context.pages())
|
||||
this._dispatchEvent("page", { page: import_pageDispatcher.PageDispatcher.from(this, page) });
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.Page, (page) => {
|
||||
this._dispatchEvent("page", { page: import_pageDispatcher.PageDispatcher.from(this, page) });
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.Close, () => {
|
||||
this._dispatchEvent("close");
|
||||
this._dispose();
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.PageError, (error, page) => {
|
||||
this._dispatchEvent("pageError", { error: (0, import_errors.serializeError)(error), page: import_pageDispatcher.PageDispatcher.from(this, page) });
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.Console, (message) => {
|
||||
const pageDispatcher = import_pageDispatcher.PageDispatcher.fromNullable(this, message.page());
|
||||
const workerDispatcher = import_pageDispatcher.WorkerDispatcher.fromNullable(this, message.worker());
|
||||
if (this._shouldDispatchEvent(message.page(), "console") || workerDispatcher?._subscriptions.has("console")) {
|
||||
this._dispatchEvent("console", {
|
||||
page: pageDispatcher,
|
||||
worker: workerDispatcher,
|
||||
...this.serializeConsoleMessage(message, workerDispatcher || pageDispatcher)
|
||||
});
|
||||
}
|
||||
});
|
||||
this._dialogHandler = (dialog) => {
|
||||
if (!this._shouldDispatchEvent(dialog.page(), "dialog"))
|
||||
return false;
|
||||
this._dispatchEvent("dialog", { dialog: new import_dialogDispatcher.DialogDispatcher(this, dialog) });
|
||||
return true;
|
||||
};
|
||||
context.dialogManager.addDialogHandler(this._dialogHandler);
|
||||
if (context._browser.options.name === "chromium" && this._object._browser instanceof import_crBrowser.CRBrowser) {
|
||||
for (const serviceWorker of context.serviceWorkers())
|
||||
this._dispatchEvent("serviceWorker", { worker: new import_pageDispatcher.WorkerDispatcher(this, serviceWorker) });
|
||||
this.addObjectListener(import_crBrowser.CRBrowserContext.CREvents.ServiceWorker, (serviceWorker) => this._dispatchEvent("serviceWorker", { worker: new import_pageDispatcher.WorkerDispatcher(this, serviceWorker) }));
|
||||
}
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.Request, (request) => {
|
||||
const redirectFromDispatcher = request.redirectedFrom() && this.connection.existingDispatcher(request.redirectedFrom());
|
||||
if (!redirectFromDispatcher && !this._shouldDispatchNetworkEvent(request, "request") && !request.isNavigationRequest())
|
||||
return;
|
||||
const requestDispatcher = import_networkDispatchers.RequestDispatcher.from(this, request);
|
||||
this._dispatchEvent("request", {
|
||||
request: requestDispatcher,
|
||||
page: import_pageDispatcher.PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined())
|
||||
});
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.Response, (response) => {
|
||||
const requestDispatcher = this.connection.existingDispatcher(response.request());
|
||||
if (!requestDispatcher && !this._shouldDispatchNetworkEvent(response.request(), "response"))
|
||||
return;
|
||||
this._dispatchEvent("response", {
|
||||
response: import_networkDispatchers.ResponseDispatcher.from(this, response),
|
||||
page: import_pageDispatcher.PageDispatcher.fromNullable(this, response.frame()?._page.initializedOrUndefined())
|
||||
});
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.RequestFailed, (request) => {
|
||||
const requestDispatcher = this.connection.existingDispatcher(request);
|
||||
if (!requestDispatcher && !this._shouldDispatchNetworkEvent(request, "requestFailed"))
|
||||
return;
|
||||
this._dispatchEvent("requestFailed", {
|
||||
request: import_networkDispatchers.RequestDispatcher.from(this, request),
|
||||
failureText: request._failureText || void 0,
|
||||
responseEndTiming: request._responseEndTiming,
|
||||
page: import_pageDispatcher.PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined())
|
||||
});
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.RequestFinished, ({ request, response }) => {
|
||||
const requestDispatcher = this.connection.existingDispatcher(request);
|
||||
if (!requestDispatcher && !this._shouldDispatchNetworkEvent(request, "requestFinished"))
|
||||
return;
|
||||
this._dispatchEvent("requestFinished", {
|
||||
request: import_networkDispatchers.RequestDispatcher.from(this, request),
|
||||
response: import_networkDispatchers.ResponseDispatcher.fromNullable(this, response),
|
||||
responseEndTiming: request._responseEndTiming,
|
||||
page: import_pageDispatcher.PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined())
|
||||
});
|
||||
});
|
||||
this.addObjectListener(import_browserContext.BrowserContext.Events.RecorderEvent, ({ event, data, page, code }) => {
|
||||
this._dispatchEvent("recorderEvent", { event, data, code, page: import_pageDispatcher.PageDispatcher.from(this, page) });
|
||||
});
|
||||
}
|
||||
static from(parentScope, context) {
|
||||
const result = parentScope.connection.existingDispatcher(context);
|
||||
return result || new BrowserContextDispatcher(parentScope, context);
|
||||
}
|
||||
_shouldDispatchNetworkEvent(request, event) {
|
||||
return this._shouldDispatchEvent(request.frame()?._page?.initializedOrUndefined(), event);
|
||||
}
|
||||
_shouldDispatchEvent(page, event) {
|
||||
if (this._subscriptions.has(event))
|
||||
return true;
|
||||
const pageDispatcher = page ? this.connection.existingDispatcher(page) : void 0;
|
||||
if (pageDispatcher?._subscriptions.has(event))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
serializeConsoleMessage(message, jsScope) {
|
||||
return {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
args: message.args().map((a) => {
|
||||
const elementHandle = a.asElement();
|
||||
if (elementHandle)
|
||||
return import_elementHandlerDispatcher.ElementHandleDispatcher.from(import_frameDispatcher.FrameDispatcher.from(this, elementHandle._frame), elementHandle);
|
||||
return import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(jsScope, a);
|
||||
}),
|
||||
location: message.location()
|
||||
};
|
||||
}
|
||||
async createTempFiles(params, progress) {
|
||||
const dir = this._context._browser.options.artifactsDir;
|
||||
const tmpDir = import_path.default.join(dir, "upload-" + (0, import_crypto.createGuid)());
|
||||
const tempDirWithRootName = params.rootDirName ? import_path.default.join(tmpDir, import_path.default.basename(params.rootDirName)) : tmpDir;
|
||||
await progress.race(import_fs.default.promises.mkdir(tempDirWithRootName, { recursive: true }));
|
||||
this._context._tempDirs.push(tmpDir);
|
||||
return {
|
||||
rootDir: params.rootDirName ? new import_writableStreamDispatcher.WritableStreamDispatcher(this, tempDirWithRootName) : void 0,
|
||||
writableStreams: await Promise.all(params.items.map(async (item) => {
|
||||
await progress.race(import_fs.default.promises.mkdir(import_path.default.dirname(import_path.default.join(tempDirWithRootName, item.name)), { recursive: true }));
|
||||
const file = import_fs.default.createWriteStream(import_path.default.join(tempDirWithRootName, item.name));
|
||||
return new import_writableStreamDispatcher.WritableStreamDispatcher(this, file, item.lastModifiedMs);
|
||||
}))
|
||||
};
|
||||
}
|
||||
async exposeBinding(params, progress) {
|
||||
const binding = await this._context.exposeBinding(progress, params.name, !!params.needsHandle, (source, ...args) => {
|
||||
if (this._disposed)
|
||||
return;
|
||||
const pageDispatcher = import_pageDispatcher.PageDispatcher.from(this, source.page);
|
||||
const binding2 = new import_pageDispatcher.BindingCallDispatcher(pageDispatcher, params.name, !!params.needsHandle, source, args);
|
||||
this._dispatchEvent("bindingCall", { binding: binding2 });
|
||||
return binding2.promise();
|
||||
});
|
||||
this._bindings.push(binding);
|
||||
}
|
||||
async newPage(params, progress) {
|
||||
return { page: import_pageDispatcher.PageDispatcher.from(this, await this._context.newPage(progress)) };
|
||||
}
|
||||
async cookies(params, progress) {
|
||||
return { cookies: await progress.race(this._context.cookies(params.urls)) };
|
||||
}
|
||||
async addCookies(params, progress) {
|
||||
await this._context.addCookies(params.cookies);
|
||||
}
|
||||
async clearCookies(params, progress) {
|
||||
const nameRe = params.nameRegexSource !== void 0 && params.nameRegexFlags !== void 0 ? new RegExp(params.nameRegexSource, params.nameRegexFlags) : void 0;
|
||||
const domainRe = params.domainRegexSource !== void 0 && params.domainRegexFlags !== void 0 ? new RegExp(params.domainRegexSource, params.domainRegexFlags) : void 0;
|
||||
const pathRe = params.pathRegexSource !== void 0 && params.pathRegexFlags !== void 0 ? new RegExp(params.pathRegexSource, params.pathRegexFlags) : void 0;
|
||||
await this._context.clearCookies({
|
||||
name: nameRe || params.name,
|
||||
domain: domainRe || params.domain,
|
||||
path: pathRe || params.path
|
||||
});
|
||||
}
|
||||
async grantPermissions(params, progress) {
|
||||
await this._context.grantPermissions(params.permissions, params.origin);
|
||||
}
|
||||
async clearPermissions(params, progress) {
|
||||
await this._context.clearPermissions();
|
||||
}
|
||||
async setGeolocation(params, progress) {
|
||||
await this._context.setGeolocation(params.geolocation);
|
||||
}
|
||||
async setExtraHTTPHeaders(params, progress) {
|
||||
await this._context.setExtraHTTPHeaders(progress, params.headers);
|
||||
}
|
||||
async setOffline(params, progress) {
|
||||
await this._context.setOffline(progress, params.offline);
|
||||
}
|
||||
async setHTTPCredentials(params, progress) {
|
||||
await progress.race(this._context.setHTTPCredentials(params.httpCredentials));
|
||||
}
|
||||
async addInitScript(params, progress) {
|
||||
this._initScripts.push(await this._context.addInitScript(progress, params.source));
|
||||
}
|
||||
async setNetworkInterceptionPatterns(params, progress) {
|
||||
const hadMatchers = this._interceptionUrlMatchers.length > 0;
|
||||
if (!params.patterns.length) {
|
||||
if (hadMatchers)
|
||||
await this._context.removeRequestInterceptor(this._requestInterceptor);
|
||||
this._interceptionUrlMatchers = [];
|
||||
} else {
|
||||
this._interceptionUrlMatchers = params.patterns.map((pattern) => pattern.regexSource ? new RegExp(pattern.regexSource, pattern.regexFlags) : pattern.glob);
|
||||
if (!hadMatchers)
|
||||
await this._context.addRequestInterceptor(progress, this._requestInterceptor);
|
||||
}
|
||||
}
|
||||
async setWebSocketInterceptionPatterns(params, progress) {
|
||||
this._webSocketInterceptionPatterns = params.patterns;
|
||||
if (params.patterns.length && !this._routeWebSocketInitScript)
|
||||
this._routeWebSocketInitScript = await import_webSocketRouteDispatcher.WebSocketRouteDispatcher.install(progress, this.connection, this._context);
|
||||
}
|
||||
async storageState(params, progress) {
|
||||
return await progress.race(this._context.storageState(progress, params.indexedDB));
|
||||
}
|
||||
async close(params, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._context.close(params);
|
||||
}
|
||||
async enableRecorder(params, progress) {
|
||||
await import_recorderApp.RecorderApp.show(this._context, params);
|
||||
}
|
||||
async disableRecorder(params, progress) {
|
||||
const recorder = await import_recorder.Recorder.existingForContext(this._context);
|
||||
if (recorder)
|
||||
recorder.setMode("none");
|
||||
}
|
||||
async pause(params, progress) {
|
||||
}
|
||||
async newCDPSession(params, progress) {
|
||||
if (!this._object._browser.options.isChromium)
|
||||
throw new Error(`CDP session is only available in Chromium`);
|
||||
if (!params.page && !params.frame || params.page && params.frame)
|
||||
throw new Error(`CDP session must be initiated with either Page or Frame, not none or both`);
|
||||
const crBrowserContext = this._object;
|
||||
return { session: new import_cdpSessionDispatcher.CDPSessionDispatcher(this, await progress.race(crBrowserContext.newCDPSession((params.page ? params.page : params.frame)._object))) };
|
||||
}
|
||||
async harStart(params, progress) {
|
||||
const harId = this._context.harStart(params.page ? params.page._object : null, params.options);
|
||||
return { harId };
|
||||
}
|
||||
async harExport(params, progress) {
|
||||
const artifact = await progress.race(this._context.harExport(params.harId));
|
||||
if (!artifact)
|
||||
throw new Error("No HAR artifact. Ensure record.harPath is set.");
|
||||
return { artifact: import_artifactDispatcher.ArtifactDispatcher.from(this, artifact) };
|
||||
}
|
||||
async clockFastForward(params, progress) {
|
||||
await this._context.clock.fastForward(progress, params.ticksString ?? params.ticksNumber ?? 0);
|
||||
}
|
||||
async clockInstall(params, progress) {
|
||||
await this._context.clock.install(progress, params.timeString ?? params.timeNumber ?? void 0);
|
||||
}
|
||||
async clockPauseAt(params, progress) {
|
||||
await this._context.clock.pauseAt(progress, params.timeString ?? params.timeNumber ?? 0);
|
||||
this._clockPaused = true;
|
||||
}
|
||||
async clockResume(params, progress) {
|
||||
await this._context.clock.resume(progress);
|
||||
this._clockPaused = false;
|
||||
}
|
||||
async clockRunFor(params, progress) {
|
||||
await this._context.clock.runFor(progress, params.ticksString ?? params.ticksNumber ?? 0);
|
||||
}
|
||||
async clockSetFixedTime(params, progress) {
|
||||
await this._context.clock.setFixedTime(progress, params.timeString ?? params.timeNumber ?? 0);
|
||||
}
|
||||
async clockSetSystemTime(params, progress) {
|
||||
await this._context.clock.setSystemTime(progress, params.timeString ?? params.timeNumber ?? 0);
|
||||
}
|
||||
async updateSubscription(params, progress) {
|
||||
if (params.enabled)
|
||||
this._subscriptions.add(params.event);
|
||||
else
|
||||
this._subscriptions.delete(params.event);
|
||||
}
|
||||
async registerSelectorEngine(params, progress) {
|
||||
this._object.selectors().register(params.selectorEngine);
|
||||
}
|
||||
async setTestIdAttributeName(params, progress) {
|
||||
this._object.selectors().setTestIdAttributeName(params.testIdAttributeName);
|
||||
}
|
||||
_onDispose() {
|
||||
if (this._context.isClosingOrClosed())
|
||||
return;
|
||||
this._context.dialogManager.removeDialogHandler(this._dialogHandler);
|
||||
this._interceptionUrlMatchers = [];
|
||||
this._context.removeRequestInterceptor(this._requestInterceptor).catch(() => {
|
||||
});
|
||||
this._context.removeExposedBindings(this._bindings).catch(() => {
|
||||
});
|
||||
this._bindings = [];
|
||||
this._context.removeInitScripts(this._initScripts).catch(() => {
|
||||
});
|
||||
this._initScripts = [];
|
||||
if (this._routeWebSocketInitScript)
|
||||
import_webSocketRouteDispatcher.WebSocketRouteDispatcher.uninstall(this.connection, this._context, this._routeWebSocketInitScript).catch(() => {
|
||||
});
|
||||
this._routeWebSocketInitScript = void 0;
|
||||
if (this._clockPaused)
|
||||
this._context.clock.resumeNoReply();
|
||||
this._clockPaused = false;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserContextDispatcher
|
||||
});
|
||||
118
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserDispatcher.js
generated
vendored
Normal file
118
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserDispatcher_exports = {};
|
||||
__export(browserDispatcher_exports, {
|
||||
BrowserDispatcher: () => BrowserDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(browserDispatcher_exports);
|
||||
var import_browser = require("../browser");
|
||||
var import_browserContextDispatcher = require("./browserContextDispatcher");
|
||||
var import_cdpSessionDispatcher = require("./cdpSessionDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_artifactDispatcher = require("./artifactDispatcher");
|
||||
class BrowserDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, browser, options = {}) {
|
||||
super(scope, browser, "Browser", { version: browser.version(), name: browser.options.name });
|
||||
this._type_Browser = true;
|
||||
this._isolatedContexts = /* @__PURE__ */ new Set();
|
||||
this._options = options;
|
||||
if (!options.isolateContexts) {
|
||||
this.addObjectListener(import_browser.Browser.Events.Context, (context) => this._dispatchEvent("context", { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, context) }));
|
||||
this.addObjectListener(import_browser.Browser.Events.Disconnected, () => this._didClose());
|
||||
if (browser._defaultContext)
|
||||
this._dispatchEvent("context", { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, browser._defaultContext) });
|
||||
for (const context of browser.contexts())
|
||||
this._dispatchEvent("context", { context: import_browserContextDispatcher.BrowserContextDispatcher.from(this, context) });
|
||||
}
|
||||
}
|
||||
_didClose() {
|
||||
this._dispatchEvent("close");
|
||||
this._dispose();
|
||||
}
|
||||
async newContext(params, progress) {
|
||||
if (params.recordVideo && this._object.attribution.playwright.options.isServer)
|
||||
params.recordVideo.dir = this._object.options.artifactsDir;
|
||||
if (!this._options.isolateContexts) {
|
||||
const context2 = await this._object.newContext(progress, params);
|
||||
const contextDispatcher2 = import_browserContextDispatcher.BrowserContextDispatcher.from(this, context2);
|
||||
return { context: contextDispatcher2 };
|
||||
}
|
||||
const context = await this._object.newContext(progress, params);
|
||||
this._isolatedContexts.add(context);
|
||||
context.on(import_browserContext.BrowserContext.Events.Close, () => this._isolatedContexts.delete(context));
|
||||
const contextDispatcher = import_browserContextDispatcher.BrowserContextDispatcher.from(this, context);
|
||||
this._dispatchEvent("context", { context: contextDispatcher });
|
||||
return { context: contextDispatcher };
|
||||
}
|
||||
async newContextForReuse(params, progress) {
|
||||
const context = await this._object.newContextForReuse(progress, params);
|
||||
const contextDispatcher = import_browserContextDispatcher.BrowserContextDispatcher.from(this, context);
|
||||
this._dispatchEvent("context", { context: contextDispatcher });
|
||||
return { context: contextDispatcher };
|
||||
}
|
||||
async disconnectFromReusedContext(params, progress) {
|
||||
const context = this._object.contextForReuse();
|
||||
const contextDispatcher = context ? this.connection.existingDispatcher(context) : void 0;
|
||||
if (contextDispatcher) {
|
||||
await contextDispatcher.stopPendingOperations(new Error(params.reason));
|
||||
contextDispatcher._dispose();
|
||||
}
|
||||
}
|
||||
async close(params, progress) {
|
||||
if (this._options.ignoreStopAndKill)
|
||||
return;
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._object.close(params);
|
||||
}
|
||||
async killForTests(params, progress) {
|
||||
if (this._options.ignoreStopAndKill)
|
||||
return;
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._object.killForTests();
|
||||
}
|
||||
async defaultUserAgentForTest() {
|
||||
return { userAgent: this._object.userAgent() };
|
||||
}
|
||||
async newBrowserCDPSession(params, progress) {
|
||||
if (!this._object.options.isChromium)
|
||||
throw new Error(`CDP session is only available in Chromium`);
|
||||
const crBrowser = this._object;
|
||||
return { session: new import_cdpSessionDispatcher.CDPSessionDispatcher(this, await crBrowser.newBrowserCDPSession()) };
|
||||
}
|
||||
async startTracing(params, progress) {
|
||||
if (!this._object.options.isChromium)
|
||||
throw new Error(`Tracing is only available in Chromium`);
|
||||
const crBrowser = this._object;
|
||||
await crBrowser.startTracing(params.page ? params.page._object : void 0, params);
|
||||
}
|
||||
async stopTracing(params, progress) {
|
||||
if (!this._object.options.isChromium)
|
||||
throw new Error(`Tracing is only available in Chromium`);
|
||||
const crBrowser = this._object;
|
||||
return { artifact: import_artifactDispatcher.ArtifactDispatcher.from(this, await crBrowser.stopTracing()) };
|
||||
}
|
||||
async cleanupContexts() {
|
||||
await Promise.all(Array.from(this._isolatedContexts).map((context) => context.close({ reason: "Global context cleanup (connection terminated)" })));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserDispatcher
|
||||
});
|
||||
64
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserTypeDispatcher.js
generated
vendored
Normal file
64
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/browserTypeDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserTypeDispatcher_exports = {};
|
||||
__export(browserTypeDispatcher_exports, {
|
||||
BrowserTypeDispatcher: () => BrowserTypeDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(browserTypeDispatcher_exports);
|
||||
var import_browserContextDispatcher = require("./browserContextDispatcher");
|
||||
var import_browserDispatcher = require("./browserDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
class BrowserTypeDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, browserType, denyLaunch) {
|
||||
super(scope, browserType, "BrowserType", {
|
||||
executablePath: browserType.executablePath(),
|
||||
name: browserType.name()
|
||||
});
|
||||
this._type_BrowserType = true;
|
||||
this._denyLaunch = denyLaunch;
|
||||
}
|
||||
async launch(params, progress) {
|
||||
if (this._denyLaunch)
|
||||
throw new Error(`Launching more browsers is not allowed.`);
|
||||
const browser = await this._object.launch(progress, params);
|
||||
return { browser: new import_browserDispatcher.BrowserDispatcher(this, browser) };
|
||||
}
|
||||
async launchPersistentContext(params, progress) {
|
||||
if (this._denyLaunch)
|
||||
throw new Error(`Launching more browsers is not allowed.`);
|
||||
const browserContext = await this._object.launchPersistentContext(progress, params.userDataDir, params);
|
||||
const browserDispatcher = new import_browserDispatcher.BrowserDispatcher(this, browserContext._browser);
|
||||
const contextDispatcher = import_browserContextDispatcher.BrowserContextDispatcher.from(browserDispatcher, browserContext);
|
||||
return { browser: browserDispatcher, context: contextDispatcher };
|
||||
}
|
||||
async connectOverCDP(params, progress) {
|
||||
if (this._denyLaunch)
|
||||
throw new Error(`Launching more browsers is not allowed.`);
|
||||
const browser = await this._object.connectOverCDP(progress, params.endpointURL, params);
|
||||
const browserDispatcher = new import_browserDispatcher.BrowserDispatcher(this, browser);
|
||||
return {
|
||||
browser: browserDispatcher,
|
||||
defaultContext: browser._defaultContext ? import_browserContextDispatcher.BrowserContextDispatcher.from(browserDispatcher, browser._defaultContext) : void 0
|
||||
};
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserTypeDispatcher
|
||||
});
|
||||
44
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/cdpSessionDispatcher.js
generated
vendored
Normal file
44
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/cdpSessionDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var cdpSessionDispatcher_exports = {};
|
||||
__export(cdpSessionDispatcher_exports, {
|
||||
CDPSessionDispatcher: () => CDPSessionDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(cdpSessionDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_crConnection = require("../chromium/crConnection");
|
||||
class CDPSessionDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, cdpSession) {
|
||||
super(scope, cdpSession, "CDPSession", {});
|
||||
this._type_CDPSession = true;
|
||||
this.addObjectListener(import_crConnection.CDPSession.Events.Event, ({ method, params }) => this._dispatchEvent("event", { method, params }));
|
||||
this.addObjectListener(import_crConnection.CDPSession.Events.Closed, () => this._dispose());
|
||||
}
|
||||
async send(params, progress) {
|
||||
return { result: await progress.race(this._object.send(params.method, params.params)) };
|
||||
}
|
||||
async detach(_, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._object.detach();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CDPSessionDispatcher
|
||||
});
|
||||
78
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/debugControllerDispatcher.js
generated
vendored
Normal file
78
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/debugControllerDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var debugControllerDispatcher_exports = {};
|
||||
__export(debugControllerDispatcher_exports, {
|
||||
DebugControllerDispatcher: () => DebugControllerDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(debugControllerDispatcher_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_debugController = require("../debugController");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
class DebugControllerDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(connection, debugController) {
|
||||
super(connection, debugController, "DebugController", {});
|
||||
this._type_DebugController = true;
|
||||
this._listeners = [
|
||||
import_utils.eventsHelper.addEventListener(this._object, import_debugController.DebugController.Events.StateChanged, (params) => {
|
||||
this._dispatchEvent("stateChanged", params);
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(this._object, import_debugController.DebugController.Events.InspectRequested, ({ selector, locator, ariaSnapshot }) => {
|
||||
this._dispatchEvent("inspectRequested", { selector, locator, ariaSnapshot });
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(this._object, import_debugController.DebugController.Events.SourceChanged, ({ text, header, footer, actions }) => {
|
||||
this._dispatchEvent("sourceChanged", { text, header, footer, actions });
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(this._object, import_debugController.DebugController.Events.Paused, ({ paused }) => {
|
||||
this._dispatchEvent("paused", { paused });
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(this._object, import_debugController.DebugController.Events.SetModeRequested, ({ mode }) => {
|
||||
this._dispatchEvent("setModeRequested", { mode });
|
||||
})
|
||||
];
|
||||
}
|
||||
async initialize(params, progress) {
|
||||
this._object.initialize(params.codegenId, params.sdkLanguage);
|
||||
}
|
||||
async setReportStateChanged(params, progress) {
|
||||
this._object.setReportStateChanged(params.enabled);
|
||||
}
|
||||
async setRecorderMode(params, progress) {
|
||||
await this._object.setRecorderMode(progress, params);
|
||||
}
|
||||
async highlight(params, progress) {
|
||||
await this._object.highlight(progress, params);
|
||||
}
|
||||
async hideHighlight(params, progress) {
|
||||
await this._object.hideHighlight(progress);
|
||||
}
|
||||
async resume(params, progress) {
|
||||
await this._object.resume(progress);
|
||||
}
|
||||
async kill(params, progress) {
|
||||
this._object.kill();
|
||||
}
|
||||
_onDispose() {
|
||||
import_utils.eventsHelper.removeEventListeners(this._listeners);
|
||||
this._object.dispose();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DebugControllerDispatcher
|
||||
});
|
||||
47
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/dialogDispatcher.js
generated
vendored
Normal file
47
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/dialogDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var dialogDispatcher_exports = {};
|
||||
__export(dialogDispatcher_exports, {
|
||||
DialogDispatcher: () => DialogDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(dialogDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_pageDispatcher = require("./pageDispatcher");
|
||||
class DialogDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, dialog) {
|
||||
const page = import_pageDispatcher.PageDispatcher.fromNullable(scope, dialog.page().initializedOrUndefined());
|
||||
super(page || scope, dialog, "Dialog", {
|
||||
page,
|
||||
type: dialog.type(),
|
||||
message: dialog.message(),
|
||||
defaultValue: dialog.defaultValue()
|
||||
});
|
||||
this._type_Dialog = true;
|
||||
}
|
||||
async accept(params, progress) {
|
||||
await progress.race(this._object.accept(params.promptText));
|
||||
}
|
||||
async dismiss(params, progress) {
|
||||
await progress.race(this._object.dismiss());
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DialogDispatcher
|
||||
});
|
||||
371
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/dispatcher.js
generated
vendored
Normal file
371
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/dispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var dispatcher_exports = {};
|
||||
__export(dispatcher_exports, {
|
||||
Dispatcher: () => Dispatcher,
|
||||
DispatcherConnection: () => DispatcherConnection,
|
||||
RootDispatcher: () => RootDispatcher,
|
||||
setMaxDispatchersForTest: () => setMaxDispatchersForTest
|
||||
});
|
||||
module.exports = __toCommonJS(dispatcher_exports);
|
||||
var import_events = require("events");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_validator = require("../../protocol/validator");
|
||||
var import_utils = require("../../utils");
|
||||
var import_debug = require("../utils/debug");
|
||||
var import_errors = require("../errors");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var import_protocolError = require("../protocolError");
|
||||
var import_callLog = require("../callLog");
|
||||
var import_protocolMetainfo = require("../../utils/isomorphic/protocolMetainfo");
|
||||
var import_progress = require("../progress");
|
||||
const metadataValidator = (0, import_validator.createMetadataValidator)();
|
||||
let maxDispatchersOverride;
|
||||
function setMaxDispatchersForTest(value) {
|
||||
maxDispatchersOverride = value;
|
||||
}
|
||||
function maxDispatchersForBucket(gcBucket) {
|
||||
return maxDispatchersOverride ?? {
|
||||
"JSHandle": 1e5,
|
||||
"ElementHandle": 1e5
|
||||
}[gcBucket] ?? 1e4;
|
||||
}
|
||||
class Dispatcher extends import_events.EventEmitter {
|
||||
constructor(parent, object, type, initializer, gcBucket) {
|
||||
super();
|
||||
this._dispatchers = /* @__PURE__ */ new Map();
|
||||
this._disposed = false;
|
||||
this._eventListeners = [];
|
||||
this._activeProgressControllers = /* @__PURE__ */ new Set();
|
||||
this.connection = parent instanceof DispatcherConnection ? parent : parent.connection;
|
||||
this._parent = parent instanceof DispatcherConnection ? void 0 : parent;
|
||||
const guid = object.guid;
|
||||
this._guid = guid;
|
||||
this._type = type;
|
||||
this._object = object;
|
||||
this._gcBucket = gcBucket ?? type;
|
||||
this.connection.registerDispatcher(this);
|
||||
if (this._parent) {
|
||||
(0, import_utils.assert)(!this._parent._dispatchers.has(guid));
|
||||
this._parent._dispatchers.set(guid, this);
|
||||
}
|
||||
if (this._parent)
|
||||
this.connection.sendCreate(this._parent, type, guid, initializer);
|
||||
this.connection.maybeDisposeStaleDispatchers(this._gcBucket);
|
||||
}
|
||||
parentScope() {
|
||||
return this._parent;
|
||||
}
|
||||
addObjectListener(eventName, handler) {
|
||||
this._eventListeners.push(import_eventsHelper.eventsHelper.addEventListener(this._object, eventName, handler));
|
||||
}
|
||||
adopt(child) {
|
||||
if (child._parent === this)
|
||||
return;
|
||||
const oldParent = child._parent;
|
||||
oldParent._dispatchers.delete(child._guid);
|
||||
this._dispatchers.set(child._guid, child);
|
||||
child._parent = this;
|
||||
this.connection.sendAdopt(this, child);
|
||||
}
|
||||
async _runCommand(callMetadata, method, validParams) {
|
||||
const controller = new import_progress.ProgressController(callMetadata, (message) => {
|
||||
const logName = this._object.logName || "api";
|
||||
import_utils.debugLogger.log(logName, message);
|
||||
this._object.instrumentation.onCallLog(this._object, callMetadata, logName, message);
|
||||
});
|
||||
this._activeProgressControllers.add(controller);
|
||||
try {
|
||||
return await controller.run((progress) => this[method](validParams, progress), validParams?.timeout);
|
||||
} finally {
|
||||
this._activeProgressControllers.delete(controller);
|
||||
}
|
||||
}
|
||||
_dispatchEvent(method, params) {
|
||||
if (this._disposed) {
|
||||
if ((0, import_debug.isUnderTest)())
|
||||
throw new Error(`${this._guid} is sending "${String(method)}" event after being disposed`);
|
||||
return;
|
||||
}
|
||||
this.connection.sendEvent(this, method, params);
|
||||
}
|
||||
_dispose(reason) {
|
||||
this._disposeRecursively(new import_errors.TargetClosedError());
|
||||
this.connection.sendDispose(this, reason);
|
||||
}
|
||||
_onDispose() {
|
||||
}
|
||||
async stopPendingOperations(error) {
|
||||
const controllers = [];
|
||||
const collect = (dispatcher) => {
|
||||
controllers.push(...dispatcher._activeProgressControllers);
|
||||
for (const child of [...dispatcher._dispatchers.values()])
|
||||
collect(child);
|
||||
};
|
||||
collect(this);
|
||||
await Promise.all(controllers.map((controller) => controller.abort(error)));
|
||||
}
|
||||
_disposeRecursively(error) {
|
||||
(0, import_utils.assert)(!this._disposed, `${this._guid} is disposed more than once`);
|
||||
for (const controller of this._activeProgressControllers) {
|
||||
if (!controller.metadata.potentiallyClosesScope)
|
||||
controller.abort(error).catch(() => {
|
||||
});
|
||||
}
|
||||
this._onDispose();
|
||||
this._disposed = true;
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
this._parent?._dispatchers.delete(this._guid);
|
||||
const list = this.connection._dispatchersByBucket.get(this._gcBucket);
|
||||
list?.delete(this._guid);
|
||||
this.connection._dispatcherByGuid.delete(this._guid);
|
||||
this.connection._dispatcherByObject.delete(this._object);
|
||||
for (const dispatcher of [...this._dispatchers.values()])
|
||||
dispatcher._disposeRecursively(error);
|
||||
this._dispatchers.clear();
|
||||
}
|
||||
_debugScopeState() {
|
||||
return {
|
||||
_guid: this._guid,
|
||||
objects: Array.from(this._dispatchers.values()).map((o) => o._debugScopeState())
|
||||
};
|
||||
}
|
||||
async waitForEventInfo() {
|
||||
}
|
||||
}
|
||||
class RootDispatcher extends Dispatcher {
|
||||
constructor(connection, createPlaywright) {
|
||||
super(connection, (0, import_instrumentation.createRootSdkObject)(), "Root", {});
|
||||
this.createPlaywright = createPlaywright;
|
||||
this._initialized = false;
|
||||
}
|
||||
async initialize(params, progress) {
|
||||
(0, import_utils.assert)(this.createPlaywright);
|
||||
(0, import_utils.assert)(!this._initialized);
|
||||
this._initialized = true;
|
||||
return {
|
||||
playwright: await this.createPlaywright(this, params)
|
||||
};
|
||||
}
|
||||
}
|
||||
class DispatcherConnection {
|
||||
constructor(isLocal) {
|
||||
this._dispatcherByGuid = /* @__PURE__ */ new Map();
|
||||
this._dispatcherByObject = /* @__PURE__ */ new Map();
|
||||
this._dispatchersByBucket = /* @__PURE__ */ new Map();
|
||||
this.onmessage = (message) => {
|
||||
};
|
||||
this._waitOperations = /* @__PURE__ */ new Map();
|
||||
this._isLocal = !!isLocal;
|
||||
}
|
||||
sendEvent(dispatcher, event, params) {
|
||||
const validator = (0, import_validator.findValidator)(dispatcher._type, event, "Event");
|
||||
params = validator(params, "", this._validatorToWireContext());
|
||||
this.onmessage({ guid: dispatcher._guid, method: event, params });
|
||||
}
|
||||
sendCreate(parent, type, guid, initializer) {
|
||||
const validator = (0, import_validator.findValidator)(type, "", "Initializer");
|
||||
initializer = validator(initializer, "", this._validatorToWireContext());
|
||||
this.onmessage({ guid: parent._guid, method: "__create__", params: { type, initializer, guid } });
|
||||
}
|
||||
sendAdopt(parent, dispatcher) {
|
||||
this.onmessage({ guid: parent._guid, method: "__adopt__", params: { guid: dispatcher._guid } });
|
||||
}
|
||||
sendDispose(dispatcher, reason) {
|
||||
this.onmessage({ guid: dispatcher._guid, method: "__dispose__", params: { reason } });
|
||||
}
|
||||
_validatorToWireContext() {
|
||||
return {
|
||||
tChannelImpl: this._tChannelImplToWire.bind(this),
|
||||
binary: this._isLocal ? "buffer" : "toBase64",
|
||||
isUnderTest: import_debug.isUnderTest
|
||||
};
|
||||
}
|
||||
_validatorFromWireContext() {
|
||||
return {
|
||||
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||
binary: this._isLocal ? "buffer" : "fromBase64",
|
||||
isUnderTest: import_debug.isUnderTest
|
||||
};
|
||||
}
|
||||
_tChannelImplFromWire(names, arg, path, context) {
|
||||
if (arg && typeof arg === "object" && typeof arg.guid === "string") {
|
||||
const guid = arg.guid;
|
||||
const dispatcher = this._dispatcherByGuid.get(guid);
|
||||
if (!dispatcher)
|
||||
throw new import_validator.ValidationError(`${path}: no object with guid ${guid}`);
|
||||
if (names !== "*" && !names.includes(dispatcher._type))
|
||||
throw new import_validator.ValidationError(`${path}: object with guid ${guid} has type ${dispatcher._type}, expected ${names.toString()}`);
|
||||
return dispatcher;
|
||||
}
|
||||
throw new import_validator.ValidationError(`${path}: expected guid for ${names.toString()}`);
|
||||
}
|
||||
_tChannelImplToWire(names, arg, path, context) {
|
||||
if (arg instanceof Dispatcher) {
|
||||
if (names !== "*" && !names.includes(arg._type))
|
||||
throw new import_validator.ValidationError(`${path}: dispatcher with guid ${arg._guid} has type ${arg._type}, expected ${names.toString()}`);
|
||||
return { guid: arg._guid };
|
||||
}
|
||||
throw new import_validator.ValidationError(`${path}: expected dispatcher ${names.toString()}`);
|
||||
}
|
||||
existingDispatcher(object) {
|
||||
return this._dispatcherByObject.get(object);
|
||||
}
|
||||
registerDispatcher(dispatcher) {
|
||||
(0, import_utils.assert)(!this._dispatcherByGuid.has(dispatcher._guid));
|
||||
this._dispatcherByGuid.set(dispatcher._guid, dispatcher);
|
||||
this._dispatcherByObject.set(dispatcher._object, dispatcher);
|
||||
let list = this._dispatchersByBucket.get(dispatcher._gcBucket);
|
||||
if (!list) {
|
||||
list = /* @__PURE__ */ new Set();
|
||||
this._dispatchersByBucket.set(dispatcher._gcBucket, list);
|
||||
}
|
||||
list.add(dispatcher._guid);
|
||||
}
|
||||
maybeDisposeStaleDispatchers(gcBucket) {
|
||||
const maxDispatchers = maxDispatchersForBucket(gcBucket);
|
||||
const list = this._dispatchersByBucket.get(gcBucket);
|
||||
if (!list || list.size <= maxDispatchers)
|
||||
return;
|
||||
const dispatchersArray = [...list];
|
||||
const disposeCount = maxDispatchers / 10 | 0;
|
||||
this._dispatchersByBucket.set(gcBucket, new Set(dispatchersArray.slice(disposeCount)));
|
||||
for (let i = 0; i < disposeCount; ++i) {
|
||||
const d = this._dispatcherByGuid.get(dispatchersArray[i]);
|
||||
if (!d)
|
||||
continue;
|
||||
d._dispose("gc");
|
||||
}
|
||||
}
|
||||
async dispatch(message) {
|
||||
const { id, guid, method, params, metadata } = message;
|
||||
const dispatcher = this._dispatcherByGuid.get(guid);
|
||||
if (!dispatcher) {
|
||||
this.onmessage({ id, error: (0, import_errors.serializeError)(new import_errors.TargetClosedError()) });
|
||||
return;
|
||||
}
|
||||
let validParams;
|
||||
let validMetadata;
|
||||
try {
|
||||
const validator = (0, import_validator.findValidator)(dispatcher._type, method, "Params");
|
||||
const validatorContext = this._validatorFromWireContext();
|
||||
validParams = validator(params, "", validatorContext);
|
||||
validMetadata = metadataValidator(metadata, "", validatorContext);
|
||||
if (typeof dispatcher[method] !== "function")
|
||||
throw new Error(`Mismatching dispatcher: "${dispatcher._type}" does not implement "${method}"`);
|
||||
} catch (e) {
|
||||
this.onmessage({ id, error: (0, import_errors.serializeError)(e) });
|
||||
return;
|
||||
}
|
||||
const metainfo = import_protocolMetainfo.methodMetainfo.get(dispatcher._type + "." + method);
|
||||
if (metainfo?.internal) {
|
||||
validMetadata.internal = true;
|
||||
}
|
||||
const sdkObject = dispatcher._object;
|
||||
const callMetadata = {
|
||||
id: `call@${id}`,
|
||||
location: validMetadata.location,
|
||||
title: validMetadata.title,
|
||||
internal: validMetadata.internal,
|
||||
stepId: validMetadata.stepId,
|
||||
objectId: sdkObject.guid,
|
||||
pageId: sdkObject.attribution?.page?.guid,
|
||||
frameId: sdkObject.attribution?.frame?.guid,
|
||||
startTime: (0, import_utils.monotonicTime)(),
|
||||
endTime: 0,
|
||||
type: dispatcher._type,
|
||||
method,
|
||||
params: params || {},
|
||||
log: []
|
||||
};
|
||||
if (params?.info?.waitId) {
|
||||
const info = params.info;
|
||||
switch (info.phase) {
|
||||
case "before": {
|
||||
this._waitOperations.set(info.waitId, callMetadata);
|
||||
await sdkObject.instrumentation.onBeforeCall(sdkObject, callMetadata);
|
||||
this.onmessage({ id });
|
||||
return;
|
||||
}
|
||||
case "log": {
|
||||
const originalMetadata = this._waitOperations.get(info.waitId);
|
||||
originalMetadata.log.push(info.message);
|
||||
sdkObject.instrumentation.onCallLog(sdkObject, originalMetadata, "api", info.message);
|
||||
this.onmessage({ id });
|
||||
return;
|
||||
}
|
||||
case "after": {
|
||||
const originalMetadata = this._waitOperations.get(info.waitId);
|
||||
originalMetadata.endTime = (0, import_utils.monotonicTime)();
|
||||
originalMetadata.error = info.error ? { error: { name: "Error", message: info.error } } : void 0;
|
||||
this._waitOperations.delete(info.waitId);
|
||||
await sdkObject.instrumentation.onAfterCall(sdkObject, originalMetadata);
|
||||
this.onmessage({ id });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
await sdkObject.instrumentation.onBeforeCall(sdkObject, callMetadata);
|
||||
const response = { id };
|
||||
try {
|
||||
if (this._dispatcherByGuid.get(guid) !== dispatcher)
|
||||
throw new import_errors.TargetClosedError(closeReason(sdkObject));
|
||||
const result = await dispatcher._runCommand(callMetadata, method, validParams);
|
||||
const validator = (0, import_validator.findValidator)(dispatcher._type, method, "Result");
|
||||
response.result = validator(result, "", this._validatorToWireContext());
|
||||
callMetadata.result = result;
|
||||
} catch (e) {
|
||||
if ((0, import_errors.isTargetClosedError)(e)) {
|
||||
const reason = closeReason(sdkObject);
|
||||
if (reason)
|
||||
(0, import_utils.rewriteErrorMessage)(e, reason);
|
||||
} else if ((0, import_protocolError.isProtocolError)(e)) {
|
||||
if (e.type === "closed")
|
||||
e = new import_errors.TargetClosedError(closeReason(sdkObject), e.browserLogMessage());
|
||||
else if (e.type === "crashed")
|
||||
(0, import_utils.rewriteErrorMessage)(e, "Target crashed " + e.browserLogMessage());
|
||||
}
|
||||
response.error = (0, import_errors.serializeError)(e);
|
||||
callMetadata.error = response.error;
|
||||
} finally {
|
||||
callMetadata.endTime = (0, import_utils.monotonicTime)();
|
||||
await sdkObject.instrumentation.onAfterCall(sdkObject, callMetadata);
|
||||
if (metainfo?.slowMo)
|
||||
await this._doSlowMo(sdkObject);
|
||||
}
|
||||
if (response.error)
|
||||
response.log = (0, import_callLog.compressCallLog)(callMetadata.log);
|
||||
this.onmessage(response);
|
||||
}
|
||||
async _doSlowMo(sdkObject) {
|
||||
const slowMo = sdkObject.attribution.browser?.options.slowMo;
|
||||
if (slowMo)
|
||||
await new Promise((f) => setTimeout(f, slowMo));
|
||||
}
|
||||
}
|
||||
function closeReason(sdkObject) {
|
||||
return sdkObject.attribution.page?.closeReason || sdkObject.attribution.context?._closeReason || sdkObject.attribution.browser?._closeReason;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Dispatcher,
|
||||
DispatcherConnection,
|
||||
RootDispatcher,
|
||||
setMaxDispatchersForTest
|
||||
});
|
||||
89
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/electronDispatcher.js
generated
vendored
Normal file
89
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/electronDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var electronDispatcher_exports = {};
|
||||
__export(electronDispatcher_exports, {
|
||||
ElectronApplicationDispatcher: () => ElectronApplicationDispatcher,
|
||||
ElectronDispatcher: () => ElectronDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(electronDispatcher_exports);
|
||||
var import_browserContextDispatcher = require("./browserContextDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
||||
var import_electron = require("../electron/electron");
|
||||
class ElectronDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, electron, denyLaunch) {
|
||||
super(scope, electron, "Electron", {});
|
||||
this._type_Electron = true;
|
||||
this._denyLaunch = denyLaunch;
|
||||
}
|
||||
async launch(params, progress) {
|
||||
if (this._denyLaunch)
|
||||
throw new Error(`Launching more browsers is not allowed.`);
|
||||
const electronApplication = await this._object.launch(progress, params);
|
||||
return { electronApplication: new ElectronApplicationDispatcher(this, electronApplication) };
|
||||
}
|
||||
}
|
||||
class ElectronApplicationDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, electronApplication) {
|
||||
super(scope, electronApplication, "ElectronApplication", {
|
||||
context: import_browserContextDispatcher.BrowserContextDispatcher.from(scope, electronApplication.context())
|
||||
});
|
||||
this._type_EventTarget = true;
|
||||
this._type_ElectronApplication = true;
|
||||
this._subscriptions = /* @__PURE__ */ new Set();
|
||||
this.addObjectListener(import_electron.ElectronApplication.Events.Close, () => {
|
||||
this._dispatchEvent("close");
|
||||
this._dispose();
|
||||
});
|
||||
this.addObjectListener(import_electron.ElectronApplication.Events.Console, (message) => {
|
||||
if (!this._subscriptions.has("console"))
|
||||
return;
|
||||
this._dispatchEvent("console", {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
args: message.args().map((a) => import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, a)),
|
||||
location: message.location()
|
||||
});
|
||||
});
|
||||
}
|
||||
async browserWindow(params, progress) {
|
||||
const handle = await progress.race(this._object.browserWindow(params.page.page()));
|
||||
return { handle: import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, handle) };
|
||||
}
|
||||
async evaluateExpression(params, progress) {
|
||||
const handle = await progress.race(this._object._nodeElectronHandlePromise);
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(handle.evaluateExpression(params.expression, { isFunction: params.isFunction }, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async evaluateExpressionHandle(params, progress) {
|
||||
const handle = await progress.race(this._object._nodeElectronHandlePromise);
|
||||
const result = await progress.race(handle.evaluateExpressionHandle(params.expression, { isFunction: params.isFunction }, (0, import_jsHandleDispatcher.parseArgument)(params.arg)));
|
||||
return { handle: import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, result) };
|
||||
}
|
||||
async updateSubscription(params, progress) {
|
||||
if (params.enabled)
|
||||
this._subscriptions.add(params.event);
|
||||
else
|
||||
this._subscriptions.delete(params.event);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ElectronApplicationDispatcher,
|
||||
ElectronDispatcher
|
||||
});
|
||||
181
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/elementHandlerDispatcher.js
generated
vendored
Normal file
181
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/elementHandlerDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var elementHandlerDispatcher_exports = {};
|
||||
__export(elementHandlerDispatcher_exports, {
|
||||
ElementHandleDispatcher: () => ElementHandleDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(elementHandlerDispatcher_exports);
|
||||
var import_browserContextDispatcher = require("./browserContextDispatcher");
|
||||
var import_frameDispatcher = require("./frameDispatcher");
|
||||
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
||||
class ElementHandleDispatcher extends import_jsHandleDispatcher.JSHandleDispatcher {
|
||||
constructor(scope, elementHandle) {
|
||||
super(scope, elementHandle);
|
||||
this._type_ElementHandle = true;
|
||||
this._elementHandle = elementHandle;
|
||||
}
|
||||
static from(scope, handle) {
|
||||
return scope.connection.existingDispatcher(handle) || new ElementHandleDispatcher(scope, handle);
|
||||
}
|
||||
static fromNullable(scope, handle) {
|
||||
if (!handle)
|
||||
return void 0;
|
||||
return scope.connection.existingDispatcher(handle) || new ElementHandleDispatcher(scope, handle);
|
||||
}
|
||||
static fromJSOrElementHandle(scope, handle) {
|
||||
const result = scope.connection.existingDispatcher(handle);
|
||||
if (result)
|
||||
return result;
|
||||
const elementHandle = handle.asElement();
|
||||
if (!elementHandle)
|
||||
return new import_jsHandleDispatcher.JSHandleDispatcher(scope, handle);
|
||||
return new ElementHandleDispatcher(scope, elementHandle);
|
||||
}
|
||||
async ownerFrame(params, progress) {
|
||||
const frame = await this._elementHandle.ownerFrame();
|
||||
return { frame: frame ? import_frameDispatcher.FrameDispatcher.from(this._browserContextDispatcher(), frame) : void 0 };
|
||||
}
|
||||
async contentFrame(params, progress) {
|
||||
const frame = await progress.race(this._elementHandle.contentFrame());
|
||||
return { frame: frame ? import_frameDispatcher.FrameDispatcher.from(this._browserContextDispatcher(), frame) : void 0 };
|
||||
}
|
||||
async getAttribute(params, progress) {
|
||||
const value = await this._elementHandle.getAttribute(progress, params.name);
|
||||
return { value: value === null ? void 0 : value };
|
||||
}
|
||||
async inputValue(params, progress) {
|
||||
const value = await this._elementHandle.inputValue(progress);
|
||||
return { value };
|
||||
}
|
||||
async textContent(params, progress) {
|
||||
const value = await this._elementHandle.textContent(progress);
|
||||
return { value: value === null ? void 0 : value };
|
||||
}
|
||||
async innerText(params, progress) {
|
||||
return { value: await this._elementHandle.innerText(progress) };
|
||||
}
|
||||
async innerHTML(params, progress) {
|
||||
return { value: await this._elementHandle.innerHTML(progress) };
|
||||
}
|
||||
async isChecked(params, progress) {
|
||||
return { value: await this._elementHandle.isChecked(progress) };
|
||||
}
|
||||
async isDisabled(params, progress) {
|
||||
return { value: await this._elementHandle.isDisabled(progress) };
|
||||
}
|
||||
async isEditable(params, progress) {
|
||||
return { value: await this._elementHandle.isEditable(progress) };
|
||||
}
|
||||
async isEnabled(params, progress) {
|
||||
return { value: await this._elementHandle.isEnabled(progress) };
|
||||
}
|
||||
async isHidden(params, progress) {
|
||||
return { value: await this._elementHandle.isHidden(progress) };
|
||||
}
|
||||
async isVisible(params, progress) {
|
||||
return { value: await this._elementHandle.isVisible(progress) };
|
||||
}
|
||||
async dispatchEvent(params, progress) {
|
||||
await this._elementHandle.dispatchEvent(progress, params.type, (0, import_jsHandleDispatcher.parseArgument)(params.eventInit));
|
||||
}
|
||||
async scrollIntoViewIfNeeded(params, progress) {
|
||||
await this._elementHandle.scrollIntoViewIfNeeded(progress);
|
||||
}
|
||||
async hover(params, progress) {
|
||||
return await this._elementHandle.hover(progress, params);
|
||||
}
|
||||
async click(params, progress) {
|
||||
return await this._elementHandle.click(progress, params);
|
||||
}
|
||||
async dblclick(params, progress) {
|
||||
return await this._elementHandle.dblclick(progress, params);
|
||||
}
|
||||
async tap(params, progress) {
|
||||
return await this._elementHandle.tap(progress, params);
|
||||
}
|
||||
async selectOption(params, progress) {
|
||||
const elements = (params.elements || []).map((e) => e._elementHandle);
|
||||
return { values: await this._elementHandle.selectOption(progress, elements, params.options || [], params) };
|
||||
}
|
||||
async fill(params, progress) {
|
||||
return await this._elementHandle.fill(progress, params.value, params);
|
||||
}
|
||||
async selectText(params, progress) {
|
||||
await this._elementHandle.selectText(progress, params);
|
||||
}
|
||||
async setInputFiles(params, progress) {
|
||||
return await this._elementHandle.setInputFiles(progress, params);
|
||||
}
|
||||
async focus(params, progress) {
|
||||
await this._elementHandle.focus(progress);
|
||||
}
|
||||
async type(params, progress) {
|
||||
return await this._elementHandle.type(progress, params.text, params);
|
||||
}
|
||||
async press(params, progress) {
|
||||
return await this._elementHandle.press(progress, params.key, params);
|
||||
}
|
||||
async check(params, progress) {
|
||||
return await this._elementHandle.check(progress, params);
|
||||
}
|
||||
async uncheck(params, progress) {
|
||||
return await this._elementHandle.uncheck(progress, params);
|
||||
}
|
||||
async boundingBox(params, progress) {
|
||||
const value = await progress.race(this._elementHandle.boundingBox());
|
||||
return { value: value || void 0 };
|
||||
}
|
||||
async screenshot(params, progress) {
|
||||
const mask = (params.mask || []).map(({ frame, selector }) => ({
|
||||
frame: frame._object,
|
||||
selector
|
||||
}));
|
||||
return { binary: await this._elementHandle.screenshot(progress, { ...params, mask }) };
|
||||
}
|
||||
async querySelector(params, progress) {
|
||||
const handle = await progress.race(this._elementHandle.querySelector(params.selector, params));
|
||||
return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), handle) };
|
||||
}
|
||||
async querySelectorAll(params, progress) {
|
||||
const elements = await progress.race(this._elementHandle.querySelectorAll(params.selector));
|
||||
return { elements: elements.map((e) => ElementHandleDispatcher.from(this.parentScope(), e)) };
|
||||
}
|
||||
async evalOnSelector(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._elementHandle.evalOnSelector(params.selector, !!params.strict, params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async evalOnSelectorAll(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._elementHandle.evalOnSelectorAll(params.selector, params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async waitForElementState(params, progress) {
|
||||
await this._elementHandle.waitForElementState(progress, params.state);
|
||||
}
|
||||
async waitForSelector(params, progress) {
|
||||
return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._elementHandle.waitForSelector(progress, params.selector, params)) };
|
||||
}
|
||||
_browserContextDispatcher() {
|
||||
const parentScope = this.parentScope().parentScope();
|
||||
if (parentScope instanceof import_browserContextDispatcher.BrowserContextDispatcher)
|
||||
return parentScope;
|
||||
return parentScope.parentScope();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ElementHandleDispatcher
|
||||
});
|
||||
227
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/frameDispatcher.js
generated
vendored
Normal file
227
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/frameDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var frameDispatcher_exports = {};
|
||||
__export(frameDispatcher_exports, {
|
||||
FrameDispatcher: () => FrameDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(frameDispatcher_exports);
|
||||
var import_frames = require("../frames");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_elementHandlerDispatcher = require("./elementHandlerDispatcher");
|
||||
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
||||
var import_networkDispatchers = require("./networkDispatchers");
|
||||
var import_networkDispatchers2 = require("./networkDispatchers");
|
||||
var import_ariaSnapshot = require("../../utils/isomorphic/ariaSnapshot");
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
class FrameDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, frame) {
|
||||
const gcBucket = frame._page.mainFrame() === frame ? "MainFrame" : "Frame";
|
||||
const pageDispatcher = scope.connection.existingDispatcher(frame._page);
|
||||
super(pageDispatcher || scope, frame, "Frame", {
|
||||
url: frame.url(),
|
||||
name: frame.name(),
|
||||
parentFrame: FrameDispatcher.fromNullable(scope, frame.parentFrame()),
|
||||
loadStates: Array.from(frame._firedLifecycleEvents)
|
||||
}, gcBucket);
|
||||
this._type_Frame = true;
|
||||
this._browserContextDispatcher = scope;
|
||||
this._frame = frame;
|
||||
this.addObjectListener(import_frames.Frame.Events.AddLifecycle, (lifecycleEvent) => {
|
||||
this._dispatchEvent("loadstate", { add: lifecycleEvent });
|
||||
});
|
||||
this.addObjectListener(import_frames.Frame.Events.RemoveLifecycle, (lifecycleEvent) => {
|
||||
this._dispatchEvent("loadstate", { remove: lifecycleEvent });
|
||||
});
|
||||
this.addObjectListener(import_frames.Frame.Events.InternalNavigation, (event) => {
|
||||
if (!event.isPublic)
|
||||
return;
|
||||
const params = { url: event.url, name: event.name, error: event.error ? event.error.message : void 0 };
|
||||
if (event.newDocument)
|
||||
params.newDocument = { request: import_networkDispatchers2.RequestDispatcher.fromNullable(this._browserContextDispatcher, event.newDocument.request || null) };
|
||||
this._dispatchEvent("navigated", params);
|
||||
});
|
||||
}
|
||||
static from(scope, frame) {
|
||||
const result = scope.connection.existingDispatcher(frame);
|
||||
return result || new FrameDispatcher(scope, frame);
|
||||
}
|
||||
static fromNullable(scope, frame) {
|
||||
if (!frame)
|
||||
return;
|
||||
return FrameDispatcher.from(scope, frame);
|
||||
}
|
||||
async goto(params, progress) {
|
||||
return { response: import_networkDispatchers.ResponseDispatcher.fromNullable(this._browserContextDispatcher, await this._frame.goto(progress, params.url, params)) };
|
||||
}
|
||||
async frameElement(params, progress) {
|
||||
return { element: import_elementHandlerDispatcher.ElementHandleDispatcher.from(this, await progress.race(this._frame.frameElement())) };
|
||||
}
|
||||
async evaluateExpression(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._frame.evaluateExpression(params.expression, { isFunction: params.isFunction }, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async evaluateExpressionHandle(params, progress) {
|
||||
return { handle: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this, await progress.race(this._frame.evaluateExpressionHandle(params.expression, { isFunction: params.isFunction }, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async waitForSelector(params, progress) {
|
||||
return { element: import_elementHandlerDispatcher.ElementHandleDispatcher.fromNullable(this, await this._frame.waitForSelector(progress, params.selector, true, params)) };
|
||||
}
|
||||
async dispatchEvent(params, progress) {
|
||||
return this._frame.dispatchEvent(progress, params.selector, params.type, (0, import_jsHandleDispatcher.parseArgument)(params.eventInit), params);
|
||||
}
|
||||
async evalOnSelector(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._frame.evalOnSelector(params.selector, !!params.strict, params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async evalOnSelectorAll(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._frame.evalOnSelectorAll(params.selector, params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async querySelector(params, progress) {
|
||||
return { element: import_elementHandlerDispatcher.ElementHandleDispatcher.fromNullable(this, await progress.race(this._frame.querySelector(params.selector, params))) };
|
||||
}
|
||||
async querySelectorAll(params, progress) {
|
||||
const elements = await progress.race(this._frame.querySelectorAll(params.selector));
|
||||
return { elements: elements.map((e) => import_elementHandlerDispatcher.ElementHandleDispatcher.from(this, e)) };
|
||||
}
|
||||
async queryCount(params, progress) {
|
||||
return { value: await progress.race(this._frame.queryCount(params.selector, params)) };
|
||||
}
|
||||
async content(params, progress) {
|
||||
return { value: await progress.race(this._frame.content()) };
|
||||
}
|
||||
async setContent(params, progress) {
|
||||
return await this._frame.setContent(progress, params.html, params);
|
||||
}
|
||||
async addScriptTag(params, progress) {
|
||||
return { element: import_elementHandlerDispatcher.ElementHandleDispatcher.from(this, await progress.race(this._frame.addScriptTag(params))) };
|
||||
}
|
||||
async addStyleTag(params, progress) {
|
||||
return { element: import_elementHandlerDispatcher.ElementHandleDispatcher.from(this, await progress.race(this._frame.addStyleTag(params))) };
|
||||
}
|
||||
async click(params, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
return await this._frame.click(progress, params.selector, params);
|
||||
}
|
||||
async dblclick(params, progress) {
|
||||
return await this._frame.dblclick(progress, params.selector, params);
|
||||
}
|
||||
async dragAndDrop(params, progress) {
|
||||
return await this._frame.dragAndDrop(progress, params.source, params.target, params);
|
||||
}
|
||||
async tap(params, progress) {
|
||||
return await this._frame.tap(progress, params.selector, params);
|
||||
}
|
||||
async fill(params, progress) {
|
||||
return await this._frame.fill(progress, params.selector, params.value, params);
|
||||
}
|
||||
async focus(params, progress) {
|
||||
await this._frame.focus(progress, params.selector, params);
|
||||
}
|
||||
async blur(params, progress) {
|
||||
await this._frame.blur(progress, params.selector, params);
|
||||
}
|
||||
async textContent(params, progress) {
|
||||
const value = await this._frame.textContent(progress, params.selector, params);
|
||||
return { value: value === null ? void 0 : value };
|
||||
}
|
||||
async innerText(params, progress) {
|
||||
return { value: await this._frame.innerText(progress, params.selector, params) };
|
||||
}
|
||||
async innerHTML(params, progress) {
|
||||
return { value: await this._frame.innerHTML(progress, params.selector, params) };
|
||||
}
|
||||
async resolveSelector(params, progress) {
|
||||
return await this._frame.resolveSelector(progress, params.selector);
|
||||
}
|
||||
async getAttribute(params, progress) {
|
||||
const value = await this._frame.getAttribute(progress, params.selector, params.name, params);
|
||||
return { value: value === null ? void 0 : value };
|
||||
}
|
||||
async inputValue(params, progress) {
|
||||
const value = await this._frame.inputValue(progress, params.selector, params);
|
||||
return { value };
|
||||
}
|
||||
async isChecked(params, progress) {
|
||||
return { value: await this._frame.isChecked(progress, params.selector, params) };
|
||||
}
|
||||
async isDisabled(params, progress) {
|
||||
return { value: await this._frame.isDisabled(progress, params.selector, params) };
|
||||
}
|
||||
async isEditable(params, progress) {
|
||||
return { value: await this._frame.isEditable(progress, params.selector, params) };
|
||||
}
|
||||
async isEnabled(params, progress) {
|
||||
return { value: await this._frame.isEnabled(progress, params.selector, params) };
|
||||
}
|
||||
async isHidden(params, progress) {
|
||||
return { value: await this._frame.isHidden(progress, params.selector, params) };
|
||||
}
|
||||
async isVisible(params, progress) {
|
||||
return { value: await this._frame.isVisible(progress, params.selector, params) };
|
||||
}
|
||||
async hover(params, progress) {
|
||||
return await this._frame.hover(progress, params.selector, params);
|
||||
}
|
||||
async selectOption(params, progress) {
|
||||
const elements = (params.elements || []).map((e) => e._elementHandle);
|
||||
return { values: await this._frame.selectOption(progress, params.selector, elements, params.options || [], params) };
|
||||
}
|
||||
async setInputFiles(params, progress) {
|
||||
return await this._frame.setInputFiles(progress, params.selector, params);
|
||||
}
|
||||
async type(params, progress) {
|
||||
return await this._frame.type(progress, params.selector, params.text, params);
|
||||
}
|
||||
async press(params, progress) {
|
||||
return await this._frame.press(progress, params.selector, params.key, params);
|
||||
}
|
||||
async check(params, progress) {
|
||||
return await this._frame.check(progress, params.selector, params);
|
||||
}
|
||||
async uncheck(params, progress) {
|
||||
return await this._frame.uncheck(progress, params.selector, params);
|
||||
}
|
||||
async waitForTimeout(params, progress) {
|
||||
return await this._frame.waitForTimeout(progress, params.waitTimeout);
|
||||
}
|
||||
async waitForFunction(params, progress) {
|
||||
return { handle: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this, await this._frame.waitForFunctionExpression(progress, params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg), params)) };
|
||||
}
|
||||
async title(params, progress) {
|
||||
return { value: await progress.race(this._frame.title()) };
|
||||
}
|
||||
async highlight(params, progress) {
|
||||
return await this._frame.highlight(progress, params.selector);
|
||||
}
|
||||
async expect(params, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
let expectedValue = params.expectedValue ? (0, import_jsHandleDispatcher.parseArgument)(params.expectedValue) : void 0;
|
||||
if (params.expression === "to.match.aria" && expectedValue)
|
||||
expectedValue = (0, import_ariaSnapshot.parseAriaSnapshotUnsafe)(import_utilsBundle.yaml, expectedValue);
|
||||
const result = await this._frame.expect(progress, params.selector, { ...params, expectedValue }, params.timeout);
|
||||
if (result.received !== void 0)
|
||||
result.received = (0, import_jsHandleDispatcher.serializeResult)(result.received);
|
||||
return result;
|
||||
}
|
||||
async ariaSnapshot(params, progress) {
|
||||
return { snapshot: await this._frame.ariaSnapshot(progress, params.selector) };
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FrameDispatcher
|
||||
});
|
||||
85
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/jsHandleDispatcher.js
generated
vendored
Normal file
85
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/jsHandleDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var jsHandleDispatcher_exports = {};
|
||||
__export(jsHandleDispatcher_exports, {
|
||||
JSHandleDispatcher: () => JSHandleDispatcher,
|
||||
parseArgument: () => parseArgument,
|
||||
parseValue: () => parseValue,
|
||||
serializeResult: () => serializeResult
|
||||
});
|
||||
module.exports = __toCommonJS(jsHandleDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_elementHandlerDispatcher = require("./elementHandlerDispatcher");
|
||||
var import_serializers = require("../../protocol/serializers");
|
||||
class JSHandleDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, jsHandle) {
|
||||
super(scope, jsHandle, jsHandle.asElement() ? "ElementHandle" : "JSHandle", {
|
||||
preview: jsHandle.toString()
|
||||
});
|
||||
this._type_JSHandle = true;
|
||||
jsHandle._setPreviewCallback((preview) => this._dispatchEvent("previewUpdated", { preview }));
|
||||
}
|
||||
static fromJSHandle(scope, handle) {
|
||||
return scope.connection.existingDispatcher(handle) || new JSHandleDispatcher(scope, handle);
|
||||
}
|
||||
async evaluateExpression(params, progress) {
|
||||
const jsHandle = await progress.race(this._object.evaluateExpression(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)));
|
||||
return { value: serializeResult(jsHandle) };
|
||||
}
|
||||
async evaluateExpressionHandle(params, progress) {
|
||||
const jsHandle = await progress.race(this._object.evaluateExpressionHandle(params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)));
|
||||
return { handle: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this.parentScope(), jsHandle) };
|
||||
}
|
||||
async getProperty(params, progress) {
|
||||
const jsHandle = await progress.race(this._object.getProperty(params.name));
|
||||
return { handle: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this.parentScope(), jsHandle) };
|
||||
}
|
||||
async getPropertyList(params, progress) {
|
||||
const map = await progress.race(this._object.getProperties());
|
||||
const properties = [];
|
||||
for (const [name, value] of map) {
|
||||
properties.push({ name, value: import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(this.parentScope(), value) });
|
||||
}
|
||||
return { properties };
|
||||
}
|
||||
async jsonValue(params, progress) {
|
||||
return { value: serializeResult(await progress.race(this._object.jsonValue())) };
|
||||
}
|
||||
async dispose(_, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
this._object.dispose();
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
function parseArgument(arg) {
|
||||
return (0, import_serializers.parseSerializedValue)(arg.value, arg.handles.map((a) => a._object));
|
||||
}
|
||||
function parseValue(v) {
|
||||
return (0, import_serializers.parseSerializedValue)(v, []);
|
||||
}
|
||||
function serializeResult(arg) {
|
||||
return (0, import_serializers.serializeValue)(arg, (value) => ({ fallThrough: value }));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JSHandleDispatcher,
|
||||
parseArgument,
|
||||
parseValue,
|
||||
serializeResult
|
||||
});
|
||||
58
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/jsonPipeDispatcher.js
generated
vendored
Normal file
58
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/jsonPipeDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var jsonPipeDispatcher_exports = {};
|
||||
__export(jsonPipeDispatcher_exports, {
|
||||
JsonPipeDispatcher: () => JsonPipeDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(jsonPipeDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
class JsonPipeDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope) {
|
||||
super(scope, new import_instrumentation.SdkObject(scope._object, "jsonPipe"), "JsonPipe", {});
|
||||
this._type_JsonPipe = true;
|
||||
}
|
||||
async send(params, progress) {
|
||||
this.emit("message", params.message);
|
||||
}
|
||||
async close(params, progress) {
|
||||
this.emit("close");
|
||||
if (!this._disposed) {
|
||||
this._dispatchEvent("closed", {});
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
dispatch(message) {
|
||||
if (!this._disposed)
|
||||
this._dispatchEvent("message", { message });
|
||||
}
|
||||
wasClosed(reason) {
|
||||
if (!this._disposed) {
|
||||
this._dispatchEvent("closed", { reason });
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JsonPipeDispatcher
|
||||
});
|
||||
149
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/localUtilsDispatcher.js
generated
vendored
Normal file
149
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/localUtilsDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var localUtilsDispatcher_exports = {};
|
||||
__export(localUtilsDispatcher_exports, {
|
||||
LocalUtilsDispatcher: () => LocalUtilsDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(localUtilsDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_instrumentation = require("../../server/instrumentation");
|
||||
var localUtils = __toESM(require("../localUtils"));
|
||||
var import_userAgent = require("../utils/userAgent");
|
||||
var import_deviceDescriptors = require("../deviceDescriptors");
|
||||
var import_jsonPipeDispatcher = require("../dispatchers/jsonPipeDispatcher");
|
||||
var import_socksInterceptor = require("../socksInterceptor");
|
||||
var import_transport = require("../transport");
|
||||
var import_network = require("../utils/network");
|
||||
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
||||
class LocalUtilsDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, playwright) {
|
||||
const localUtils2 = new import_instrumentation.SdkObject(playwright, "localUtils", "localUtils");
|
||||
localUtils2.logName = "browser";
|
||||
const deviceDescriptors = Object.entries(import_deviceDescriptors.deviceDescriptors).map(([name, descriptor]) => ({ name, descriptor }));
|
||||
super(scope, localUtils2, "LocalUtils", {
|
||||
deviceDescriptors
|
||||
});
|
||||
this._harBackends = /* @__PURE__ */ new Map();
|
||||
this._stackSessions = /* @__PURE__ */ new Map();
|
||||
this._type_LocalUtils = true;
|
||||
}
|
||||
async zip(params, progress) {
|
||||
return await localUtils.zip(progress, this._stackSessions, params);
|
||||
}
|
||||
async harOpen(params, progress) {
|
||||
return await localUtils.harOpen(progress, this._harBackends, params);
|
||||
}
|
||||
async harLookup(params, progress) {
|
||||
return await localUtils.harLookup(progress, this._harBackends, params);
|
||||
}
|
||||
async harClose(params, progress) {
|
||||
localUtils.harClose(this._harBackends, params);
|
||||
}
|
||||
async harUnzip(params, progress) {
|
||||
return await localUtils.harUnzip(progress, params);
|
||||
}
|
||||
async tracingStarted(params, progress) {
|
||||
return await localUtils.tracingStarted(progress, this._stackSessions, params);
|
||||
}
|
||||
async traceDiscarded(params, progress) {
|
||||
return await localUtils.traceDiscarded(progress, this._stackSessions, params);
|
||||
}
|
||||
async addStackToTracingNoReply(params, progress) {
|
||||
localUtils.addStackToTracingNoReply(this._stackSessions, params);
|
||||
}
|
||||
async connect(params, progress) {
|
||||
const wsHeaders = {
|
||||
"User-Agent": (0, import_userAgent.getUserAgent)(),
|
||||
"x-playwright-proxy": params.exposeNetwork ?? "",
|
||||
...params.headers
|
||||
};
|
||||
const wsEndpoint = await urlToWSEndpoint(progress, params.wsEndpoint);
|
||||
const transport = await import_transport.WebSocketTransport.connect(progress, wsEndpoint, { headers: wsHeaders, followRedirects: true, debugLogHeader: "x-playwright-debug-log" });
|
||||
const socksInterceptor = new import_socksInterceptor.SocksInterceptor(transport, params.exposeNetwork, params.socksProxyRedirectPortForTest);
|
||||
const pipe = new import_jsonPipeDispatcher.JsonPipeDispatcher(this);
|
||||
transport.onmessage = (json) => {
|
||||
if (socksInterceptor.interceptMessage(json))
|
||||
return;
|
||||
const cb = () => {
|
||||
try {
|
||||
pipe.dispatch(json);
|
||||
} catch (e) {
|
||||
transport.close();
|
||||
}
|
||||
};
|
||||
if (params.slowMo)
|
||||
setTimeout(cb, params.slowMo);
|
||||
else
|
||||
cb();
|
||||
};
|
||||
pipe.on("message", (message) => {
|
||||
transport.send(message);
|
||||
});
|
||||
transport.onclose = (reason) => {
|
||||
socksInterceptor?.cleanup();
|
||||
pipe.wasClosed(reason);
|
||||
};
|
||||
pipe.on("close", () => transport.close());
|
||||
return { pipe, headers: transport.headers };
|
||||
}
|
||||
async globToRegex(params, progress) {
|
||||
const regex = (0, import_urlMatch.resolveGlobToRegexPattern)(params.baseURL, params.glob, params.webSocketUrl);
|
||||
return { regex };
|
||||
}
|
||||
}
|
||||
async function urlToWSEndpoint(progress, endpointURL) {
|
||||
if (endpointURL.startsWith("ws"))
|
||||
return endpointURL;
|
||||
progress.log(`<ws preparing> retrieving websocket url from ${endpointURL}`);
|
||||
const fetchUrl = new URL(endpointURL);
|
||||
if (!fetchUrl.pathname.endsWith("/"))
|
||||
fetchUrl.pathname += "/";
|
||||
fetchUrl.pathname += "json";
|
||||
const json = await (0, import_network.fetchData)(progress, {
|
||||
url: fetchUrl.toString(),
|
||||
method: "GET",
|
||||
headers: { "User-Agent": (0, import_userAgent.getUserAgent)() }
|
||||
}, async (params, response) => {
|
||||
return new Error(`Unexpected status ${response.statusCode} when connecting to ${fetchUrl.toString()}.
|
||||
This does not look like a Playwright server, try connecting via ws://.`);
|
||||
});
|
||||
const wsUrl = new URL(endpointURL);
|
||||
let wsEndpointPath = JSON.parse(json).wsEndpointPath;
|
||||
if (wsEndpointPath.startsWith("/"))
|
||||
wsEndpointPath = wsEndpointPath.substring(1);
|
||||
if (!wsUrl.pathname.endsWith("/"))
|
||||
wsUrl.pathname += "/";
|
||||
wsUrl.pathname += wsEndpointPath;
|
||||
wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
||||
return wsUrl.toString();
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
LocalUtilsDispatcher
|
||||
});
|
||||
213
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/networkDispatchers.js
generated
vendored
Normal file
213
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/networkDispatchers.js
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var networkDispatchers_exports = {};
|
||||
__export(networkDispatchers_exports, {
|
||||
APIRequestContextDispatcher: () => APIRequestContextDispatcher,
|
||||
RequestDispatcher: () => RequestDispatcher,
|
||||
ResponseDispatcher: () => ResponseDispatcher,
|
||||
RouteDispatcher: () => RouteDispatcher,
|
||||
WebSocketDispatcher: () => WebSocketDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(networkDispatchers_exports);
|
||||
var import_network = require("../network");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_frameDispatcher = require("./frameDispatcher");
|
||||
var import_pageDispatcher = require("./pageDispatcher");
|
||||
var import_tracingDispatcher = require("./tracingDispatcher");
|
||||
var import_network2 = require("../network");
|
||||
class RequestDispatcher extends import_dispatcher.Dispatcher {
|
||||
static from(scope, request) {
|
||||
const result = scope.connection.existingDispatcher(request);
|
||||
return result || new RequestDispatcher(scope, request);
|
||||
}
|
||||
static fromNullable(scope, request) {
|
||||
return request ? RequestDispatcher.from(scope, request) : void 0;
|
||||
}
|
||||
constructor(scope, request) {
|
||||
const postData = request.postDataBuffer();
|
||||
const frame = request.frame();
|
||||
const page = request.frame()?._page;
|
||||
const pageDispatcher = page ? scope.connection.existingDispatcher(page) : null;
|
||||
const frameDispatcher = import_frameDispatcher.FrameDispatcher.fromNullable(scope, frame);
|
||||
super(pageDispatcher || frameDispatcher || scope, request, "Request", {
|
||||
frame: frameDispatcher,
|
||||
serviceWorker: import_pageDispatcher.WorkerDispatcher.fromNullable(scope, request.serviceWorker()),
|
||||
url: request.url(),
|
||||
resourceType: request.resourceType(),
|
||||
method: request.method(),
|
||||
postData: postData === null ? void 0 : postData,
|
||||
headers: request.headers(),
|
||||
isNavigationRequest: request.isNavigationRequest(),
|
||||
redirectedFrom: RequestDispatcher.fromNullable(scope, request.redirectedFrom()),
|
||||
hasResponse: !!request._existingResponse()
|
||||
});
|
||||
this._type_Request = true;
|
||||
this._browserContextDispatcher = scope;
|
||||
this.addObjectListener(import_network2.Request.Events.Response, () => this._dispatchEvent("response", {}));
|
||||
}
|
||||
async rawRequestHeaders(params, progress) {
|
||||
return { headers: await progress.race(this._object.rawRequestHeaders()) };
|
||||
}
|
||||
async response(params, progress) {
|
||||
return { response: ResponseDispatcher.fromNullable(this._browserContextDispatcher, await progress.race(this._object.response())) };
|
||||
}
|
||||
}
|
||||
class ResponseDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, response) {
|
||||
super(scope, response, "Response", {
|
||||
// TODO: responses in popups can point to non-reported requests.
|
||||
request: scope,
|
||||
url: response.url(),
|
||||
status: response.status(),
|
||||
statusText: response.statusText(),
|
||||
headers: response.headers(),
|
||||
timing: response.timing(),
|
||||
fromServiceWorker: response.fromServiceWorker()
|
||||
});
|
||||
this._type_Response = true;
|
||||
}
|
||||
static from(scope, response) {
|
||||
const result = scope.connection.existingDispatcher(response);
|
||||
const requestDispatcher = RequestDispatcher.from(scope, response.request());
|
||||
return result || new ResponseDispatcher(requestDispatcher, response);
|
||||
}
|
||||
static fromNullable(scope, response) {
|
||||
return response ? ResponseDispatcher.from(scope, response) : void 0;
|
||||
}
|
||||
async body(params, progress) {
|
||||
return { binary: await progress.race(this._object.body()) };
|
||||
}
|
||||
async securityDetails(params, progress) {
|
||||
return { value: await progress.race(this._object.securityDetails()) || void 0 };
|
||||
}
|
||||
async serverAddr(params, progress) {
|
||||
return { value: await progress.race(this._object.serverAddr()) || void 0 };
|
||||
}
|
||||
async rawResponseHeaders(params, progress) {
|
||||
return { headers: await progress.race(this._object.rawResponseHeaders()) };
|
||||
}
|
||||
async sizes(params, progress) {
|
||||
return { sizes: await progress.race(this._object.sizes()) };
|
||||
}
|
||||
}
|
||||
class RouteDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, route) {
|
||||
super(scope, route, "Route", {
|
||||
// Context route can point to a non-reported request, so we send the request in the initializer.
|
||||
request: scope
|
||||
});
|
||||
this._type_Route = true;
|
||||
this._handled = false;
|
||||
}
|
||||
_checkNotHandled() {
|
||||
if (this._handled)
|
||||
throw new Error("Route is already handled!");
|
||||
this._handled = true;
|
||||
}
|
||||
async continue(params, progress) {
|
||||
this._checkNotHandled();
|
||||
await this._object.continue({
|
||||
url: params.url,
|
||||
method: params.method,
|
||||
headers: params.headers,
|
||||
postData: params.postData,
|
||||
isFallback: params.isFallback
|
||||
});
|
||||
}
|
||||
async fulfill(params, progress) {
|
||||
this._checkNotHandled();
|
||||
await this._object.fulfill(params);
|
||||
}
|
||||
async abort(params, progress) {
|
||||
this._checkNotHandled();
|
||||
await this._object.abort(params.errorCode || "failed");
|
||||
}
|
||||
async redirectNavigationRequest(params, progress) {
|
||||
this._checkNotHandled();
|
||||
this._object.redirectNavigationRequest(params.url);
|
||||
}
|
||||
}
|
||||
class WebSocketDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, webSocket) {
|
||||
super(scope, webSocket, "WebSocket", {
|
||||
url: webSocket.url()
|
||||
});
|
||||
this._type_EventTarget = true;
|
||||
this._type_WebSocket = true;
|
||||
this.addObjectListener(import_network.WebSocket.Events.FrameSent, (event) => this._dispatchEvent("frameSent", event));
|
||||
this.addObjectListener(import_network.WebSocket.Events.FrameReceived, (event) => this._dispatchEvent("frameReceived", event));
|
||||
this.addObjectListener(import_network.WebSocket.Events.SocketError, (error) => this._dispatchEvent("socketError", { error }));
|
||||
this.addObjectListener(import_network.WebSocket.Events.Close, () => this._dispatchEvent("close", {}));
|
||||
}
|
||||
}
|
||||
class APIRequestContextDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(parentScope, request) {
|
||||
const tracing = import_tracingDispatcher.TracingDispatcher.from(parentScope, request.tracing());
|
||||
super(parentScope, request, "APIRequestContext", {
|
||||
tracing
|
||||
});
|
||||
this._type_APIRequestContext = true;
|
||||
this.adopt(tracing);
|
||||
}
|
||||
static from(scope, request) {
|
||||
const result = scope.connection.existingDispatcher(request);
|
||||
return result || new APIRequestContextDispatcher(scope, request);
|
||||
}
|
||||
static fromNullable(scope, request) {
|
||||
return request ? APIRequestContextDispatcher.from(scope, request) : void 0;
|
||||
}
|
||||
async storageState(params, progress) {
|
||||
return await this._object.storageState(progress, params.indexedDB);
|
||||
}
|
||||
async dispose(params, progress) {
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._object.dispose(params);
|
||||
this._dispose();
|
||||
}
|
||||
async fetch(params, progress) {
|
||||
const fetchResponse = await this._object.fetch(progress, params);
|
||||
return {
|
||||
response: {
|
||||
url: fetchResponse.url,
|
||||
status: fetchResponse.status,
|
||||
statusText: fetchResponse.statusText,
|
||||
headers: fetchResponse.headers,
|
||||
fetchUid: fetchResponse.fetchUid
|
||||
}
|
||||
};
|
||||
}
|
||||
async fetchResponseBody(params, progress) {
|
||||
return { binary: this._object.fetchResponses.get(params.fetchUid) };
|
||||
}
|
||||
async fetchLog(params, progress) {
|
||||
const log = this._object.fetchLog.get(params.fetchUid) || [];
|
||||
return { log };
|
||||
}
|
||||
async disposeAPIResponse(params, progress) {
|
||||
this._object.disposeResponse(params.fetchUid);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
APIRequestContextDispatcher,
|
||||
RequestDispatcher,
|
||||
ResponseDispatcher,
|
||||
RouteDispatcher,
|
||||
WebSocketDispatcher
|
||||
});
|
||||
389
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/pageDispatcher.js
generated
vendored
Normal file
389
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/pageDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var pageDispatcher_exports = {};
|
||||
__export(pageDispatcher_exports, {
|
||||
BindingCallDispatcher: () => BindingCallDispatcher,
|
||||
PageDispatcher: () => PageDispatcher,
|
||||
WorkerDispatcher: () => WorkerDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(pageDispatcher_exports);
|
||||
var import_page = require("../page");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_errors = require("../errors");
|
||||
var import_artifactDispatcher = require("./artifactDispatcher");
|
||||
var import_elementHandlerDispatcher = require("./elementHandlerDispatcher");
|
||||
var import_frameDispatcher = require("./frameDispatcher");
|
||||
var import_jsHandleDispatcher = require("./jsHandleDispatcher");
|
||||
var import_networkDispatchers = require("./networkDispatchers");
|
||||
var import_networkDispatchers2 = require("./networkDispatchers");
|
||||
var import_networkDispatchers3 = require("./networkDispatchers");
|
||||
var import_webSocketRouteDispatcher = require("./webSocketRouteDispatcher");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
||||
class PageDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(parentScope, page) {
|
||||
const mainFrame = import_frameDispatcher.FrameDispatcher.from(parentScope, page.mainFrame());
|
||||
super(parentScope, page, "Page", {
|
||||
mainFrame,
|
||||
viewportSize: page.emulatedSize()?.viewport,
|
||||
isClosed: page.isClosed(),
|
||||
opener: PageDispatcher.fromNullable(parentScope, page.opener())
|
||||
});
|
||||
this._type_EventTarget = true;
|
||||
this._type_Page = true;
|
||||
this._subscriptions = /* @__PURE__ */ new Set();
|
||||
this._webSocketInterceptionPatterns = [];
|
||||
this._bindings = [];
|
||||
this._initScripts = [];
|
||||
this._interceptionUrlMatchers = [];
|
||||
this._locatorHandlers = /* @__PURE__ */ new Set();
|
||||
this._jsCoverageActive = false;
|
||||
this._cssCoverageActive = false;
|
||||
this.adopt(mainFrame);
|
||||
this._page = page;
|
||||
this._requestInterceptor = (route, request) => {
|
||||
const matchesSome = this._interceptionUrlMatchers.some((urlMatch) => (0, import_urlMatch.urlMatches)(this._page.browserContext._options.baseURL, request.url(), urlMatch));
|
||||
if (!matchesSome) {
|
||||
route.continue({ isFallback: true }).catch(() => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._dispatchEvent("route", { route: new import_networkDispatchers3.RouteDispatcher(import_networkDispatchers.RequestDispatcher.from(this.parentScope(), request), route) });
|
||||
};
|
||||
this.addObjectListener(import_page.Page.Events.Close, () => {
|
||||
this._dispatchEvent("close");
|
||||
this._dispose();
|
||||
});
|
||||
this.addObjectListener(import_page.Page.Events.Crash, () => this._dispatchEvent("crash"));
|
||||
this.addObjectListener(import_page.Page.Events.Download, (download) => {
|
||||
this._dispatchEvent("download", { url: download.url, suggestedFilename: download.suggestedFilename(), artifact: import_artifactDispatcher.ArtifactDispatcher.from(parentScope, download.artifact) });
|
||||
});
|
||||
this.addObjectListener(import_page.Page.Events.EmulatedSizeChanged, () => this._dispatchEvent("viewportSizeChanged", { viewportSize: page.emulatedSize()?.viewport }));
|
||||
this.addObjectListener(import_page.Page.Events.FileChooser, (fileChooser) => this._dispatchEvent("fileChooser", {
|
||||
element: import_elementHandlerDispatcher.ElementHandleDispatcher.from(mainFrame, fileChooser.element()),
|
||||
isMultiple: fileChooser.isMultiple()
|
||||
}));
|
||||
this.addObjectListener(import_page.Page.Events.FrameAttached, (frame) => this._onFrameAttached(frame));
|
||||
this.addObjectListener(import_page.Page.Events.FrameDetached, (frame) => this._onFrameDetached(frame));
|
||||
this.addObjectListener(import_page.Page.Events.LocatorHandlerTriggered, (uid) => this._dispatchEvent("locatorHandlerTriggered", { uid }));
|
||||
this.addObjectListener(import_page.Page.Events.WebSocket, (webSocket) => this._dispatchEvent("webSocket", { webSocket: new import_networkDispatchers3.WebSocketDispatcher(this, webSocket) }));
|
||||
this.addObjectListener(import_page.Page.Events.Worker, (worker) => this._dispatchEvent("worker", { worker: new WorkerDispatcher(this, worker) }));
|
||||
this.addObjectListener(import_page.Page.Events.Video, (artifact) => this._dispatchEvent("video", { artifact: import_artifactDispatcher.ArtifactDispatcher.from(parentScope, artifact) }));
|
||||
if (page.video)
|
||||
this._dispatchEvent("video", { artifact: import_artifactDispatcher.ArtifactDispatcher.from(this.parentScope(), page.video) });
|
||||
const frames = page.frameManager.frames();
|
||||
for (let i = 1; i < frames.length; i++)
|
||||
this._onFrameAttached(frames[i]);
|
||||
}
|
||||
static from(parentScope, page) {
|
||||
return PageDispatcher.fromNullable(parentScope, page);
|
||||
}
|
||||
static fromNullable(parentScope, page) {
|
||||
if (!page)
|
||||
return void 0;
|
||||
const result = parentScope.connection.existingDispatcher(page);
|
||||
return result || new PageDispatcher(parentScope, page);
|
||||
}
|
||||
page() {
|
||||
return this._page;
|
||||
}
|
||||
async exposeBinding(params, progress) {
|
||||
const binding = await this._page.exposeBinding(progress, params.name, !!params.needsHandle, (source, ...args) => {
|
||||
if (this._disposed)
|
||||
return;
|
||||
const binding2 = new BindingCallDispatcher(this, params.name, !!params.needsHandle, source, args);
|
||||
this._dispatchEvent("bindingCall", { binding: binding2 });
|
||||
return binding2.promise();
|
||||
});
|
||||
this._bindings.push(binding);
|
||||
}
|
||||
async setExtraHTTPHeaders(params, progress) {
|
||||
await this._page.setExtraHTTPHeaders(progress, params.headers);
|
||||
}
|
||||
async reload(params, progress) {
|
||||
return { response: import_networkDispatchers2.ResponseDispatcher.fromNullable(this.parentScope(), await this._page.reload(progress, params)) };
|
||||
}
|
||||
async goBack(params, progress) {
|
||||
return { response: import_networkDispatchers2.ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goBack(progress, params)) };
|
||||
}
|
||||
async goForward(params, progress) {
|
||||
return { response: import_networkDispatchers2.ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goForward(progress, params)) };
|
||||
}
|
||||
async requestGC(params, progress) {
|
||||
await progress.race(this._page.requestGC());
|
||||
}
|
||||
async registerLocatorHandler(params, progress) {
|
||||
const uid = this._page.registerLocatorHandler(params.selector, params.noWaitAfter);
|
||||
this._locatorHandlers.add(uid);
|
||||
return { uid };
|
||||
}
|
||||
async resolveLocatorHandlerNoReply(params, progress) {
|
||||
this._page.resolveLocatorHandler(params.uid, params.remove);
|
||||
}
|
||||
async unregisterLocatorHandler(params, progress) {
|
||||
this._page.unregisterLocatorHandler(params.uid);
|
||||
this._locatorHandlers.delete(params.uid);
|
||||
}
|
||||
async emulateMedia(params, progress) {
|
||||
await this._page.emulateMedia(progress, {
|
||||
media: params.media,
|
||||
colorScheme: params.colorScheme,
|
||||
reducedMotion: params.reducedMotion,
|
||||
forcedColors: params.forcedColors,
|
||||
contrast: params.contrast
|
||||
});
|
||||
}
|
||||
async setViewportSize(params, progress) {
|
||||
await this._page.setViewportSize(progress, params.viewportSize);
|
||||
}
|
||||
async addInitScript(params, progress) {
|
||||
this._initScripts.push(await this._page.addInitScript(progress, params.source));
|
||||
}
|
||||
async setNetworkInterceptionPatterns(params, progress) {
|
||||
const hadMatchers = this._interceptionUrlMatchers.length > 0;
|
||||
if (!params.patterns.length) {
|
||||
if (hadMatchers)
|
||||
await this._page.removeRequestInterceptor(this._requestInterceptor);
|
||||
this._interceptionUrlMatchers = [];
|
||||
} else {
|
||||
this._interceptionUrlMatchers = params.patterns.map((pattern) => pattern.regexSource ? new RegExp(pattern.regexSource, pattern.regexFlags) : pattern.glob);
|
||||
if (!hadMatchers)
|
||||
await this._page.addRequestInterceptor(progress, this._requestInterceptor);
|
||||
}
|
||||
}
|
||||
async setWebSocketInterceptionPatterns(params, progress) {
|
||||
this._webSocketInterceptionPatterns = params.patterns;
|
||||
if (params.patterns.length && !this._routeWebSocketInitScript)
|
||||
this._routeWebSocketInitScript = await import_webSocketRouteDispatcher.WebSocketRouteDispatcher.install(progress, this.connection, this._page);
|
||||
}
|
||||
async expectScreenshot(params, progress) {
|
||||
const mask = (params.mask || []).map(({ frame, selector }) => ({
|
||||
frame: frame._object,
|
||||
selector
|
||||
}));
|
||||
const locator = params.locator ? {
|
||||
frame: params.locator.frame._object,
|
||||
selector: params.locator.selector
|
||||
} : void 0;
|
||||
return await this._page.expectScreenshot(progress, {
|
||||
...params,
|
||||
locator,
|
||||
mask
|
||||
});
|
||||
}
|
||||
async screenshot(params, progress) {
|
||||
const mask = (params.mask || []).map(({ frame, selector }) => ({
|
||||
frame: frame._object,
|
||||
selector
|
||||
}));
|
||||
return { binary: await this._page.screenshot(progress, { ...params, mask }) };
|
||||
}
|
||||
async close(params, progress) {
|
||||
if (!params.runBeforeUnload)
|
||||
progress.metadata.potentiallyClosesScope = true;
|
||||
await this._page.close(params);
|
||||
}
|
||||
async updateSubscription(params, progress) {
|
||||
if (params.event === "fileChooser")
|
||||
await this._page.setFileChooserInterceptedBy(params.enabled, this);
|
||||
if (params.enabled)
|
||||
this._subscriptions.add(params.event);
|
||||
else
|
||||
this._subscriptions.delete(params.event);
|
||||
}
|
||||
async keyboardDown(params, progress) {
|
||||
await this._page.keyboard.down(progress, params.key);
|
||||
}
|
||||
async keyboardUp(params, progress) {
|
||||
await this._page.keyboard.up(progress, params.key);
|
||||
}
|
||||
async keyboardInsertText(params, progress) {
|
||||
await this._page.keyboard.insertText(progress, params.text);
|
||||
}
|
||||
async keyboardType(params, progress) {
|
||||
await this._page.keyboard.type(progress, params.text, params);
|
||||
}
|
||||
async keyboardPress(params, progress) {
|
||||
await this._page.keyboard.press(progress, params.key, params);
|
||||
}
|
||||
async consoleMessages(params, progress) {
|
||||
this._subscriptions.add("console");
|
||||
return { messages: this._page.consoleMessages().map((message) => this.parentScope().serializeConsoleMessage(message, this)) };
|
||||
}
|
||||
async pageErrors(params, progress) {
|
||||
return { errors: this._page.pageErrors().map((error) => (0, import_errors.serializeError)(error)) };
|
||||
}
|
||||
async mouseMove(params, progress) {
|
||||
progress.metadata.point = { x: params.x, y: params.y };
|
||||
await this._page.mouse.move(progress, params.x, params.y, params);
|
||||
}
|
||||
async mouseDown(params, progress) {
|
||||
progress.metadata.point = this._page.mouse.currentPoint();
|
||||
await this._page.mouse.down(progress, params);
|
||||
}
|
||||
async mouseUp(params, progress) {
|
||||
progress.metadata.point = this._page.mouse.currentPoint();
|
||||
await this._page.mouse.up(progress, params);
|
||||
}
|
||||
async mouseClick(params, progress) {
|
||||
progress.metadata.point = { x: params.x, y: params.y };
|
||||
await this._page.mouse.click(progress, params.x, params.y, params);
|
||||
}
|
||||
async mouseWheel(params, progress) {
|
||||
await this._page.mouse.wheel(progress, params.deltaX, params.deltaY);
|
||||
}
|
||||
async touchscreenTap(params, progress) {
|
||||
progress.metadata.point = { x: params.x, y: params.y };
|
||||
await this._page.touchscreen.tap(progress, params.x, params.y);
|
||||
}
|
||||
async pdf(params, progress) {
|
||||
if (!this._page.pdf)
|
||||
throw new Error("PDF generation is only supported for Headless Chromium");
|
||||
const buffer = await progress.race(this._page.pdf(params));
|
||||
return { pdf: buffer };
|
||||
}
|
||||
async requests(params, progress) {
|
||||
this._subscriptions.add("request");
|
||||
return { requests: this._page.networkRequests().map((request) => import_networkDispatchers.RequestDispatcher.from(this.parentScope(), request)) };
|
||||
}
|
||||
async snapshotForAI(params, progress) {
|
||||
return await this._page.snapshotForAI(progress, params);
|
||||
}
|
||||
async bringToFront(params, progress) {
|
||||
await progress.race(this._page.bringToFront());
|
||||
}
|
||||
async startJSCoverage(params, progress) {
|
||||
const coverage = this._page.coverage;
|
||||
await coverage.startJSCoverage(progress, params);
|
||||
this._jsCoverageActive = true;
|
||||
}
|
||||
async stopJSCoverage(params, progress) {
|
||||
this._jsCoverageActive = false;
|
||||
const coverage = this._page.coverage;
|
||||
return await coverage.stopJSCoverage();
|
||||
}
|
||||
async startCSSCoverage(params, progress) {
|
||||
const coverage = this._page.coverage;
|
||||
await coverage.startCSSCoverage(progress, params);
|
||||
this._cssCoverageActive = true;
|
||||
}
|
||||
async stopCSSCoverage(params, progress) {
|
||||
this._cssCoverageActive = false;
|
||||
const coverage = this._page.coverage;
|
||||
return await coverage.stopCSSCoverage();
|
||||
}
|
||||
_onFrameAttached(frame) {
|
||||
this._dispatchEvent("frameAttached", { frame: import_frameDispatcher.FrameDispatcher.from(this.parentScope(), frame) });
|
||||
}
|
||||
_onFrameDetached(frame) {
|
||||
this._dispatchEvent("frameDetached", { frame: import_frameDispatcher.FrameDispatcher.from(this.parentScope(), frame) });
|
||||
}
|
||||
_onDispose() {
|
||||
if (this._page.isClosedOrClosingOrCrashed())
|
||||
return;
|
||||
this._interceptionUrlMatchers = [];
|
||||
this._page.removeRequestInterceptor(this._requestInterceptor).catch(() => {
|
||||
});
|
||||
this._page.removeExposedBindings(this._bindings).catch(() => {
|
||||
});
|
||||
this._bindings = [];
|
||||
this._page.removeInitScripts(this._initScripts).catch(() => {
|
||||
});
|
||||
this._initScripts = [];
|
||||
if (this._routeWebSocketInitScript)
|
||||
import_webSocketRouteDispatcher.WebSocketRouteDispatcher.uninstall(this.connection, this._page, this._routeWebSocketInitScript).catch(() => {
|
||||
});
|
||||
this._routeWebSocketInitScript = void 0;
|
||||
for (const uid of this._locatorHandlers)
|
||||
this._page.unregisterLocatorHandler(uid);
|
||||
this._locatorHandlers.clear();
|
||||
this._page.setFileChooserInterceptedBy(false, this).catch(() => {
|
||||
});
|
||||
if (this._jsCoverageActive)
|
||||
this._page.coverage.stopJSCoverage().catch(() => {
|
||||
});
|
||||
this._jsCoverageActive = false;
|
||||
if (this._cssCoverageActive)
|
||||
this._page.coverage.stopCSSCoverage().catch(() => {
|
||||
});
|
||||
this._cssCoverageActive = false;
|
||||
}
|
||||
}
|
||||
class WorkerDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, worker) {
|
||||
super(scope, worker, "Worker", {
|
||||
url: worker.url
|
||||
});
|
||||
this._type_Worker = true;
|
||||
this._type_EventTarget = true;
|
||||
this._subscriptions = /* @__PURE__ */ new Set();
|
||||
this.addObjectListener(import_page.Worker.Events.Close, () => this._dispatchEvent("close"));
|
||||
}
|
||||
static fromNullable(scope, worker) {
|
||||
if (!worker)
|
||||
return void 0;
|
||||
const result = scope.connection.existingDispatcher(worker);
|
||||
return result || new WorkerDispatcher(scope, worker);
|
||||
}
|
||||
async evaluateExpression(params, progress) {
|
||||
return { value: (0, import_jsHandleDispatcher.serializeResult)(await progress.race(this._object.evaluateExpression(params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async evaluateExpressionHandle(params, progress) {
|
||||
return { handle: import_jsHandleDispatcher.JSHandleDispatcher.fromJSHandle(this, await progress.race(this._object.evaluateExpressionHandle(params.expression, params.isFunction, (0, import_jsHandleDispatcher.parseArgument)(params.arg)))) };
|
||||
}
|
||||
async updateSubscription(params, progress) {
|
||||
if (params.enabled)
|
||||
this._subscriptions.add(params.event);
|
||||
else
|
||||
this._subscriptions.delete(params.event);
|
||||
}
|
||||
}
|
||||
class BindingCallDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, name, needsHandle, source, args) {
|
||||
const frameDispatcher = import_frameDispatcher.FrameDispatcher.from(scope.parentScope(), source.frame);
|
||||
super(scope, new import_instrumentation.SdkObject(scope._object, "bindingCall"), "BindingCall", {
|
||||
frame: frameDispatcher,
|
||||
name,
|
||||
args: needsHandle ? void 0 : args.map(import_jsHandleDispatcher.serializeResult),
|
||||
handle: needsHandle ? import_elementHandlerDispatcher.ElementHandleDispatcher.fromJSOrElementHandle(frameDispatcher, args[0]) : void 0
|
||||
});
|
||||
this._type_BindingCall = true;
|
||||
this._promise = new Promise((resolve, reject) => {
|
||||
this._resolve = resolve;
|
||||
this._reject = reject;
|
||||
});
|
||||
}
|
||||
promise() {
|
||||
return this._promise;
|
||||
}
|
||||
async resolve(params, progress) {
|
||||
this._resolve((0, import_jsHandleDispatcher.parseArgument)(params.result));
|
||||
this._dispose();
|
||||
}
|
||||
async reject(params, progress) {
|
||||
this._reject((0, import_errors.parseError)(params.error));
|
||||
this._dispose();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BindingCallDispatcher,
|
||||
PageDispatcher,
|
||||
WorkerDispatcher
|
||||
});
|
||||
108
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/playwrightDispatcher.js
generated
vendored
Normal file
108
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/playwrightDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var playwrightDispatcher_exports = {};
|
||||
__export(playwrightDispatcher_exports, {
|
||||
PlaywrightDispatcher: () => PlaywrightDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(playwrightDispatcher_exports);
|
||||
var import_socksProxy = require("../utils/socksProxy");
|
||||
var import_fetch = require("../fetch");
|
||||
var import_androidDispatcher = require("./androidDispatcher");
|
||||
var import_androidDispatcher2 = require("./androidDispatcher");
|
||||
var import_browserDispatcher = require("./browserDispatcher");
|
||||
var import_browserTypeDispatcher = require("./browserTypeDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_electronDispatcher = require("./electronDispatcher");
|
||||
var import_localUtilsDispatcher = require("./localUtilsDispatcher");
|
||||
var import_networkDispatchers = require("./networkDispatchers");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
class PlaywrightDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, playwright, options = {}) {
|
||||
const denyLaunch = options.denyLaunch ?? false;
|
||||
const chromium = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.chromium, denyLaunch);
|
||||
const firefox = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.firefox, denyLaunch);
|
||||
const webkit = new import_browserTypeDispatcher.BrowserTypeDispatcher(scope, playwright.webkit, denyLaunch);
|
||||
const android = new import_androidDispatcher.AndroidDispatcher(scope, playwright.android);
|
||||
const initializer = {
|
||||
chromium,
|
||||
firefox,
|
||||
webkit,
|
||||
android,
|
||||
electron: new import_electronDispatcher.ElectronDispatcher(scope, playwright.electron, denyLaunch),
|
||||
utils: playwright.options.isServer ? void 0 : new import_localUtilsDispatcher.LocalUtilsDispatcher(scope, playwright),
|
||||
socksSupport: options.socksProxy ? new SocksSupportDispatcher(scope, playwright, options.socksProxy) : void 0
|
||||
};
|
||||
let browserDispatcher;
|
||||
if (options.preLaunchedBrowser) {
|
||||
const browserTypeDispatcher = initializer[options.preLaunchedBrowser.options.name];
|
||||
browserDispatcher = new import_browserDispatcher.BrowserDispatcher(browserTypeDispatcher, options.preLaunchedBrowser, {
|
||||
ignoreStopAndKill: true,
|
||||
isolateContexts: !options.sharedBrowser
|
||||
});
|
||||
initializer.preLaunchedBrowser = browserDispatcher;
|
||||
}
|
||||
if (options.preLaunchedAndroidDevice)
|
||||
initializer.preConnectedAndroidDevice = new import_androidDispatcher2.AndroidDeviceDispatcher(android, options.preLaunchedAndroidDevice);
|
||||
super(scope, playwright, "Playwright", initializer);
|
||||
this._type_Playwright = true;
|
||||
this._browserDispatcher = browserDispatcher;
|
||||
}
|
||||
async newRequest(params, progress) {
|
||||
const request = new import_fetch.GlobalAPIRequestContext(this._object, params);
|
||||
return { request: import_networkDispatchers.APIRequestContextDispatcher.from(this.parentScope(), request) };
|
||||
}
|
||||
async cleanup() {
|
||||
await this._browserDispatcher?.cleanupContexts();
|
||||
}
|
||||
}
|
||||
class SocksSupportDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, parent, socksProxy) {
|
||||
super(scope, new import_instrumentation.SdkObject(parent, "socksSupport"), "SocksSupport", {});
|
||||
this._type_SocksSupport = true;
|
||||
this._socksProxy = socksProxy;
|
||||
this._socksListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(socksProxy, import_socksProxy.SocksProxy.Events.SocksRequested, (payload) => this._dispatchEvent("socksRequested", payload)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(socksProxy, import_socksProxy.SocksProxy.Events.SocksData, (payload) => this._dispatchEvent("socksData", payload)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(socksProxy, import_socksProxy.SocksProxy.Events.SocksClosed, (payload) => this._dispatchEvent("socksClosed", payload))
|
||||
];
|
||||
}
|
||||
async socksConnected(params, progress) {
|
||||
this._socksProxy?.socketConnected(params);
|
||||
}
|
||||
async socksFailed(params, progress) {
|
||||
this._socksProxy?.socketFailed(params);
|
||||
}
|
||||
async socksData(params, progress) {
|
||||
this._socksProxy?.sendSocketData(params);
|
||||
}
|
||||
async socksError(params, progress) {
|
||||
this._socksProxy?.sendSocketError(params);
|
||||
}
|
||||
async socksEnd(params, progress) {
|
||||
this._socksProxy?.sendSocketEnd(params);
|
||||
}
|
||||
_onDispose() {
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._socksListeners);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
PlaywrightDispatcher
|
||||
});
|
||||
67
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/streamDispatcher.js
generated
vendored
Normal file
67
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/streamDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var streamDispatcher_exports = {};
|
||||
__export(streamDispatcher_exports, {
|
||||
StreamDispatcher: () => StreamDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(streamDispatcher_exports);
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
class StreamSdkObject extends import_instrumentation.SdkObject {
|
||||
constructor(parent, stream) {
|
||||
super(parent, "stream");
|
||||
this.stream = stream;
|
||||
}
|
||||
}
|
||||
class StreamDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, stream) {
|
||||
super(scope, new StreamSdkObject(scope._object, stream), "Stream", {});
|
||||
this._type_Stream = true;
|
||||
this._ended = false;
|
||||
stream.once("end", () => this._ended = true);
|
||||
stream.once("error", () => this._ended = true);
|
||||
}
|
||||
async read(params, progress) {
|
||||
const stream = this._object.stream;
|
||||
if (this._ended)
|
||||
return { binary: Buffer.from("") };
|
||||
if (!stream.readableLength) {
|
||||
const readyPromise = new import_manualPromise.ManualPromise();
|
||||
const done = () => readyPromise.resolve();
|
||||
stream.on("readable", done);
|
||||
stream.on("end", done);
|
||||
stream.on("error", done);
|
||||
await progress.race(readyPromise).finally(() => {
|
||||
stream.off("readable", done);
|
||||
stream.off("end", done);
|
||||
stream.off("error", done);
|
||||
});
|
||||
}
|
||||
const buffer = stream.read(Math.min(stream.readableLength, params.size || stream.readableLength));
|
||||
return { binary: buffer || Buffer.from("") };
|
||||
}
|
||||
async close(params, progress) {
|
||||
this._object.stream.destroy();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
StreamDispatcher
|
||||
});
|
||||
68
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/tracingDispatcher.js
generated
vendored
Normal file
68
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/tracingDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tracingDispatcher_exports = {};
|
||||
__export(tracingDispatcher_exports, {
|
||||
TracingDispatcher: () => TracingDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(tracingDispatcher_exports);
|
||||
var import_artifactDispatcher = require("./artifactDispatcher");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
class TracingDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, tracing) {
|
||||
super(scope, tracing, "Tracing", {});
|
||||
this._type_Tracing = true;
|
||||
this._started = false;
|
||||
}
|
||||
static from(scope, tracing) {
|
||||
const result = scope.connection.existingDispatcher(tracing);
|
||||
return result || new TracingDispatcher(scope, tracing);
|
||||
}
|
||||
async tracingStart(params, progress) {
|
||||
this._object.start(params);
|
||||
this._started = true;
|
||||
}
|
||||
async tracingStartChunk(params, progress) {
|
||||
return await this._object.startChunk(progress, params);
|
||||
}
|
||||
async tracingGroup(params, progress) {
|
||||
const { name, location } = params;
|
||||
this._object.group(name, location, progress.metadata);
|
||||
}
|
||||
async tracingGroupEnd(params, progress) {
|
||||
this._object.groupEnd();
|
||||
}
|
||||
async tracingStopChunk(params, progress) {
|
||||
const { artifact, entries } = await this._object.stopChunk(progress, params);
|
||||
return { artifact: artifact ? import_artifactDispatcher.ArtifactDispatcher.from(this, artifact) : void 0, entries };
|
||||
}
|
||||
async tracingStop(params, progress) {
|
||||
this._started = false;
|
||||
await this._object.stop(progress);
|
||||
}
|
||||
_onDispose() {
|
||||
if (this._started)
|
||||
this._object.stopChunk(void 0, { mode: "discard" }).then(() => this._object.stop(void 0)).catch(() => {
|
||||
});
|
||||
this._started = false;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TracingDispatcher
|
||||
});
|
||||
165
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/webSocketRouteDispatcher.js
generated
vendored
Normal file
165
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/webSocketRouteDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var webSocketRouteDispatcher_exports = {};
|
||||
__export(webSocketRouteDispatcher_exports, {
|
||||
WebSocketRouteDispatcher: () => WebSocketRouteDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(webSocketRouteDispatcher_exports);
|
||||
var import_page = require("../page");
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_pageDispatcher = require("./pageDispatcher");
|
||||
var rawWebSocketMockSource = __toESM(require("../../generated/webSocketMockSource"));
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var import_urlMatch = require("../../utils/isomorphic/urlMatch");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
class WebSocketRouteDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, id, url, frame) {
|
||||
super(scope, new import_instrumentation.SdkObject(scope._object, "webSocketRoute"), "WebSocketRoute", { url });
|
||||
this._type_WebSocketRoute = true;
|
||||
this._id = id;
|
||||
this._frame = frame;
|
||||
this._eventListeners.push(
|
||||
// When the frame navigates or detaches, there will be no more communication
|
||||
// from the mock websocket, so pretend like it was closed.
|
||||
import_eventsHelper.eventsHelper.addEventListener(frame._page, import_page.Page.Events.InternalFrameNavigatedToNewDocument, (frame2) => {
|
||||
if (frame2 === this._frame)
|
||||
this._executionContextGone();
|
||||
}),
|
||||
import_eventsHelper.eventsHelper.addEventListener(frame._page, import_page.Page.Events.FrameDetached, (frame2) => {
|
||||
if (frame2 === this._frame)
|
||||
this._executionContextGone();
|
||||
}),
|
||||
import_eventsHelper.eventsHelper.addEventListener(frame._page, import_page.Page.Events.Close, () => this._executionContextGone()),
|
||||
import_eventsHelper.eventsHelper.addEventListener(frame._page, import_page.Page.Events.Crash, () => this._executionContextGone())
|
||||
);
|
||||
WebSocketRouteDispatcher._idToDispatcher.set(this._id, this);
|
||||
scope._dispatchEvent("webSocketRoute", { webSocketRoute: this });
|
||||
}
|
||||
static {
|
||||
this._idToDispatcher = /* @__PURE__ */ new Map();
|
||||
}
|
||||
static async install(progress, connection, target) {
|
||||
const context = target instanceof import_page.Page ? target.browserContext : target;
|
||||
let data = context.getBindingClient(kBindingName);
|
||||
if (data && data.connection !== connection)
|
||||
throw new Error("Another client is already routing WebSockets");
|
||||
if (!data) {
|
||||
data = { counter: 0, connection, binding: null };
|
||||
data.binding = await context.exposeBinding(progress, kBindingName, false, (source, payload) => {
|
||||
if (payload.type === "onCreate") {
|
||||
const contextDispatcher = connection.existingDispatcher(context);
|
||||
const pageDispatcher = contextDispatcher ? import_pageDispatcher.PageDispatcher.fromNullable(contextDispatcher, source.page) : void 0;
|
||||
let scope;
|
||||
if (pageDispatcher && matchesPattern(pageDispatcher, context._options.baseURL, payload.url))
|
||||
scope = pageDispatcher;
|
||||
else if (contextDispatcher && matchesPattern(contextDispatcher, context._options.baseURL, payload.url))
|
||||
scope = contextDispatcher;
|
||||
if (scope) {
|
||||
new WebSocketRouteDispatcher(scope, payload.id, payload.url, source.frame);
|
||||
} else {
|
||||
const request = { id: payload.id, type: "passthrough" };
|
||||
source.frame.evaluateExpression(`globalThis.__pwWebSocketDispatch(${JSON.stringify(request)})`).catch(() => {
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
const dispatcher = WebSocketRouteDispatcher._idToDispatcher.get(payload.id);
|
||||
if (payload.type === "onMessageFromPage")
|
||||
dispatcher?._dispatchEvent("messageFromPage", { message: payload.data.data, isBase64: payload.data.isBase64 });
|
||||
if (payload.type === "onMessageFromServer")
|
||||
dispatcher?._dispatchEvent("messageFromServer", { message: payload.data.data, isBase64: payload.data.isBase64 });
|
||||
if (payload.type === "onClosePage")
|
||||
dispatcher?._dispatchEvent("closePage", { code: payload.code, reason: payload.reason, wasClean: payload.wasClean });
|
||||
if (payload.type === "onCloseServer")
|
||||
dispatcher?._dispatchEvent("closeServer", { code: payload.code, reason: payload.reason, wasClean: payload.wasClean });
|
||||
}, data);
|
||||
}
|
||||
++data.counter;
|
||||
return await target.addInitScript(progress, `
|
||||
(() => {
|
||||
const module = {};
|
||||
${rawWebSocketMockSource.source}
|
||||
(module.exports.inject())(globalThis);
|
||||
})();
|
||||
`);
|
||||
}
|
||||
static async uninstall(connection, target, initScript) {
|
||||
const context = target instanceof import_page.Page ? target.browserContext : target;
|
||||
const data = context.getBindingClient(kBindingName);
|
||||
if (!data || data.connection !== connection)
|
||||
return;
|
||||
if (--data.counter <= 0)
|
||||
await context.removeExposedBindings([data.binding]);
|
||||
await target.removeInitScripts([initScript]);
|
||||
}
|
||||
async connect(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "connect" });
|
||||
}
|
||||
async ensureOpened(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "ensureOpened" });
|
||||
}
|
||||
async sendToPage(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "sendToPage", data: { data: params.message, isBase64: params.isBase64 } });
|
||||
}
|
||||
async sendToServer(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "sendToServer", data: { data: params.message, isBase64: params.isBase64 } });
|
||||
}
|
||||
async closePage(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "closePage", code: params.code, reason: params.reason, wasClean: params.wasClean });
|
||||
}
|
||||
async closeServer(params, progress) {
|
||||
await this._evaluateAPIRequest(progress, { id: this._id, type: "closeServer", code: params.code, reason: params.reason, wasClean: params.wasClean });
|
||||
}
|
||||
async _evaluateAPIRequest(progress, request) {
|
||||
await progress.race(this._frame.evaluateExpression(`globalThis.__pwWebSocketDispatch(${JSON.stringify(request)})`).catch(() => {
|
||||
}));
|
||||
}
|
||||
_onDispose() {
|
||||
WebSocketRouteDispatcher._idToDispatcher.delete(this._id);
|
||||
}
|
||||
_executionContextGone() {
|
||||
if (!this._disposed) {
|
||||
this._dispatchEvent("closePage", { wasClean: true });
|
||||
this._dispatchEvent("closeServer", { wasClean: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
function matchesPattern(dispatcher, baseURL, url) {
|
||||
for (const pattern of dispatcher._webSocketInterceptionPatterns || []) {
|
||||
const urlMatch = pattern.regexSource ? new RegExp(pattern.regexSource, pattern.regexFlags) : pattern.glob;
|
||||
if ((0, import_urlMatch.urlMatches)(baseURL, url, urlMatch, true))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const kBindingName = "__pwWebSocketBinding";
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
WebSocketRouteDispatcher
|
||||
});
|
||||
79
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/writableStreamDispatcher.js
generated
vendored
Normal file
79
.playwright-mcp/node_modules/playwright-core/lib/server/dispatchers/writableStreamDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var writableStreamDispatcher_exports = {};
|
||||
__export(writableStreamDispatcher_exports, {
|
||||
WritableStreamDispatcher: () => WritableStreamDispatcher
|
||||
});
|
||||
module.exports = __toCommonJS(writableStreamDispatcher_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_dispatcher = require("./dispatcher");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
class WritableStreamSdkObject extends import_instrumentation.SdkObject {
|
||||
constructor(parent, streamOrDirectory, lastModifiedMs) {
|
||||
super(parent, "stream");
|
||||
this.streamOrDirectory = streamOrDirectory;
|
||||
this.lastModifiedMs = lastModifiedMs;
|
||||
}
|
||||
}
|
||||
class WritableStreamDispatcher extends import_dispatcher.Dispatcher {
|
||||
constructor(scope, streamOrDirectory, lastModifiedMs) {
|
||||
super(scope, new WritableStreamSdkObject(scope._object, streamOrDirectory, lastModifiedMs), "WritableStream", {});
|
||||
this._type_WritableStream = true;
|
||||
}
|
||||
async write(params, progress) {
|
||||
if (typeof this._object.streamOrDirectory === "string")
|
||||
throw new Error("Cannot write to a directory");
|
||||
const stream = this._object.streamOrDirectory;
|
||||
await progress.race(new Promise((fulfill, reject) => {
|
||||
stream.write(params.binary, (error) => {
|
||||
if (error)
|
||||
reject(error);
|
||||
else
|
||||
fulfill();
|
||||
});
|
||||
}));
|
||||
}
|
||||
async close(params, progress) {
|
||||
if (typeof this._object.streamOrDirectory === "string")
|
||||
throw new Error("Cannot close a directory");
|
||||
const stream = this._object.streamOrDirectory;
|
||||
await progress.race(new Promise((fulfill) => stream.end(fulfill)));
|
||||
if (this._object.lastModifiedMs)
|
||||
await progress.race(import_fs.default.promises.utimes(this.path(), new Date(this._object.lastModifiedMs), new Date(this._object.lastModifiedMs)));
|
||||
}
|
||||
path() {
|
||||
if (typeof this._object.streamOrDirectory === "string")
|
||||
return this._object.streamOrDirectory;
|
||||
return this._object.streamOrDirectory.path;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
WritableStreamDispatcher
|
||||
});
|
||||
806
.playwright-mcp/node_modules/playwright-core/lib/server/dom.js
generated
vendored
Normal file
806
.playwright-mcp/node_modules/playwright-core/lib/server/dom.js
generated
vendored
Normal file
@@ -0,0 +1,806 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var dom_exports = {};
|
||||
__export(dom_exports, {
|
||||
ElementHandle: () => ElementHandle,
|
||||
FrameExecutionContext: () => FrameExecutionContext,
|
||||
NonRecoverableDOMError: () => NonRecoverableDOMError,
|
||||
assertDone: () => assertDone,
|
||||
isNonRecoverableDOMError: () => isNonRecoverableDOMError,
|
||||
kUnableToAdoptErrorMessage: () => kUnableToAdoptErrorMessage,
|
||||
throwElementIsNotAttached: () => throwElementIsNotAttached,
|
||||
throwRetargetableDOMError: () => throwRetargetableDOMError
|
||||
});
|
||||
module.exports = __toCommonJS(dom_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var js = __toESM(require("./javascript"));
|
||||
var import_utils = require("../utils");
|
||||
var import_fileUploadUtils = require("./fileUploadUtils");
|
||||
var rawInjectedScriptSource = __toESM(require("../generated/injectedScriptSource"));
|
||||
class NonRecoverableDOMError extends Error {
|
||||
}
|
||||
function isNonRecoverableDOMError(error) {
|
||||
return error instanceof NonRecoverableDOMError;
|
||||
}
|
||||
class FrameExecutionContext extends js.ExecutionContext {
|
||||
constructor(delegate, frame, world) {
|
||||
super(frame, delegate, world || "content-script");
|
||||
this.frame = frame;
|
||||
this.world = world;
|
||||
}
|
||||
adoptIfNeeded(handle) {
|
||||
if (handle instanceof ElementHandle && handle._context !== this)
|
||||
return this.frame._page.delegate.adoptElementHandle(handle, this);
|
||||
return null;
|
||||
}
|
||||
async evaluate(pageFunction, arg) {
|
||||
return js.evaluate(this, true, pageFunction, arg);
|
||||
}
|
||||
async evaluateHandle(pageFunction, arg) {
|
||||
return js.evaluate(this, false, pageFunction, arg);
|
||||
}
|
||||
async evaluateExpression(expression, options, arg) {
|
||||
return js.evaluateExpression(this, expression, { ...options, returnByValue: true }, arg);
|
||||
}
|
||||
async evaluateExpressionHandle(expression, options, arg) {
|
||||
return js.evaluateExpression(this, expression, { ...options, returnByValue: false }, arg);
|
||||
}
|
||||
injectedScript() {
|
||||
if (!this._injectedScriptPromise) {
|
||||
const customEngines = [];
|
||||
const selectorsRegistry = this.frame._page.browserContext.selectors();
|
||||
for (const [name, { source: source2 }] of selectorsRegistry._engines)
|
||||
customEngines.push({ name, source: `(${source2})` });
|
||||
const sdkLanguage = this.frame._page.browserContext._browser.sdkLanguage();
|
||||
const options = {
|
||||
isUnderTest: (0, import_utils.isUnderTest)(),
|
||||
sdkLanguage,
|
||||
testIdAttributeName: selectorsRegistry.testIdAttributeName(),
|
||||
stableRafCount: this.frame._page.delegate.rafCountForStablePosition(),
|
||||
browserName: this.frame._page.browserContext._browser.options.name,
|
||||
isUtilityWorld: this.world === "utility",
|
||||
customEngines
|
||||
};
|
||||
const source = `
|
||||
(() => {
|
||||
const module = {};
|
||||
${rawInjectedScriptSource.source}
|
||||
return new (module.exports.InjectedScript())(globalThis, ${JSON.stringify(options)});
|
||||
})();
|
||||
`;
|
||||
this._injectedScriptPromise = this.rawEvaluateHandle(source).then((handle) => {
|
||||
handle._setPreview("InjectedScript");
|
||||
return handle;
|
||||
});
|
||||
}
|
||||
return this._injectedScriptPromise;
|
||||
}
|
||||
}
|
||||
class ElementHandle extends js.JSHandle {
|
||||
constructor(context, objectId) {
|
||||
super(context, "node", void 0, objectId);
|
||||
this.__elementhandle = true;
|
||||
this._page = context.frame._page;
|
||||
this._frame = context.frame;
|
||||
this._initializePreview().catch((e) => {
|
||||
});
|
||||
}
|
||||
async _initializePreview() {
|
||||
const utility = await this._context.injectedScript();
|
||||
this._setPreview(await utility.evaluate((injected, e) => "JSHandle@" + injected.previewNode(e), this));
|
||||
}
|
||||
asElement() {
|
||||
return this;
|
||||
}
|
||||
async evaluateInUtility(pageFunction, arg) {
|
||||
try {
|
||||
const utility = await this._frame._utilityContext();
|
||||
return await utility.evaluate(pageFunction, [await utility.injectedScript(), this, arg]);
|
||||
} catch (e) {
|
||||
if (this._frame.isNonRetriableError(e))
|
||||
throw e;
|
||||
return "error:notconnected";
|
||||
}
|
||||
}
|
||||
async evaluateHandleInUtility(pageFunction, arg) {
|
||||
try {
|
||||
const utility = await this._frame._utilityContext();
|
||||
return await utility.evaluateHandle(pageFunction, [await utility.injectedScript(), this, arg]);
|
||||
} catch (e) {
|
||||
if (this._frame.isNonRetriableError(e))
|
||||
throw e;
|
||||
return "error:notconnected";
|
||||
}
|
||||
}
|
||||
async ownerFrame() {
|
||||
const frameId = await this._page.delegate.getOwnerFrame(this);
|
||||
if (!frameId)
|
||||
return null;
|
||||
const frame = this._page.frameManager.frame(frameId);
|
||||
if (frame)
|
||||
return frame;
|
||||
for (const page of this._page.browserContext.pages()) {
|
||||
const frame2 = page.frameManager.frame(frameId);
|
||||
if (frame2)
|
||||
return frame2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async isIframeElement() {
|
||||
return this.evaluateInUtility(([injected, node]) => node && (node.nodeName === "IFRAME" || node.nodeName === "FRAME"), {});
|
||||
}
|
||||
async contentFrame() {
|
||||
const isFrameElement = throwRetargetableDOMError(await this.isIframeElement());
|
||||
if (!isFrameElement)
|
||||
return null;
|
||||
return this._page.delegate.getContentFrame(this);
|
||||
}
|
||||
async getAttribute(progress, name) {
|
||||
return this._frame.getAttribute(progress, ":scope", name, {}, this);
|
||||
}
|
||||
async inputValue(progress) {
|
||||
return this._frame.inputValue(progress, ":scope", {}, this);
|
||||
}
|
||||
async textContent(progress) {
|
||||
return this._frame.textContent(progress, ":scope", {}, this);
|
||||
}
|
||||
async innerText(progress) {
|
||||
return this._frame.innerText(progress, ":scope", {}, this);
|
||||
}
|
||||
async innerHTML(progress) {
|
||||
return this._frame.innerHTML(progress, ":scope", {}, this);
|
||||
}
|
||||
async dispatchEvent(progress, type, eventInit = {}) {
|
||||
return this._frame.dispatchEvent(progress, ":scope", type, eventInit, {}, this);
|
||||
}
|
||||
async _scrollRectIntoViewIfNeeded(progress, rect) {
|
||||
return await progress.race(this._page.delegate.scrollRectIntoViewIfNeeded(this, rect));
|
||||
}
|
||||
async _waitAndScrollIntoViewIfNeeded(progress, waitForVisible) {
|
||||
const result = await this._retryAction(progress, "scroll into view", async () => {
|
||||
progress.log(` waiting for element to be stable`);
|
||||
const waitResult = await progress.race(this.evaluateInUtility(async ([injected, node, { waitForVisible: waitForVisible2 }]) => {
|
||||
return await injected.checkElementStates(node, waitForVisible2 ? ["visible", "stable"] : ["stable"]);
|
||||
}, { waitForVisible }));
|
||||
if (waitResult)
|
||||
return waitResult;
|
||||
return await this._scrollRectIntoViewIfNeeded(progress);
|
||||
}, {});
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async scrollIntoViewIfNeeded(progress) {
|
||||
await this._waitAndScrollIntoViewIfNeeded(
|
||||
progress,
|
||||
false
|
||||
/* waitForVisible */
|
||||
);
|
||||
}
|
||||
async _clickablePoint() {
|
||||
const intersectQuadWithViewport = (quad) => {
|
||||
return quad.map((point) => ({
|
||||
x: Math.min(Math.max(point.x, 0), metrics.width),
|
||||
y: Math.min(Math.max(point.y, 0), metrics.height)
|
||||
}));
|
||||
};
|
||||
const computeQuadArea = (quad) => {
|
||||
let area = 0;
|
||||
for (let i = 0; i < quad.length; ++i) {
|
||||
const p1 = quad[i];
|
||||
const p2 = quad[(i + 1) % quad.length];
|
||||
area += (p1.x * p2.y - p2.x * p1.y) / 2;
|
||||
}
|
||||
return Math.abs(area);
|
||||
};
|
||||
const [quads, metrics] = await Promise.all([
|
||||
this._page.delegate.getContentQuads(this),
|
||||
this._page.mainFrame()._utilityContext().then((utility) => utility.evaluate(() => ({ width: innerWidth, height: innerHeight })))
|
||||
]);
|
||||
if (quads === "error:notconnected")
|
||||
return quads;
|
||||
if (!quads || !quads.length)
|
||||
return "error:notvisible";
|
||||
const filtered = quads.map((quad) => intersectQuadWithViewport(quad)).filter((quad) => computeQuadArea(quad) > 0.99);
|
||||
if (!filtered.length)
|
||||
return "error:notinviewport";
|
||||
if (this._page.browserContext._browser.options.name === "firefox") {
|
||||
for (const quad of filtered) {
|
||||
const integerPoint = findIntegerPointInsideQuad(quad);
|
||||
if (integerPoint)
|
||||
return integerPoint;
|
||||
}
|
||||
}
|
||||
return quadMiddlePoint(filtered[0]);
|
||||
}
|
||||
async _offsetPoint(offset) {
|
||||
const [box, border] = await Promise.all([
|
||||
this.boundingBox(),
|
||||
this.evaluateInUtility(([injected, node]) => injected.getElementBorderWidth(node), {}).catch((e) => {
|
||||
})
|
||||
]);
|
||||
if (!box || !border)
|
||||
return "error:notvisible";
|
||||
if (border === "error:notconnected")
|
||||
return border;
|
||||
return {
|
||||
x: box.x + border.left + offset.x,
|
||||
y: box.y + border.top + offset.y
|
||||
};
|
||||
}
|
||||
async _retryAction(progress, actionName, action, options) {
|
||||
let retry = 0;
|
||||
const waitTime = [0, 20, 100, 100, 500];
|
||||
while (true) {
|
||||
if (retry) {
|
||||
progress.log(`retrying ${actionName} action${options.trial ? " (trial run)" : ""}`);
|
||||
const timeout = waitTime[Math.min(retry - 1, waitTime.length - 1)];
|
||||
if (timeout) {
|
||||
progress.log(` waiting ${timeout}ms`);
|
||||
const result2 = await progress.race(this.evaluateInUtility(([injected, node, timeout2]) => new Promise((f) => setTimeout(f, timeout2)), timeout));
|
||||
if (result2 === "error:notconnected")
|
||||
return result2;
|
||||
}
|
||||
} else {
|
||||
progress.log(`attempting ${actionName} action${options.trial ? " (trial run)" : ""}`);
|
||||
}
|
||||
if (!options.skipActionPreChecks && !options.force)
|
||||
await this._frame._page.performActionPreChecks(progress);
|
||||
const result = await action(retry);
|
||||
++retry;
|
||||
if (result === "error:notvisible") {
|
||||
if (options.force)
|
||||
throw new NonRecoverableDOMError("Element is not visible");
|
||||
progress.log(" element is not visible");
|
||||
continue;
|
||||
}
|
||||
if (result === "error:notinviewport") {
|
||||
if (options.force)
|
||||
throw new NonRecoverableDOMError("Element is outside of the viewport");
|
||||
progress.log(" element is outside of the viewport");
|
||||
continue;
|
||||
}
|
||||
if (result === "error:optionsnotfound") {
|
||||
progress.log(" did not find some options");
|
||||
continue;
|
||||
}
|
||||
if (result === "error:optionnotenabled") {
|
||||
progress.log(" option being selected is not enabled");
|
||||
continue;
|
||||
}
|
||||
if (typeof result === "object" && "hitTargetDescription" in result) {
|
||||
progress.log(` ${result.hitTargetDescription} intercepts pointer events`);
|
||||
continue;
|
||||
}
|
||||
if (typeof result === "object" && "missingState" in result) {
|
||||
progress.log(` element is not ${result.missingState}`);
|
||||
continue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
async _retryPointerAction(progress, actionName, waitForEnabled, action, options) {
|
||||
const skipActionPreChecks = actionName === "move and up";
|
||||
return await this._retryAction(progress, actionName, async (retry) => {
|
||||
const scrollOptions = [
|
||||
void 0,
|
||||
{ block: "end", inline: "end" },
|
||||
{ block: "center", inline: "center" },
|
||||
{ block: "start", inline: "start" }
|
||||
];
|
||||
const forceScrollOptions = scrollOptions[retry % scrollOptions.length];
|
||||
return await this._performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options);
|
||||
}, { ...options, skipActionPreChecks });
|
||||
}
|
||||
async _performPointerAction(progress, actionName, waitForEnabled, action, forceScrollOptions, options) {
|
||||
const { force = false, position } = options;
|
||||
const doScrollIntoView = async () => {
|
||||
if (forceScrollOptions) {
|
||||
return await this.evaluateInUtility(([injected, node, options2]) => {
|
||||
if (node.nodeType === 1)
|
||||
node.scrollIntoView(options2);
|
||||
return "done";
|
||||
}, forceScrollOptions);
|
||||
}
|
||||
return await this._scrollRectIntoViewIfNeeded(progress, position ? { x: position.x, y: position.y, width: 0, height: 0 } : void 0);
|
||||
};
|
||||
if (this._frame.parentFrame()) {
|
||||
await progress.race(doScrollIntoView().catch(() => {
|
||||
}));
|
||||
}
|
||||
if (options.__testHookBeforeStable)
|
||||
await progress.race(options.__testHookBeforeStable());
|
||||
if (!force) {
|
||||
const elementStates = waitForEnabled ? ["visible", "enabled", "stable"] : ["visible", "stable"];
|
||||
progress.log(` waiting for element to be ${waitForEnabled ? "visible, enabled and stable" : "visible and stable"}`);
|
||||
const result = await progress.race(this.evaluateInUtility(async ([injected, node, { elementStates: elementStates2 }]) => {
|
||||
return await injected.checkElementStates(node, elementStates2);
|
||||
}, { elementStates }));
|
||||
if (result)
|
||||
return result;
|
||||
progress.log(` element is ${waitForEnabled ? "visible, enabled and stable" : "visible and stable"}`);
|
||||
}
|
||||
if (options.__testHookAfterStable)
|
||||
await progress.race(options.__testHookAfterStable());
|
||||
progress.log(" scrolling into view if needed");
|
||||
const scrolled = await progress.race(doScrollIntoView());
|
||||
if (scrolled !== "done")
|
||||
return scrolled;
|
||||
progress.log(" done scrolling");
|
||||
const maybePoint = position ? await progress.race(this._offsetPoint(position)) : await progress.race(this._clickablePoint());
|
||||
if (typeof maybePoint === "string")
|
||||
return maybePoint;
|
||||
const point = roundPoint(maybePoint);
|
||||
progress.metadata.point = point;
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
let hitTargetInterceptionHandle;
|
||||
if (force) {
|
||||
progress.log(` forcing action`);
|
||||
} else {
|
||||
if (options.__testHookBeforeHitTarget)
|
||||
await progress.race(options.__testHookBeforeHitTarget());
|
||||
const frameCheckResult = await progress.race(this._checkFrameIsHitTarget(point));
|
||||
if (frameCheckResult === "error:notconnected" || "hitTargetDescription" in frameCheckResult)
|
||||
return frameCheckResult;
|
||||
const hitPoint = frameCheckResult.framePoint;
|
||||
const actionType = actionName === "move and up" ? "drag" : actionName === "hover" || actionName === "tap" ? actionName : "mouse";
|
||||
const handle = await progress.race(this.evaluateHandleInUtility(([injected, node, { actionType: actionType2, hitPoint: hitPoint2, trial }]) => injected.setupHitTargetInterceptor(node, actionType2, hitPoint2, trial), { actionType, hitPoint, trial: !!options.trial }));
|
||||
if (handle === "error:notconnected")
|
||||
return handle;
|
||||
if (!handle._objectId) {
|
||||
const error = handle.rawValue();
|
||||
if (error === "error:notconnected")
|
||||
return error;
|
||||
return { hitTargetDescription: error };
|
||||
}
|
||||
hitTargetInterceptionHandle = handle;
|
||||
}
|
||||
const actionResult = await this._page.frameManager.waitForSignalsCreatedBy(progress, options.waitAfter === true, async () => {
|
||||
if (options.__testHookBeforePointerAction)
|
||||
await progress.race(options.__testHookBeforePointerAction());
|
||||
let restoreModifiers;
|
||||
if (options && options.modifiers)
|
||||
restoreModifiers = await this._page.keyboard.ensureModifiers(progress, options.modifiers);
|
||||
progress.log(` performing ${actionName} action`);
|
||||
await action(point);
|
||||
if (restoreModifiers)
|
||||
await this._page.keyboard.ensureModifiers(progress, restoreModifiers);
|
||||
if (hitTargetInterceptionHandle) {
|
||||
const stopHitTargetInterception = this._frame.raceAgainstEvaluationStallingEvents(() => {
|
||||
return hitTargetInterceptionHandle.evaluate((h) => h.stop());
|
||||
}).catch((e) => "done").finally(() => {
|
||||
hitTargetInterceptionHandle?.dispose();
|
||||
});
|
||||
if (options.waitAfter !== false) {
|
||||
const hitTargetResult = await progress.race(stopHitTargetInterception);
|
||||
if (hitTargetResult !== "done")
|
||||
return hitTargetResult;
|
||||
}
|
||||
}
|
||||
progress.log(` ${options.trial ? "trial " : ""}${actionName} action done`);
|
||||
progress.log(" waiting for scheduled navigations to finish");
|
||||
if (options.__testHookAfterPointerAction)
|
||||
await progress.race(options.__testHookAfterPointerAction());
|
||||
return "done";
|
||||
}).finally(() => {
|
||||
const stopPromise = hitTargetInterceptionHandle?.evaluate((h) => h.stop()).catch(() => {
|
||||
});
|
||||
stopPromise?.then(() => hitTargetInterceptionHandle?.dispose());
|
||||
});
|
||||
if (actionResult !== "done")
|
||||
return actionResult;
|
||||
progress.log(" navigations have finished");
|
||||
return "done";
|
||||
}
|
||||
async _markAsTargetElement(progress) {
|
||||
if (!progress.metadata.id)
|
||||
return;
|
||||
await progress.race(this.evaluateInUtility(([injected, node, callId]) => {
|
||||
if (node.nodeType === 1)
|
||||
injected.markTargetElements(/* @__PURE__ */ new Set([node]), callId);
|
||||
}, progress.metadata.id));
|
||||
}
|
||||
async hover(progress, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._hover(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
_hover(progress, options) {
|
||||
return this._retryPointerAction(progress, "hover", false, (point) => this._page.mouse.move(progress, point.x, point.y), { ...options, waitAfter: "disabled" });
|
||||
}
|
||||
async click(progress, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._click(progress, { ...options, waitAfter: !options.noWaitAfter });
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
_click(progress, options) {
|
||||
return this._retryPointerAction(progress, "click", true, (point) => this._page.mouse.click(progress, point.x, point.y, options), options);
|
||||
}
|
||||
async dblclick(progress, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._dblclick(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
_dblclick(progress, options) {
|
||||
return this._retryPointerAction(progress, "dblclick", true, (point) => this._page.mouse.click(progress, point.x, point.y, { ...options, clickCount: 2 }), { ...options, waitAfter: "disabled" });
|
||||
}
|
||||
async tap(progress, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._tap(progress, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
_tap(progress, options) {
|
||||
return this._retryPointerAction(progress, "tap", true, (point) => this._page.touchscreen.tap(progress, point.x, point.y), { ...options, waitAfter: "disabled" });
|
||||
}
|
||||
async selectOption(progress, elements, values, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._selectOption(progress, elements, values, options);
|
||||
return throwRetargetableDOMError(result);
|
||||
}
|
||||
async _selectOption(progress, elements, values, options) {
|
||||
let resultingOptions = [];
|
||||
const result = await this._retryAction(progress, "select option", async () => {
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
if (!options.force)
|
||||
progress.log(` waiting for element to be visible and enabled`);
|
||||
const optionsToSelect = [...elements, ...values];
|
||||
const result2 = await progress.race(this.evaluateInUtility(async ([injected, node, { optionsToSelect: optionsToSelect2, force }]) => {
|
||||
if (!force) {
|
||||
const checkResult = await injected.checkElementStates(node, ["visible", "enabled"]);
|
||||
if (checkResult)
|
||||
return checkResult;
|
||||
}
|
||||
return injected.selectOptions(node, optionsToSelect2);
|
||||
}, { optionsToSelect, force: options.force }));
|
||||
if (Array.isArray(result2)) {
|
||||
progress.log(" selected specified option(s)");
|
||||
resultingOptions = result2;
|
||||
return "done";
|
||||
}
|
||||
return result2;
|
||||
}, options);
|
||||
if (result === "error:notconnected")
|
||||
return result;
|
||||
return resultingOptions;
|
||||
}
|
||||
async fill(progress, value, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._fill(progress, value, options);
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _fill(progress, value, options) {
|
||||
progress.log(` fill("${value}")`);
|
||||
return await this._retryAction(progress, "fill", async () => {
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
if (!options.force)
|
||||
progress.log(" waiting for element to be visible, enabled and editable");
|
||||
const result = await progress.race(this.evaluateInUtility(async ([injected, node, { value: value2, force }]) => {
|
||||
if (!force) {
|
||||
const checkResult = await injected.checkElementStates(node, ["visible", "enabled", "editable"]);
|
||||
if (checkResult)
|
||||
return checkResult;
|
||||
}
|
||||
return injected.fill(node, value2);
|
||||
}, { value, force: options.force }));
|
||||
if (result === "needsinput") {
|
||||
if (value)
|
||||
await this._page.keyboard.insertText(progress, value);
|
||||
else
|
||||
await this._page.keyboard.press(progress, "Delete");
|
||||
return "done";
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}, options);
|
||||
}
|
||||
async selectText(progress, options) {
|
||||
const result = await this._retryAction(progress, "selectText", async () => {
|
||||
if (!options.force)
|
||||
progress.log(" waiting for element to be visible");
|
||||
return await progress.race(this.evaluateInUtility(async ([injected, node, { force }]) => {
|
||||
if (!force) {
|
||||
const checkResult = await injected.checkElementStates(node, ["visible"]);
|
||||
if (checkResult)
|
||||
return checkResult;
|
||||
}
|
||||
return injected.selectText(node);
|
||||
}, { force: options.force }));
|
||||
}, options);
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async setInputFiles(progress, params) {
|
||||
const inputFileItems = await progress.race((0, import_fileUploadUtils.prepareFilesForUpload)(this._frame, params));
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._setInputFiles(progress, inputFileItems);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _setInputFiles(progress, items) {
|
||||
const { filePayloads, localPaths, localDirectory } = items;
|
||||
const multiple = filePayloads && filePayloads.length > 1 || localPaths && localPaths.length > 1;
|
||||
const result = await progress.race(this.evaluateHandleInUtility(([injected, node, { multiple: multiple2, directoryUpload }]) => {
|
||||
const element = injected.retarget(node, "follow-label");
|
||||
if (!element)
|
||||
return;
|
||||
if (element.tagName !== "INPUT")
|
||||
throw injected.createStacklessError("Node is not an HTMLInputElement");
|
||||
const inputElement = element;
|
||||
if (multiple2 && !inputElement.multiple && !inputElement.webkitdirectory)
|
||||
throw injected.createStacklessError("Non-multiple file input can only accept single file");
|
||||
if (directoryUpload && !inputElement.webkitdirectory)
|
||||
throw injected.createStacklessError("File input does not support directories, pass individual files instead");
|
||||
if (!directoryUpload && inputElement.webkitdirectory)
|
||||
throw injected.createStacklessError("[webkitdirectory] input requires passing a path to a directory");
|
||||
return inputElement;
|
||||
}, { multiple, directoryUpload: !!localDirectory }));
|
||||
if (result === "error:notconnected" || !result.asElement())
|
||||
return "error:notconnected";
|
||||
const retargeted = result.asElement();
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
if (localPaths || localDirectory) {
|
||||
const localPathsOrDirectory = localDirectory ? [localDirectory] : localPaths;
|
||||
await progress.race(Promise.all(localPathsOrDirectory.map((localPath) => import_fs.default.promises.access(localPath, import_fs.default.constants.F_OK))));
|
||||
const waitForInputEvent = localDirectory ? this.evaluate((node) => new Promise((fulfill) => {
|
||||
node.addEventListener("input", fulfill, { once: true });
|
||||
})).catch(() => {
|
||||
}) : Promise.resolve();
|
||||
await progress.race(this._page.delegate.setInputFilePaths(retargeted, localPathsOrDirectory));
|
||||
await progress.race(waitForInputEvent);
|
||||
} else {
|
||||
await progress.race(retargeted.evaluateInUtility(([injected, node, files]) => injected.setInputFiles(node, files), filePayloads));
|
||||
}
|
||||
return "done";
|
||||
}
|
||||
async focus(progress) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._focus(progress);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _focus(progress, resetSelectionIfNotFocused) {
|
||||
return await progress.race(this.evaluateInUtility(([injected, node, resetSelectionIfNotFocused2]) => injected.focusNode(node, resetSelectionIfNotFocused2), resetSelectionIfNotFocused));
|
||||
}
|
||||
async _blur(progress) {
|
||||
return await progress.race(this.evaluateInUtility(([injected, node]) => injected.blurNode(node), {}));
|
||||
}
|
||||
async type(progress, text, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._type(progress, text, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _type(progress, text, options) {
|
||||
progress.log(`elementHandle.type("${text}")`);
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
const result = await this._focus(
|
||||
progress,
|
||||
true
|
||||
/* resetSelectionIfNotFocused */
|
||||
);
|
||||
if (result !== "done")
|
||||
return result;
|
||||
await this._page.keyboard.type(progress, text, options);
|
||||
return "done";
|
||||
}
|
||||
async press(progress, key, options) {
|
||||
await this._markAsTargetElement(progress);
|
||||
const result = await this._press(progress, key, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _press(progress, key, options) {
|
||||
progress.log(`elementHandle.press("${key}")`);
|
||||
await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata));
|
||||
return this._page.frameManager.waitForSignalsCreatedBy(progress, !options.noWaitAfter, async () => {
|
||||
const result = await this._focus(
|
||||
progress,
|
||||
true
|
||||
/* resetSelectionIfNotFocused */
|
||||
);
|
||||
if (result !== "done")
|
||||
return result;
|
||||
await this._page.keyboard.press(progress, key, options);
|
||||
return "done";
|
||||
});
|
||||
}
|
||||
async check(progress, options) {
|
||||
const result = await this._setChecked(progress, true, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async uncheck(progress, options) {
|
||||
const result = await this._setChecked(progress, false, options);
|
||||
return assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async _setChecked(progress, state, options) {
|
||||
const isChecked = async () => {
|
||||
const result2 = await progress.race(this.evaluateInUtility(([injected, node]) => injected.elementState(node, "checked"), {}));
|
||||
if (result2 === "error:notconnected" || result2.received === "error:notconnected")
|
||||
throwElementIsNotAttached();
|
||||
return { matches: result2.matches, isRadio: result2.isRadio };
|
||||
};
|
||||
await this._markAsTargetElement(progress);
|
||||
const checkedState = await isChecked();
|
||||
if (checkedState.matches === state)
|
||||
return "done";
|
||||
if (!state && checkedState.isRadio)
|
||||
throw new NonRecoverableDOMError("Cannot uncheck radio button. Radio buttons can only be unchecked by selecting another radio button in the same group.");
|
||||
const result = await this._click(progress, { ...options, waitAfter: "disabled" });
|
||||
if (result !== "done")
|
||||
return result;
|
||||
if (options.trial)
|
||||
return "done";
|
||||
const finalState = await isChecked();
|
||||
if (finalState.matches !== state)
|
||||
throw new NonRecoverableDOMError("Clicking the checkbox did not change its state");
|
||||
return "done";
|
||||
}
|
||||
async boundingBox() {
|
||||
return this._page.delegate.getBoundingBox(this);
|
||||
}
|
||||
async ariaSnapshot() {
|
||||
return await this.evaluateInUtility(([injected, element]) => injected.ariaSnapshot(element, { mode: "expect" }), {});
|
||||
}
|
||||
async screenshot(progress, options) {
|
||||
return await this._page.screenshotter.screenshotElement(progress, this, options);
|
||||
}
|
||||
async querySelector(selector, options) {
|
||||
return this._frame.selectors.query(selector, options, this);
|
||||
}
|
||||
async querySelectorAll(selector) {
|
||||
return this._frame.selectors.queryAll(selector, this);
|
||||
}
|
||||
async evalOnSelector(selector, strict, expression, isFunction, arg) {
|
||||
return this._frame.evalOnSelector(selector, strict, expression, isFunction, arg, this);
|
||||
}
|
||||
async evalOnSelectorAll(selector, expression, isFunction, arg) {
|
||||
return this._frame.evalOnSelectorAll(selector, expression, isFunction, arg, this);
|
||||
}
|
||||
async isVisible(progress) {
|
||||
return this._frame.isVisible(progress, ":scope", {}, this);
|
||||
}
|
||||
async isHidden(progress) {
|
||||
return this._frame.isHidden(progress, ":scope", {}, this);
|
||||
}
|
||||
async isEnabled(progress) {
|
||||
return this._frame.isEnabled(progress, ":scope", {}, this);
|
||||
}
|
||||
async isDisabled(progress) {
|
||||
return this._frame.isDisabled(progress, ":scope", {}, this);
|
||||
}
|
||||
async isEditable(progress) {
|
||||
return this._frame.isEditable(progress, ":scope", {}, this);
|
||||
}
|
||||
async isChecked(progress) {
|
||||
return this._frame.isChecked(progress, ":scope", {}, this);
|
||||
}
|
||||
async waitForElementState(progress, state) {
|
||||
const actionName = `wait for ${state}`;
|
||||
const result = await this._retryAction(progress, actionName, async () => {
|
||||
return await progress.race(this.evaluateInUtility(async ([injected, node, state2]) => {
|
||||
return await injected.checkElementStates(node, [state2]) || "done";
|
||||
}, state));
|
||||
}, {});
|
||||
assertDone(throwRetargetableDOMError(result));
|
||||
}
|
||||
async waitForSelector(progress, selector, options) {
|
||||
return await this._frame.waitForSelector(progress, selector, true, options, this);
|
||||
}
|
||||
async _adoptTo(context) {
|
||||
if (this._context !== context) {
|
||||
const adopted = await this._page.delegate.adoptElementHandle(this, context);
|
||||
this.dispose();
|
||||
return adopted;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
async _checkFrameIsHitTarget(point) {
|
||||
let frame = this._frame;
|
||||
const data = [];
|
||||
while (frame.parentFrame()) {
|
||||
const frameElement = await frame.frameElement();
|
||||
const box = await frameElement.boundingBox();
|
||||
const style = await frameElement.evaluateInUtility(([injected, iframe]) => injected.describeIFrameStyle(iframe), {}).catch((e) => "error:notconnected");
|
||||
if (!box || style === "error:notconnected")
|
||||
return "error:notconnected";
|
||||
if (style === "transformed") {
|
||||
return { framePoint: void 0 };
|
||||
}
|
||||
const pointInFrame = { x: point.x - box.x - style.left, y: point.y - box.y - style.top };
|
||||
data.push({ frame, frameElement, pointInFrame });
|
||||
frame = frame.parentFrame();
|
||||
}
|
||||
data.push({ frame, frameElement: null, pointInFrame: point });
|
||||
for (let i = data.length - 1; i > 0; i--) {
|
||||
const element = data[i - 1].frameElement;
|
||||
const point2 = data[i].pointInFrame;
|
||||
const hitTargetResult = await element.evaluateInUtility(([injected, element2, hitPoint]) => {
|
||||
return injected.expectHitTarget(hitPoint, element2);
|
||||
}, point2);
|
||||
if (hitTargetResult !== "done")
|
||||
return hitTargetResult;
|
||||
}
|
||||
return { framePoint: data[0].pointInFrame };
|
||||
}
|
||||
}
|
||||
function throwRetargetableDOMError(result) {
|
||||
if (result === "error:notconnected")
|
||||
throwElementIsNotAttached();
|
||||
return result;
|
||||
}
|
||||
function throwElementIsNotAttached() {
|
||||
throw new Error("Element is not attached to the DOM");
|
||||
}
|
||||
function assertDone(result) {
|
||||
}
|
||||
function roundPoint(point) {
|
||||
return {
|
||||
x: (point.x * 100 | 0) / 100,
|
||||
y: (point.y * 100 | 0) / 100
|
||||
};
|
||||
}
|
||||
function quadMiddlePoint(quad) {
|
||||
const result = { x: 0, y: 0 };
|
||||
for (const point of quad) {
|
||||
result.x += point.x / 4;
|
||||
result.y += point.y / 4;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function triangleArea(p1, p2, p3) {
|
||||
return Math.abs(p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y)) / 2;
|
||||
}
|
||||
function isPointInsideQuad(point, quad) {
|
||||
const area1 = triangleArea(point, quad[0], quad[1]) + triangleArea(point, quad[1], quad[2]) + triangleArea(point, quad[2], quad[3]) + triangleArea(point, quad[3], quad[0]);
|
||||
const area2 = triangleArea(quad[0], quad[1], quad[2]) + triangleArea(quad[1], quad[2], quad[3]);
|
||||
if (Math.abs(area1 - area2) > 0.1)
|
||||
return false;
|
||||
return point.x < Math.max(quad[0].x, quad[1].x, quad[2].x, quad[3].x) && point.y < Math.max(quad[0].y, quad[1].y, quad[2].y, quad[3].y);
|
||||
}
|
||||
function findIntegerPointInsideQuad(quad) {
|
||||
const point = quadMiddlePoint(quad);
|
||||
point.x = Math.floor(point.x);
|
||||
point.y = Math.floor(point.y);
|
||||
if (isPointInsideQuad(point, quad))
|
||||
return point;
|
||||
point.x += 1;
|
||||
if (isPointInsideQuad(point, quad))
|
||||
return point;
|
||||
point.y += 1;
|
||||
if (isPointInsideQuad(point, quad))
|
||||
return point;
|
||||
point.x -= 1;
|
||||
if (isPointInsideQuad(point, quad))
|
||||
return point;
|
||||
}
|
||||
const kUnableToAdoptErrorMessage = "Unable to adopt element handle from a different document";
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ElementHandle,
|
||||
FrameExecutionContext,
|
||||
NonRecoverableDOMError,
|
||||
assertDone,
|
||||
isNonRecoverableDOMError,
|
||||
kUnableToAdoptErrorMessage,
|
||||
throwElementIsNotAttached,
|
||||
throwRetargetableDOMError
|
||||
});
|
||||
70
.playwright-mcp/node_modules/playwright-core/lib/server/download.js
generated
vendored
Normal file
70
.playwright-mcp/node_modules/playwright-core/lib/server/download.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var download_exports = {};
|
||||
__export(download_exports, {
|
||||
Download: () => Download
|
||||
});
|
||||
module.exports = __toCommonJS(download_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_page = require("./page");
|
||||
var import_utils = require("../utils");
|
||||
var import_artifact = require("./artifact");
|
||||
class Download {
|
||||
constructor(page, downloadsPath, uuid, url, suggestedFilename) {
|
||||
const unaccessibleErrorMessage = page.browserContext._options.acceptDownloads === "deny" ? "Pass { acceptDownloads: true } when you are creating your browser context." : void 0;
|
||||
this.artifact = new import_artifact.Artifact(page, import_path.default.join(downloadsPath, uuid), unaccessibleErrorMessage, () => {
|
||||
return this._page.browserContext.cancelDownload(uuid);
|
||||
});
|
||||
this._page = page;
|
||||
this.url = url;
|
||||
this._suggestedFilename = suggestedFilename;
|
||||
page.browserContext._downloads.add(this);
|
||||
if (suggestedFilename !== void 0)
|
||||
this._fireDownloadEvent();
|
||||
}
|
||||
page() {
|
||||
return this._page;
|
||||
}
|
||||
_filenameSuggested(suggestedFilename) {
|
||||
(0, import_utils.assert)(this._suggestedFilename === void 0);
|
||||
this._suggestedFilename = suggestedFilename;
|
||||
this._fireDownloadEvent();
|
||||
}
|
||||
suggestedFilename() {
|
||||
return this._suggestedFilename;
|
||||
}
|
||||
_fireDownloadEvent() {
|
||||
this._page.instrumentation.onDownload(this._page, this);
|
||||
this._page.emit(import_page.Page.Events.Download, this);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Download
|
||||
});
|
||||
270
.playwright-mcp/node_modules/playwright-core/lib/server/electron/electron.js
generated
vendored
Normal file
270
.playwright-mcp/node_modules/playwright-core/lib/server/electron/electron.js
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var electron_exports = {};
|
||||
__export(electron_exports, {
|
||||
Electron: () => Electron,
|
||||
ElectronApplication: () => ElectronApplication
|
||||
});
|
||||
module.exports = __toCommonJS(electron_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var readline = __toESM(require("readline"));
|
||||
var import_utils = require("../../utils");
|
||||
var import_ascii = require("../utils/ascii");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_crBrowser = require("../chromium/crBrowser");
|
||||
var import_crConnection = require("../chromium/crConnection");
|
||||
var import_crExecutionContext = require("../chromium/crExecutionContext");
|
||||
var import_crProtocolHelper = require("../chromium/crProtocolHelper");
|
||||
var import_console = require("../console");
|
||||
var import_helper = require("../helper");
|
||||
var import_instrumentation = require("../instrumentation");
|
||||
var js = __toESM(require("../javascript"));
|
||||
var import_processLauncher = require("../utils/processLauncher");
|
||||
var import_transport = require("../transport");
|
||||
const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
|
||||
class ElectronApplication extends import_instrumentation.SdkObject {
|
||||
constructor(parent, browser, nodeConnection, process2) {
|
||||
super(parent, "electron-app");
|
||||
this._nodeElectronHandlePromise = new import_utils.ManualPromise();
|
||||
this._process = process2;
|
||||
this._browserContext = browser._defaultContext;
|
||||
this._nodeConnection = nodeConnection;
|
||||
this._nodeSession = nodeConnection.rootSession;
|
||||
this._nodeSession.on("Runtime.executionContextCreated", async (event) => {
|
||||
if (!event.context.auxData || !event.context.auxData.isDefault)
|
||||
return;
|
||||
const crExecutionContext = new import_crExecutionContext.CRExecutionContext(this._nodeSession, event.context);
|
||||
this._nodeExecutionContext = new js.ExecutionContext(this, crExecutionContext, "electron");
|
||||
const { result: remoteObject } = await crExecutionContext._client.send("Runtime.evaluate", {
|
||||
expression: `require('electron')`,
|
||||
contextId: event.context.id,
|
||||
// Needed after Electron 28 to get access to require: https://github.com/microsoft/playwright/issues/28048
|
||||
includeCommandLineAPI: true
|
||||
});
|
||||
this._nodeElectronHandlePromise.resolve(new js.JSHandle(this._nodeExecutionContext, "object", "ElectronModule", remoteObject.objectId));
|
||||
});
|
||||
this._nodeSession.on("Runtime.consoleAPICalled", (event) => this._onConsoleAPI(event));
|
||||
const appClosePromise = new Promise((f) => this.once(ElectronApplication.Events.Close, f));
|
||||
this._browserContext.setCustomCloseHandler(async () => {
|
||||
await this._browserContext.stopVideoRecording();
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
await electronHandle.evaluate(({ app }) => app.quit()).catch(() => {
|
||||
});
|
||||
this._nodeConnection.close();
|
||||
await appClosePromise;
|
||||
});
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Close: "close",
|
||||
Console: "console"
|
||||
};
|
||||
}
|
||||
async _onConsoleAPI(event) {
|
||||
if (event.executionContextId === 0) {
|
||||
return;
|
||||
}
|
||||
if (!this._nodeExecutionContext)
|
||||
return;
|
||||
const args = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(this._nodeExecutionContext, arg));
|
||||
const message = new import_console.ConsoleMessage(null, null, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
||||
this.emit(ElectronApplication.Events.Console, message);
|
||||
}
|
||||
async initialize() {
|
||||
await this._nodeSession.send("Runtime.enable", {});
|
||||
await this._nodeSession.send("Runtime.evaluate", { expression: "__playwright_run()" });
|
||||
}
|
||||
process() {
|
||||
return this._process;
|
||||
}
|
||||
context() {
|
||||
return this._browserContext;
|
||||
}
|
||||
async close() {
|
||||
await this._browserContext.close({ reason: "Application exited" });
|
||||
}
|
||||
async browserWindow(page) {
|
||||
const targetId = page.delegate._targetId;
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
return await electronHandle.evaluateHandle(({ BrowserWindow, webContents }, targetId2) => {
|
||||
const wc = webContents.fromDevToolsTargetId(targetId2);
|
||||
return BrowserWindow.fromWebContents(wc);
|
||||
}, targetId);
|
||||
}
|
||||
}
|
||||
class Electron extends import_instrumentation.SdkObject {
|
||||
constructor(playwright) {
|
||||
super(playwright, "electron");
|
||||
this.logName = "browser";
|
||||
}
|
||||
async launch(progress, options) {
|
||||
let app = void 0;
|
||||
let electronArguments = ["--inspect=0", "--remote-debugging-port=0", ...options.args || []];
|
||||
if (import_os.default.platform() === "linux") {
|
||||
const runningAsRoot = process.geteuid && process.geteuid() === 0;
|
||||
if (runningAsRoot && electronArguments.indexOf("--no-sandbox") === -1)
|
||||
electronArguments.unshift("--no-sandbox");
|
||||
}
|
||||
const artifactsDir = await progress.race(import_fs.default.promises.mkdtemp(ARTIFACTS_FOLDER));
|
||||
const browserLogsCollector = new import_debugLogger.RecentLogsCollector();
|
||||
const env = options.env ? (0, import_processLauncher.envArrayToObject)(options.env) : process.env;
|
||||
let command;
|
||||
if (options.executablePath) {
|
||||
command = options.executablePath;
|
||||
} else {
|
||||
try {
|
||||
command = require("electron/index.js");
|
||||
} catch (error) {
|
||||
if (error?.code === "MODULE_NOT_FOUND") {
|
||||
throw new Error("\n" + (0, import_ascii.wrapInASCIIBox)([
|
||||
"Electron executablePath not found!",
|
||||
"Please install it using `npm install -D electron` or set the executablePath to your Electron executable."
|
||||
].join("\n"), 1));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
electronArguments.unshift("-r", require.resolve("./loader"));
|
||||
}
|
||||
let shell = false;
|
||||
if (process.platform === "win32") {
|
||||
shell = true;
|
||||
command = `"${command}"`;
|
||||
electronArguments = electronArguments.map((arg) => `"${arg}"`);
|
||||
}
|
||||
delete env.NODE_OPTIONS;
|
||||
const { launchedProcess, gracefullyClose, kill } = await (0, import_processLauncher.launchProcess)({
|
||||
command,
|
||||
args: electronArguments,
|
||||
env,
|
||||
log: (message) => {
|
||||
progress.log(message);
|
||||
browserLogsCollector.log(message);
|
||||
},
|
||||
shell,
|
||||
stdio: "pipe",
|
||||
cwd: options.cwd,
|
||||
tempDirectories: [artifactsDir],
|
||||
attemptToGracefullyClose: () => app.close(),
|
||||
handleSIGINT: true,
|
||||
handleSIGTERM: true,
|
||||
handleSIGHUP: true,
|
||||
onExit: () => app?.emit(ElectronApplication.Events.Close)
|
||||
});
|
||||
const waitForXserverError = waitForLine(progress, launchedProcess, /Unable to open X display/).then(() => {
|
||||
throw new Error([
|
||||
"Unable to open X display!",
|
||||
`================================`,
|
||||
"Most likely this is because there is no X server available.",
|
||||
"Use 'xvfb-run' on Linux to launch your tests with an emulated display server.",
|
||||
"For example: 'xvfb-run npm run test:e2e'",
|
||||
`================================`,
|
||||
progress.metadata.log
|
||||
].join("\n"));
|
||||
});
|
||||
const nodeMatchPromise = waitForLine(progress, launchedProcess, /^Debugger listening on (ws:\/\/.*)$/);
|
||||
const chromeMatchPromise = waitForLine(progress, launchedProcess, /^DevTools listening on (ws:\/\/.*)$/);
|
||||
const debuggerDisconnectPromise = waitForLine(progress, launchedProcess, /Waiting for the debugger to disconnect\.\.\./);
|
||||
try {
|
||||
const nodeMatch = await nodeMatchPromise;
|
||||
const nodeTransport = await import_transport.WebSocketTransport.connect(progress, nodeMatch[1]);
|
||||
const nodeConnection = new import_crConnection.CRConnection(this, nodeTransport, import_helper.helper.debugProtocolLogger(), browserLogsCollector);
|
||||
debuggerDisconnectPromise.then(() => {
|
||||
nodeTransport.close();
|
||||
}).catch(() => {
|
||||
});
|
||||
const chromeMatch = await Promise.race([
|
||||
chromeMatchPromise,
|
||||
waitForXserverError
|
||||
]);
|
||||
const chromeTransport = await import_transport.WebSocketTransport.connect(progress, chromeMatch[1]);
|
||||
const browserProcess = {
|
||||
onclose: void 0,
|
||||
process: launchedProcess,
|
||||
close: gracefullyClose,
|
||||
kill
|
||||
};
|
||||
const contextOptions = {
|
||||
...options,
|
||||
noDefaultViewport: true
|
||||
};
|
||||
const browserOptions = {
|
||||
name: "electron",
|
||||
isChromium: true,
|
||||
headful: true,
|
||||
persistent: contextOptions,
|
||||
browserProcess,
|
||||
protocolLogger: import_helper.helper.debugProtocolLogger(),
|
||||
browserLogsCollector,
|
||||
artifactsDir,
|
||||
downloadsPath: artifactsDir,
|
||||
tracesDir: options.tracesDir || artifactsDir,
|
||||
originalLaunchOptions: {}
|
||||
};
|
||||
(0, import_browserContext.validateBrowserContextOptions)(contextOptions, browserOptions);
|
||||
const browser = await progress.race(import_crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions));
|
||||
app = new ElectronApplication(this, browser, nodeConnection, launchedProcess);
|
||||
await progress.race(app.initialize());
|
||||
return app;
|
||||
} catch (error) {
|
||||
await kill();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
async function waitForLine(progress, process2, regex) {
|
||||
const promise = new import_utils.ManualPromise();
|
||||
const rl = readline.createInterface({ input: process2.stderr });
|
||||
const failError = new Error("Process failed to launch!");
|
||||
const listeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(rl, "line", onLine),
|
||||
import_eventsHelper.eventsHelper.addEventListener(rl, "close", () => promise.reject(failError)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(process2, "exit", () => promise.reject(failError)),
|
||||
// It is Ok to remove error handler because we did not create process and there is another listener.
|
||||
import_eventsHelper.eventsHelper.addEventListener(process2, "error", () => promise.reject(failError))
|
||||
];
|
||||
function onLine(line) {
|
||||
const match = line.match(regex);
|
||||
if (match)
|
||||
promise.resolve(match);
|
||||
}
|
||||
try {
|
||||
return await progress.race(promise);
|
||||
} finally {
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(listeners);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Electron,
|
||||
ElectronApplication
|
||||
});
|
||||
29
.playwright-mcp/node_modules/playwright-core/lib/server/electron/loader.js
generated
vendored
Normal file
29
.playwright-mcp/node_modules/playwright-core/lib/server/electron/loader.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
const { app } = require("electron");
|
||||
const { chromiumSwitches } = require("../chromium/chromiumSwitches");
|
||||
process.argv.splice(1, process.argv.indexOf("--remote-debugging-port=0"));
|
||||
for (const arg of chromiumSwitches()) {
|
||||
const match = arg.match(/--([^=]*)=?(.*)/);
|
||||
app.commandLine.appendSwitch(match[1], match[2]);
|
||||
}
|
||||
const originalWhenReady = app.whenReady();
|
||||
const originalEmit = app.emit.bind(app);
|
||||
let readyEventArgs;
|
||||
app.emit = (event, ...args) => {
|
||||
if (event === "ready") {
|
||||
readyEventArgs = args;
|
||||
return app.listenerCount("ready") > 0;
|
||||
}
|
||||
return originalEmit(event, ...args);
|
||||
};
|
||||
let isReady = false;
|
||||
let whenReadyCallback;
|
||||
const whenReadyPromise = new Promise((f) => whenReadyCallback = f);
|
||||
app.isReady = () => isReady;
|
||||
app.whenReady = () => whenReadyPromise;
|
||||
globalThis.__playwright_run = async () => {
|
||||
const event = await originalWhenReady;
|
||||
isReady = true;
|
||||
whenReadyCallback(event);
|
||||
originalEmit("ready", ...readyEventArgs);
|
||||
};
|
||||
69
.playwright-mcp/node_modules/playwright-core/lib/server/errors.js
generated
vendored
Normal file
69
.playwright-mcp/node_modules/playwright-core/lib/server/errors.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var errors_exports = {};
|
||||
__export(errors_exports, {
|
||||
TargetClosedError: () => TargetClosedError,
|
||||
TimeoutError: () => TimeoutError,
|
||||
isTargetClosedError: () => isTargetClosedError,
|
||||
parseError: () => parseError,
|
||||
serializeError: () => serializeError
|
||||
});
|
||||
module.exports = __toCommonJS(errors_exports);
|
||||
var import_serializers = require("../protocol/serializers");
|
||||
var import_utils = require("../utils");
|
||||
class CustomError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
}
|
||||
class TimeoutError extends CustomError {
|
||||
}
|
||||
class TargetClosedError extends CustomError {
|
||||
constructor(cause, logs) {
|
||||
super((cause || "Target page, context or browser has been closed") + (logs || ""));
|
||||
}
|
||||
}
|
||||
function isTargetClosedError(error) {
|
||||
return error instanceof TargetClosedError || error.name === "TargetClosedError";
|
||||
}
|
||||
function serializeError(e) {
|
||||
if ((0, import_utils.isError)(e))
|
||||
return { error: { message: e.message, stack: e.stack, name: e.name } };
|
||||
return { value: (0, import_serializers.serializeValue)(e, (value) => ({ fallThrough: value })) };
|
||||
}
|
||||
function parseError(error) {
|
||||
if (!error.error) {
|
||||
if (error.value === void 0)
|
||||
throw new Error("Serialized error must have either an error or a value");
|
||||
return (0, import_serializers.parseSerializedValue)(error.value, void 0);
|
||||
}
|
||||
const e = new Error(error.error.message);
|
||||
e.stack = error.error.stack || "";
|
||||
e.name = error.error.name;
|
||||
return e;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TargetClosedError,
|
||||
TimeoutError,
|
||||
isTargetClosedError,
|
||||
parseError,
|
||||
serializeError
|
||||
});
|
||||
621
.playwright-mcp/node_modules/playwright-core/lib/server/fetch.js
generated
vendored
Normal file
621
.playwright-mcp/node_modules/playwright-core/lib/server/fetch.js
generated
vendored
Normal file
@@ -0,0 +1,621 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fetch_exports = {};
|
||||
__export(fetch_exports, {
|
||||
APIRequestContext: () => APIRequestContext,
|
||||
BrowserContextAPIRequestContext: () => BrowserContextAPIRequestContext,
|
||||
GlobalAPIRequestContext: () => GlobalAPIRequestContext
|
||||
});
|
||||
module.exports = __toCommonJS(fetch_exports);
|
||||
var import_http = __toESM(require("http"));
|
||||
var import_https = __toESM(require("https"));
|
||||
var import_stream = require("stream");
|
||||
var import_tls = require("tls");
|
||||
var zlib = __toESM(require("zlib"));
|
||||
var import_utils = require("../utils");
|
||||
var import_crypto = require("./utils/crypto");
|
||||
var import_userAgent = require("./utils/userAgent");
|
||||
var import_browserContext = require("./browserContext");
|
||||
var import_cookieStore = require("./cookieStore");
|
||||
var import_formData = require("./formData");
|
||||
var import_instrumentation = require("./instrumentation");
|
||||
var import_progress = require("./progress");
|
||||
var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
|
||||
var import_happyEyeballs = require("./utils/happyEyeballs");
|
||||
var import_tracing = require("./trace/recorder/tracing");
|
||||
class APIRequestContext extends import_instrumentation.SdkObject {
|
||||
constructor(parent) {
|
||||
super(parent, "request-context");
|
||||
this.fetchResponses = /* @__PURE__ */ new Map();
|
||||
this.fetchLog = /* @__PURE__ */ new Map();
|
||||
APIRequestContext.allInstances.add(this);
|
||||
}
|
||||
static {
|
||||
this.Events = {
|
||||
Dispose: "dispose",
|
||||
Request: "request",
|
||||
RequestFinished: "requestfinished"
|
||||
};
|
||||
}
|
||||
static {
|
||||
this.allInstances = /* @__PURE__ */ new Set();
|
||||
}
|
||||
static findResponseBody(guid) {
|
||||
for (const request of APIRequestContext.allInstances) {
|
||||
const body = request.fetchResponses.get(guid);
|
||||
if (body)
|
||||
return body;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
_disposeImpl() {
|
||||
APIRequestContext.allInstances.delete(this);
|
||||
this.fetchResponses.clear();
|
||||
this.fetchLog.clear();
|
||||
this.emit(APIRequestContext.Events.Dispose);
|
||||
}
|
||||
disposeResponse(fetchUid) {
|
||||
this.fetchResponses.delete(fetchUid);
|
||||
this.fetchLog.delete(fetchUid);
|
||||
}
|
||||
_storeResponseBody(body) {
|
||||
const uid = (0, import_crypto.createGuid)();
|
||||
this.fetchResponses.set(uid, body);
|
||||
return uid;
|
||||
}
|
||||
async fetch(progress, params) {
|
||||
const defaults = this._defaultOptions();
|
||||
const headers = {
|
||||
"user-agent": defaults.userAgent,
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip,deflate,br"
|
||||
};
|
||||
if (defaults.extraHTTPHeaders) {
|
||||
for (const { name, value } of defaults.extraHTTPHeaders)
|
||||
setHeader(headers, name, value);
|
||||
}
|
||||
if (params.headers) {
|
||||
for (const { name, value } of params.headers)
|
||||
setHeader(headers, name, value);
|
||||
}
|
||||
const requestUrl = new URL((0, import_utils.constructURLBasedOnBaseURL)(defaults.baseURL, params.url));
|
||||
if (params.encodedParams) {
|
||||
requestUrl.search = params.encodedParams;
|
||||
} else if (params.params) {
|
||||
for (const { name, value } of params.params)
|
||||
requestUrl.searchParams.append(name, value);
|
||||
}
|
||||
const credentials = this._getHttpCredentials(requestUrl);
|
||||
if (credentials?.send === "always")
|
||||
setBasicAuthorizationHeader(headers, credentials);
|
||||
const method = params.method?.toUpperCase() || "GET";
|
||||
const proxy = defaults.proxy;
|
||||
let agent;
|
||||
if (proxy?.server !== "per-context")
|
||||
agent = (0, import_utils.createProxyAgent)(proxy, requestUrl);
|
||||
let maxRedirects = params.maxRedirects ?? (defaults.maxRedirects ?? 20);
|
||||
maxRedirects = maxRedirects === 0 ? -1 : maxRedirects;
|
||||
const options = {
|
||||
method,
|
||||
headers,
|
||||
agent,
|
||||
maxRedirects,
|
||||
...(0, import_socksClientCertificatesInterceptor.getMatchingTLSOptionsForOrigin)(this._defaultOptions().clientCertificates, requestUrl.origin),
|
||||
__testHookLookup: params.__testHookLookup
|
||||
};
|
||||
if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)
|
||||
options.rejectUnauthorized = false;
|
||||
const postData = serializePostData(params, headers);
|
||||
if (postData)
|
||||
setHeader(headers, "content-length", String(postData.byteLength));
|
||||
const fetchResponse = await this._sendRequestWithRetries(progress, requestUrl, options, postData, params.maxRetries);
|
||||
const fetchUid = this._storeResponseBody(fetchResponse.body);
|
||||
this.fetchLog.set(fetchUid, progress.metadata.log);
|
||||
const failOnStatusCode = params.failOnStatusCode !== void 0 ? params.failOnStatusCode : !!defaults.failOnStatusCode;
|
||||
if (failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400)) {
|
||||
let responseText = "";
|
||||
if (fetchResponse.body.byteLength) {
|
||||
let text = fetchResponse.body.toString("utf8");
|
||||
if (text.length > 1e3)
|
||||
text = text.substring(0, 997) + "...";
|
||||
responseText = `
|
||||
Response text:
|
||||
${text}`;
|
||||
}
|
||||
throw new Error(`${fetchResponse.status} ${fetchResponse.statusText}${responseText}`);
|
||||
}
|
||||
return { ...fetchResponse, fetchUid };
|
||||
}
|
||||
_parseSetCookieHeader(responseUrl, setCookie) {
|
||||
if (!setCookie)
|
||||
return [];
|
||||
const url = new URL(responseUrl);
|
||||
const defaultPath = "/" + url.pathname.substr(1).split("/").slice(0, -1).join("/");
|
||||
const cookies = [];
|
||||
for (const header of setCookie) {
|
||||
const cookie = parseCookie(header);
|
||||
if (!cookie)
|
||||
continue;
|
||||
if (!cookie.domain)
|
||||
cookie.domain = url.hostname;
|
||||
else
|
||||
(0, import_utils.assert)(cookie.domain.startsWith(".") || !cookie.domain.includes("."));
|
||||
if (!(0, import_cookieStore.domainMatches)(url.hostname, cookie.domain))
|
||||
continue;
|
||||
if (!cookie.path || !cookie.path.startsWith("/"))
|
||||
cookie.path = defaultPath;
|
||||
cookies.push(cookie);
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
async _updateRequestCookieHeader(progress, url, headers) {
|
||||
if (getHeader(headers, "cookie") !== void 0)
|
||||
return;
|
||||
const contextCookies = await progress.race(this._cookies(url));
|
||||
const cookies = contextCookies.filter((c) => new import_cookieStore.Cookie(c).matches(url));
|
||||
if (cookies.length) {
|
||||
const valueArray = cookies.map((c) => `${c.name}=${c.value}`);
|
||||
setHeader(headers, "cookie", valueArray.join("; "));
|
||||
}
|
||||
}
|
||||
async _sendRequestWithRetries(progress, url, options, postData, maxRetries) {
|
||||
maxRetries ??= 0;
|
||||
let backoff = 250;
|
||||
for (let i = 0; i <= maxRetries; i++) {
|
||||
try {
|
||||
return await this._sendRequest(progress, url, options, postData);
|
||||
} catch (e) {
|
||||
if ((0, import_progress.isAbortError)(e))
|
||||
throw e;
|
||||
e = (0, import_socksClientCertificatesInterceptor.rewriteOpenSSLErrorIfNeeded)(e);
|
||||
if (maxRetries === 0)
|
||||
throw e;
|
||||
if (i === maxRetries)
|
||||
throw new Error(`Failed after ${i + 1} attempt(s): ${e}`);
|
||||
if (e.code !== "ECONNRESET")
|
||||
throw e;
|
||||
progress.log(` Received ECONNRESET, will retry after ${backoff}ms.`);
|
||||
await progress.wait(backoff);
|
||||
backoff *= 2;
|
||||
}
|
||||
}
|
||||
throw new Error("Unreachable");
|
||||
}
|
||||
async _sendRequest(progress, url, options, postData) {
|
||||
await this._updateRequestCookieHeader(progress, url, options.headers);
|
||||
const requestCookies = getHeader(options.headers, "cookie")?.split(";").map((p) => {
|
||||
const [name, value] = p.split("=").map((v) => v.trim());
|
||||
return { name, value };
|
||||
}) || [];
|
||||
const requestEvent = {
|
||||
url,
|
||||
method: options.method,
|
||||
headers: options.headers,
|
||||
cookies: requestCookies,
|
||||
postData
|
||||
};
|
||||
this.emit(APIRequestContext.Events.Request, requestEvent);
|
||||
let destroyRequest;
|
||||
const resultPromise = new Promise((fulfill, reject) => {
|
||||
const requestConstructor = (url.protocol === "https:" ? import_https.default : import_http.default).request;
|
||||
const agent = options.agent || (url.protocol === "https:" ? import_happyEyeballs.httpsHappyEyeballsAgent : import_happyEyeballs.httpHappyEyeballsAgent);
|
||||
const requestOptions = { ...options, agent };
|
||||
const startAt = (0, import_utils.monotonicTime)();
|
||||
let reusedSocketAt;
|
||||
let dnsLookupAt;
|
||||
let tcpConnectionAt;
|
||||
let tlsHandshakeAt;
|
||||
let requestFinishAt;
|
||||
let serverIPAddress;
|
||||
let serverPort;
|
||||
let securityDetails;
|
||||
const listeners = [];
|
||||
const request = requestConstructor(url, requestOptions, async (response) => {
|
||||
const responseAt = (0, import_utils.monotonicTime)();
|
||||
const notifyRequestFinished = (body2) => {
|
||||
const endAt = (0, import_utils.monotonicTime)();
|
||||
const connectEnd = tlsHandshakeAt ?? tcpConnectionAt;
|
||||
const timings = {
|
||||
send: requestFinishAt - startAt,
|
||||
wait: responseAt - requestFinishAt,
|
||||
receive: endAt - responseAt,
|
||||
dns: dnsLookupAt ? dnsLookupAt - startAt : -1,
|
||||
connect: connectEnd ? connectEnd - startAt : -1,
|
||||
// "If [ssl] is defined then the time is also included in the connect field "
|
||||
ssl: tlsHandshakeAt ? tlsHandshakeAt - tcpConnectionAt : -1,
|
||||
blocked: reusedSocketAt ? reusedSocketAt - startAt : -1
|
||||
};
|
||||
const requestFinishedEvent = {
|
||||
requestEvent,
|
||||
httpVersion: response.httpVersion,
|
||||
statusCode: response.statusCode || 0,
|
||||
statusMessage: response.statusMessage || "",
|
||||
headers: response.headers,
|
||||
rawHeaders: response.rawHeaders,
|
||||
cookies,
|
||||
body: body2,
|
||||
timings,
|
||||
serverIPAddress,
|
||||
serverPort,
|
||||
securityDetails
|
||||
};
|
||||
this.emit(APIRequestContext.Events.RequestFinished, requestFinishedEvent);
|
||||
};
|
||||
progress.log(`\u2190 ${response.statusCode} ${response.statusMessage}`);
|
||||
for (const [name, value] of Object.entries(response.headers))
|
||||
progress.log(` ${name}: ${value}`);
|
||||
const cookies = this._parseSetCookieHeader(response.url || url.toString(), response.headers["set-cookie"]);
|
||||
if (cookies.length) {
|
||||
try {
|
||||
await this._addCookies(cookies);
|
||||
} catch (e) {
|
||||
await Promise.all(cookies.map((c) => this._addCookies([c]).catch(() => {
|
||||
})));
|
||||
}
|
||||
}
|
||||
if (redirectStatus.includes(response.statusCode) && options.maxRedirects >= 0) {
|
||||
if (options.maxRedirects === 0) {
|
||||
reject(new Error("Max redirect count exceeded"));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
const headers = { ...options.headers };
|
||||
removeHeader(headers, `cookie`);
|
||||
const status = response.statusCode;
|
||||
let method = options.method;
|
||||
if ((status === 301 || status === 302) && method === "POST" || status === 303 && !["GET", "HEAD"].includes(method)) {
|
||||
method = "GET";
|
||||
postData = void 0;
|
||||
removeHeader(headers, `content-encoding`);
|
||||
removeHeader(headers, `content-language`);
|
||||
removeHeader(headers, `content-length`);
|
||||
removeHeader(headers, `content-location`);
|
||||
removeHeader(headers, `content-type`);
|
||||
}
|
||||
const redirectOptions = {
|
||||
method,
|
||||
headers,
|
||||
agent: options.agent,
|
||||
maxRedirects: options.maxRedirects - 1,
|
||||
...(0, import_socksClientCertificatesInterceptor.getMatchingTLSOptionsForOrigin)(this._defaultOptions().clientCertificates, url.origin),
|
||||
__testHookLookup: options.__testHookLookup
|
||||
};
|
||||
if (options.rejectUnauthorized === false)
|
||||
redirectOptions.rejectUnauthorized = false;
|
||||
const locationHeaderValue = Buffer.from(response.headers.location ?? "", "latin1").toString("utf8");
|
||||
if (locationHeaderValue) {
|
||||
let locationURL;
|
||||
try {
|
||||
locationURL = new URL(locationHeaderValue, url);
|
||||
} catch (error) {
|
||||
reject(new Error(`uri requested responds with an invalid redirect URL: ${locationHeaderValue}`));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
if (headers["host"])
|
||||
headers["host"] = locationURL.host;
|
||||
notifyRequestFinished();
|
||||
fulfill(this._sendRequest(progress, locationURL, redirectOptions, postData));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (response.statusCode === 401 && !getHeader(options.headers, "authorization")) {
|
||||
const auth = response.headers["www-authenticate"];
|
||||
const credentials = this._getHttpCredentials(url);
|
||||
if (auth?.trim().startsWith("Basic") && credentials) {
|
||||
setBasicAuthorizationHeader(options.headers, credentials);
|
||||
notifyRequestFinished();
|
||||
fulfill(this._sendRequest(progress, url, options, postData));
|
||||
request.destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
response.on("aborted", () => reject(new Error("aborted")));
|
||||
const chunks = [];
|
||||
const notifyBodyFinished = () => {
|
||||
const body2 = Buffer.concat(chunks);
|
||||
notifyRequestFinished(body2);
|
||||
fulfill({
|
||||
url: response.url || url.toString(),
|
||||
status: response.statusCode || 0,
|
||||
statusText: response.statusMessage || "",
|
||||
headers: toHeadersArray(response.rawHeaders),
|
||||
body: body2
|
||||
});
|
||||
};
|
||||
let body = response;
|
||||
let transform;
|
||||
const encoding = response.headers["content-encoding"];
|
||||
if (encoding === "gzip" || encoding === "x-gzip") {
|
||||
transform = zlib.createGunzip({
|
||||
flush: zlib.constants.Z_SYNC_FLUSH,
|
||||
finishFlush: zlib.constants.Z_SYNC_FLUSH
|
||||
});
|
||||
} else if (encoding === "br") {
|
||||
transform = zlib.createBrotliDecompress({
|
||||
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
|
||||
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
|
||||
});
|
||||
} else if (encoding === "deflate") {
|
||||
transform = zlib.createInflate();
|
||||
}
|
||||
if (transform) {
|
||||
const emptyStreamTransform = new SafeEmptyStreamTransform(notifyBodyFinished);
|
||||
body = (0, import_stream.pipeline)(response, emptyStreamTransform, transform, (e) => {
|
||||
if (e)
|
||||
reject(new Error(`failed to decompress '${encoding}' encoding: ${e.message}`));
|
||||
});
|
||||
body.on("error", (e) => reject(new Error(`failed to decompress '${encoding}' encoding: ${e}`)));
|
||||
} else {
|
||||
body.on("error", reject);
|
||||
}
|
||||
body.on("data", (chunk) => chunks.push(chunk));
|
||||
body.on("end", notifyBodyFinished);
|
||||
});
|
||||
request.on("error", reject);
|
||||
destroyRequest = () => request.destroy();
|
||||
listeners.push(
|
||||
import_utils.eventsHelper.addEventListener(this, APIRequestContext.Events.Dispose, () => {
|
||||
reject(new Error("Request context disposed."));
|
||||
request.destroy();
|
||||
})
|
||||
);
|
||||
request.on("close", () => import_utils.eventsHelper.removeEventListeners(listeners));
|
||||
request.on("socket", (socket) => {
|
||||
if (request.reusedSocket) {
|
||||
reusedSocketAt = (0, import_utils.monotonicTime)();
|
||||
return;
|
||||
}
|
||||
const happyEyeBallsTimings = (0, import_happyEyeballs.timingForSocket)(socket);
|
||||
dnsLookupAt = happyEyeBallsTimings.dnsLookupAt;
|
||||
tcpConnectionAt = happyEyeBallsTimings.tcpConnectionAt;
|
||||
listeners.push(
|
||||
import_utils.eventsHelper.addEventListener(socket, "lookup", () => {
|
||||
dnsLookupAt = (0, import_utils.monotonicTime)();
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(socket, "connect", () => {
|
||||
tcpConnectionAt = (0, import_utils.monotonicTime)();
|
||||
}),
|
||||
import_utils.eventsHelper.addEventListener(socket, "secureConnect", () => {
|
||||
tlsHandshakeAt = (0, import_utils.monotonicTime)();
|
||||
if (socket instanceof import_tls.TLSSocket) {
|
||||
const peerCertificate = socket.getPeerCertificate();
|
||||
securityDetails = {
|
||||
protocol: socket.getProtocol() ?? void 0,
|
||||
subjectName: peerCertificate.subject.CN,
|
||||
validFrom: new Date(peerCertificate.valid_from).getTime() / 1e3,
|
||||
validTo: new Date(peerCertificate.valid_to).getTime() / 1e3,
|
||||
issuer: peerCertificate.issuer.CN
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
serverIPAddress = socket.remoteAddress;
|
||||
serverPort = socket.remotePort;
|
||||
});
|
||||
request.on("finish", () => {
|
||||
requestFinishAt = (0, import_utils.monotonicTime)();
|
||||
});
|
||||
progress.log(`\u2192 ${options.method} ${url.toString()}`);
|
||||
if (options.headers) {
|
||||
for (const [name, value] of Object.entries(options.headers))
|
||||
progress.log(` ${name}: ${value}`);
|
||||
}
|
||||
if (postData)
|
||||
request.write(postData);
|
||||
request.end();
|
||||
});
|
||||
return progress.race(resultPromise).catch((error) => {
|
||||
destroyRequest?.();
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
_getHttpCredentials(url) {
|
||||
if (!this._defaultOptions().httpCredentials?.origin || url.origin.toLowerCase() === this._defaultOptions().httpCredentials?.origin?.toLowerCase())
|
||||
return this._defaultOptions().httpCredentials;
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
class SafeEmptyStreamTransform extends import_stream.Transform {
|
||||
constructor(onEmptyStreamCallback) {
|
||||
super();
|
||||
this._receivedSomeData = false;
|
||||
this._onEmptyStreamCallback = onEmptyStreamCallback;
|
||||
}
|
||||
_transform(chunk, encoding, callback) {
|
||||
this._receivedSomeData = true;
|
||||
callback(null, chunk);
|
||||
}
|
||||
_flush(callback) {
|
||||
if (this._receivedSomeData)
|
||||
callback(null);
|
||||
else
|
||||
this._onEmptyStreamCallback();
|
||||
}
|
||||
}
|
||||
class BrowserContextAPIRequestContext extends APIRequestContext {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
this._context = context;
|
||||
context.once(import_browserContext.BrowserContext.Events.Close, () => this._disposeImpl());
|
||||
}
|
||||
tracing() {
|
||||
return this._context.tracing;
|
||||
}
|
||||
async dispose(options) {
|
||||
this._closeReason = options.reason;
|
||||
this.fetchResponses.clear();
|
||||
}
|
||||
_defaultOptions() {
|
||||
return {
|
||||
userAgent: this._context._options.userAgent || this._context._browser.userAgent(),
|
||||
extraHTTPHeaders: this._context._options.extraHTTPHeaders,
|
||||
failOnStatusCode: void 0,
|
||||
httpCredentials: this._context._options.httpCredentials,
|
||||
proxy: this._context._options.proxy || this._context._browser.options.proxy,
|
||||
ignoreHTTPSErrors: this._context._options.ignoreHTTPSErrors,
|
||||
baseURL: this._context._options.baseURL,
|
||||
clientCertificates: this._context._options.clientCertificates
|
||||
};
|
||||
}
|
||||
async _addCookies(cookies) {
|
||||
await this._context.addCookies(cookies);
|
||||
}
|
||||
async _cookies(url) {
|
||||
return await this._context.cookies(url.toString());
|
||||
}
|
||||
async storageState(progress, indexedDB) {
|
||||
return this._context.storageState(progress, indexedDB);
|
||||
}
|
||||
}
|
||||
class GlobalAPIRequestContext extends APIRequestContext {
|
||||
constructor(playwright, options) {
|
||||
super(playwright);
|
||||
this._cookieStore = new import_cookieStore.CookieStore();
|
||||
this.attribution.context = this;
|
||||
if (options.storageState) {
|
||||
this._origins = options.storageState.origins?.map((origin) => ({ indexedDB: [], ...origin }));
|
||||
this._cookieStore.addCookies(options.storageState.cookies || []);
|
||||
}
|
||||
(0, import_browserContext.verifyClientCertificates)(options.clientCertificates);
|
||||
this._options = {
|
||||
baseURL: options.baseURL,
|
||||
userAgent: options.userAgent || (0, import_userAgent.getUserAgent)(),
|
||||
extraHTTPHeaders: options.extraHTTPHeaders,
|
||||
failOnStatusCode: !!options.failOnStatusCode,
|
||||
ignoreHTTPSErrors: !!options.ignoreHTTPSErrors,
|
||||
maxRedirects: options.maxRedirects,
|
||||
httpCredentials: options.httpCredentials,
|
||||
clientCertificates: options.clientCertificates,
|
||||
proxy: options.proxy
|
||||
};
|
||||
this._tracing = new import_tracing.Tracing(this, options.tracesDir);
|
||||
}
|
||||
tracing() {
|
||||
return this._tracing;
|
||||
}
|
||||
async dispose(options) {
|
||||
this._closeReason = options.reason;
|
||||
await this._tracing.flush();
|
||||
await this._tracing.deleteTmpTracesDir();
|
||||
this._disposeImpl();
|
||||
}
|
||||
_defaultOptions() {
|
||||
return this._options;
|
||||
}
|
||||
async _addCookies(cookies) {
|
||||
this._cookieStore.addCookies(cookies);
|
||||
}
|
||||
async _cookies(url) {
|
||||
return this._cookieStore.cookies(url);
|
||||
}
|
||||
async storageState(progress, indexedDB = false) {
|
||||
return {
|
||||
cookies: this._cookieStore.allCookies(),
|
||||
origins: (this._origins || []).map((origin) => ({ ...origin, indexedDB: indexedDB ? origin.indexedDB : [] }))
|
||||
};
|
||||
}
|
||||
}
|
||||
function toHeadersArray(rawHeaders) {
|
||||
const result = [];
|
||||
for (let i = 0; i < rawHeaders.length; i += 2)
|
||||
result.push({ name: rawHeaders[i], value: rawHeaders[i + 1] });
|
||||
return result;
|
||||
}
|
||||
const redirectStatus = [301, 302, 303, 307, 308];
|
||||
function parseCookie(header) {
|
||||
const raw = (0, import_cookieStore.parseRawCookie)(header);
|
||||
if (!raw)
|
||||
return null;
|
||||
const cookie = {
|
||||
domain: "",
|
||||
path: "",
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
||||
// The cookie-sending behavior if SameSite is not specified is SameSite=Lax.
|
||||
sameSite: "Lax",
|
||||
...raw
|
||||
};
|
||||
return cookie;
|
||||
}
|
||||
function serializePostData(params, headers) {
|
||||
(0, import_utils.assert)((params.postData ? 1 : 0) + (params.jsonData ? 1 : 0) + (params.formData ? 1 : 0) + (params.multipartData ? 1 : 0) <= 1, `Only one of 'data', 'form' or 'multipart' can be specified`);
|
||||
if (params.jsonData !== void 0) {
|
||||
setHeader(headers, "content-type", "application/json", true);
|
||||
return Buffer.from(params.jsonData, "utf8");
|
||||
} else if (params.formData) {
|
||||
const searchParams = new URLSearchParams();
|
||||
for (const { name, value } of params.formData)
|
||||
searchParams.append(name, value);
|
||||
setHeader(headers, "content-type", "application/x-www-form-urlencoded", true);
|
||||
return Buffer.from(searchParams.toString(), "utf8");
|
||||
} else if (params.multipartData) {
|
||||
const formData = new import_formData.MultipartFormData();
|
||||
for (const field of params.multipartData) {
|
||||
if (field.file)
|
||||
formData.addFileField(field.name, field.file);
|
||||
else if (field.value)
|
||||
formData.addField(field.name, field.value);
|
||||
}
|
||||
setHeader(headers, "content-type", formData.contentTypeHeader(), true);
|
||||
return formData.finish();
|
||||
} else if (params.postData !== void 0) {
|
||||
setHeader(headers, "content-type", "application/octet-stream", true);
|
||||
return params.postData;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function setHeader(headers, name, value, keepExisting = false) {
|
||||
const existing = Object.entries(headers).find((pair) => pair[0].toLowerCase() === name.toLowerCase());
|
||||
if (!existing)
|
||||
headers[name] = value;
|
||||
else if (!keepExisting)
|
||||
headers[existing[0]] = value;
|
||||
}
|
||||
function getHeader(headers, name) {
|
||||
const existing = Object.entries(headers).find((pair) => pair[0].toLowerCase() === name.toLowerCase());
|
||||
return existing ? existing[1] : void 0;
|
||||
}
|
||||
function removeHeader(headers, name) {
|
||||
delete headers[name];
|
||||
}
|
||||
function setBasicAuthorizationHeader(headers, credentials) {
|
||||
const { username, password } = credentials;
|
||||
const encoded = Buffer.from(`${username || ""}:${password || ""}`).toString("base64");
|
||||
setHeader(headers, "authorization", `Basic ${encoded}`);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
APIRequestContext,
|
||||
BrowserContextAPIRequestContext,
|
||||
GlobalAPIRequestContext
|
||||
});
|
||||
43
.playwright-mcp/node_modules/playwright-core/lib/server/fileChooser.js
generated
vendored
Normal file
43
.playwright-mcp/node_modules/playwright-core/lib/server/fileChooser.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fileChooser_exports = {};
|
||||
__export(fileChooser_exports, {
|
||||
FileChooser: () => FileChooser
|
||||
});
|
||||
module.exports = __toCommonJS(fileChooser_exports);
|
||||
class FileChooser {
|
||||
constructor(page, elementHandle, isMultiple) {
|
||||
this._page = page;
|
||||
this._elementHandle = elementHandle;
|
||||
this._isMultiple = isMultiple;
|
||||
}
|
||||
element() {
|
||||
return this._elementHandle;
|
||||
}
|
||||
isMultiple() {
|
||||
return this._isMultiple;
|
||||
}
|
||||
page() {
|
||||
return this._page;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FileChooser
|
||||
});
|
||||
84
.playwright-mcp/node_modules/playwright-core/lib/server/fileUploadUtils.js
generated
vendored
Normal file
84
.playwright-mcp/node_modules/playwright-core/lib/server/fileUploadUtils.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fileUploadUtils_exports = {};
|
||||
__export(fileUploadUtils_exports, {
|
||||
fileUploadSizeLimit: () => fileUploadSizeLimit,
|
||||
prepareFilesForUpload: () => prepareFilesForUpload
|
||||
});
|
||||
module.exports = __toCommonJS(fileUploadUtils_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_assert = require("../utils/isomorphic/assert");
|
||||
var import_utilsBundle = require("../utilsBundle");
|
||||
const fileUploadSizeLimit = 50 * 1024 * 1024;
|
||||
async function filesExceedUploadLimit(files) {
|
||||
const sizes = await Promise.all(files.map(async (file) => (await import_fs.default.promises.stat(file)).size));
|
||||
return sizes.reduce((total, size) => total + size, 0) >= fileUploadSizeLimit;
|
||||
}
|
||||
async function prepareFilesForUpload(frame, params) {
|
||||
const { payloads, streams, directoryStream } = params;
|
||||
let { localPaths, localDirectory } = params;
|
||||
if ([payloads, localPaths, localDirectory, streams, directoryStream].filter(Boolean).length !== 1)
|
||||
throw new Error("Exactly one of payloads, localPaths and streams must be provided");
|
||||
if (streams)
|
||||
localPaths = streams.map((c) => c.path());
|
||||
if (directoryStream)
|
||||
localDirectory = directoryStream.path();
|
||||
if (localPaths) {
|
||||
for (const p of localPaths)
|
||||
(0, import_assert.assert)(import_path.default.isAbsolute(p) && import_path.default.resolve(p) === p, "Paths provided to localPaths must be absolute and fully resolved.");
|
||||
}
|
||||
let fileBuffers = payloads;
|
||||
if (!frame._page.browserContext._browser._isCollocatedWithServer) {
|
||||
if (localPaths) {
|
||||
if (await filesExceedUploadLimit(localPaths))
|
||||
throw new Error("Cannot transfer files larger than 50Mb to a browser not co-located with the server");
|
||||
fileBuffers = await Promise.all(localPaths.map(async (item) => {
|
||||
return {
|
||||
name: import_path.default.basename(item),
|
||||
buffer: await import_fs.default.promises.readFile(item),
|
||||
lastModifiedMs: (await import_fs.default.promises.stat(item)).mtimeMs
|
||||
};
|
||||
}));
|
||||
localPaths = void 0;
|
||||
}
|
||||
}
|
||||
const filePayloads = fileBuffers?.map((payload) => ({
|
||||
name: payload.name,
|
||||
mimeType: payload.mimeType || import_utilsBundle.mime.getType(payload.name) || "application/octet-stream",
|
||||
buffer: payload.buffer.toString("base64"),
|
||||
lastModifiedMs: payload.lastModifiedMs
|
||||
}));
|
||||
return { localPaths, localDirectory, filePayloads };
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
fileUploadSizeLimit,
|
||||
prepareFilesForUpload
|
||||
});
|
||||
428
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffBrowser.js
generated
vendored
Normal file
428
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffBrowser.js
generated
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffBrowser_exports = {};
|
||||
__export(ffBrowser_exports, {
|
||||
FFBrowser: () => FFBrowser,
|
||||
FFBrowserContext: () => FFBrowserContext
|
||||
});
|
||||
module.exports = __toCommonJS(ffBrowser_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_browser = require("../browser");
|
||||
var import_browserContext = require("../browserContext");
|
||||
var import_errors = require("../errors");
|
||||
var network = __toESM(require("../network"));
|
||||
var import_ffConnection = require("./ffConnection");
|
||||
var import_ffPage = require("./ffPage");
|
||||
var import_page = require("../page");
|
||||
class FFBrowser extends import_browser.Browser {
|
||||
constructor(parent, connection, options) {
|
||||
super(parent, options);
|
||||
this._version = "";
|
||||
this._userAgent = "";
|
||||
this._connection = connection;
|
||||
this.session = connection.rootSession;
|
||||
this._ffPages = /* @__PURE__ */ new Map();
|
||||
this._contexts = /* @__PURE__ */ new Map();
|
||||
this._connection.on(import_ffConnection.ConnectionEvents.Disconnected, () => this._onDisconnect());
|
||||
this.session.on("Browser.attachedToTarget", this._onAttachedToTarget.bind(this));
|
||||
this.session.on("Browser.detachedFromTarget", this._onDetachedFromTarget.bind(this));
|
||||
this.session.on("Browser.downloadCreated", this._onDownloadCreated.bind(this));
|
||||
this.session.on("Browser.downloadFinished", this._onDownloadFinished.bind(this));
|
||||
this.session.on("Browser.videoRecordingFinished", this._onVideoRecordingFinished.bind(this));
|
||||
}
|
||||
static async connect(parent, transport, options) {
|
||||
const connection = new import_ffConnection.FFConnection(transport, options.protocolLogger, options.browserLogsCollector);
|
||||
const browser = new FFBrowser(parent, connection, options);
|
||||
if (options.__testHookOnConnectToBrowser)
|
||||
await options.__testHookOnConnectToBrowser();
|
||||
let firefoxUserPrefs = options.originalLaunchOptions.firefoxUserPrefs ?? {};
|
||||
if (Object.keys(kBandaidFirefoxUserPrefs).length)
|
||||
firefoxUserPrefs = { ...kBandaidFirefoxUserPrefs, ...firefoxUserPrefs };
|
||||
const promises = [
|
||||
browser.session.send("Browser.enable", {
|
||||
attachToDefaultContext: !!options.persistent,
|
||||
userPrefs: Object.entries(firefoxUserPrefs).map(([name, value]) => ({ name, value }))
|
||||
}),
|
||||
browser._initVersion()
|
||||
];
|
||||
if (options.persistent) {
|
||||
browser._defaultContext = new FFBrowserContext(browser, void 0, options.persistent);
|
||||
promises.push(browser._defaultContext._initialize());
|
||||
}
|
||||
const proxy = options.originalLaunchOptions.proxyOverride || options.proxy;
|
||||
if (proxy)
|
||||
promises.push(browser.session.send("Browser.setBrowserProxy", toJugglerProxyOptions(proxy)));
|
||||
await Promise.all(promises);
|
||||
return browser;
|
||||
}
|
||||
async _initVersion() {
|
||||
const result = await this.session.send("Browser.getInfo");
|
||||
this._version = result.version.substring(result.version.indexOf("/") + 1);
|
||||
this._userAgent = result.userAgent;
|
||||
}
|
||||
isConnected() {
|
||||
return !this._connection._closed;
|
||||
}
|
||||
async doCreateNewContext(options) {
|
||||
if (options.isMobile)
|
||||
throw new Error("options.isMobile is not supported in Firefox");
|
||||
const { browserContextId } = await this.session.send("Browser.createBrowserContext", { removeOnDetach: true });
|
||||
const context = new FFBrowserContext(this, browserContextId, options);
|
||||
await context._initialize();
|
||||
this._contexts.set(browserContextId, context);
|
||||
return context;
|
||||
}
|
||||
contexts() {
|
||||
return Array.from(this._contexts.values());
|
||||
}
|
||||
version() {
|
||||
return this._version;
|
||||
}
|
||||
userAgent() {
|
||||
return this._userAgent;
|
||||
}
|
||||
_onDetachedFromTarget(payload) {
|
||||
const ffPage = this._ffPages.get(payload.targetId);
|
||||
this._ffPages.delete(payload.targetId);
|
||||
ffPage.didClose();
|
||||
}
|
||||
_onAttachedToTarget(payload) {
|
||||
const { targetId, browserContextId, openerId, type } = payload.targetInfo;
|
||||
(0, import_utils.assert)(type === "page");
|
||||
const context = browserContextId ? this._contexts.get(browserContextId) : this._defaultContext;
|
||||
(0, import_utils.assert)(context, `Unknown context id:${browserContextId}, _defaultContext: ${this._defaultContext}`);
|
||||
const session = this._connection.createSession(payload.sessionId);
|
||||
const opener = openerId ? this._ffPages.get(openerId) : null;
|
||||
const ffPage = new import_ffPage.FFPage(session, context, opener);
|
||||
this._ffPages.set(targetId, ffPage);
|
||||
}
|
||||
_onDownloadCreated(payload) {
|
||||
const ffPage = this._ffPages.get(payload.pageTargetId);
|
||||
if (!ffPage)
|
||||
return;
|
||||
ffPage._page.frameManager.frameAbortedNavigation(payload.frameId, "Download is starting");
|
||||
let originPage = ffPage._page.initializedOrUndefined();
|
||||
if (!originPage) {
|
||||
ffPage._markAsError(new Error("Starting new page download"));
|
||||
if (ffPage._opener)
|
||||
originPage = ffPage._opener._page.initializedOrUndefined();
|
||||
}
|
||||
if (!originPage)
|
||||
return;
|
||||
this._downloadCreated(originPage, payload.uuid, payload.url, payload.suggestedFileName);
|
||||
}
|
||||
_onDownloadFinished(payload) {
|
||||
const error = payload.canceled ? "canceled" : payload.error;
|
||||
this._downloadFinished(payload.uuid, error);
|
||||
}
|
||||
_onVideoRecordingFinished(payload) {
|
||||
this._takeVideo(payload.screencastId)?.reportFinished();
|
||||
}
|
||||
_onDisconnect() {
|
||||
for (const video of this._idToVideo.values())
|
||||
video.artifact.reportFinished(new import_errors.TargetClosedError());
|
||||
this._idToVideo.clear();
|
||||
for (const ffPage of this._ffPages.values())
|
||||
ffPage.didClose();
|
||||
this._ffPages.clear();
|
||||
this._didClose();
|
||||
}
|
||||
}
|
||||
class FFBrowserContext extends import_browserContext.BrowserContext {
|
||||
constructor(browser, browserContextId, options) {
|
||||
super(browser, options, browserContextId);
|
||||
}
|
||||
async _initialize() {
|
||||
(0, import_utils.assert)(!this._ffPages().length);
|
||||
const browserContextId = this._browserContextId;
|
||||
const promises = [
|
||||
super._initialize(),
|
||||
this._updateInitScripts()
|
||||
];
|
||||
if (this._options.acceptDownloads !== "internal-browser-default") {
|
||||
promises.push(this._browser.session.send("Browser.setDownloadOptions", {
|
||||
browserContextId,
|
||||
downloadOptions: {
|
||||
behavior: this._options.acceptDownloads === "accept" ? "saveToDisk" : "cancel",
|
||||
downloadsDir: this._browser.options.downloadsPath
|
||||
}
|
||||
}));
|
||||
}
|
||||
promises.push(this.doUpdateDefaultViewport());
|
||||
if (this._options.hasTouch)
|
||||
promises.push(this._browser.session.send("Browser.setTouchOverride", { browserContextId, hasTouch: true }));
|
||||
if (this._options.userAgent)
|
||||
promises.push(this._browser.session.send("Browser.setUserAgentOverride", { browserContextId, userAgent: this._options.userAgent }));
|
||||
if (this._options.bypassCSP)
|
||||
promises.push(this._browser.session.send("Browser.setBypassCSP", { browserContextId, bypassCSP: true }));
|
||||
if (this._options.ignoreHTTPSErrors || this._options.internalIgnoreHTTPSErrors)
|
||||
promises.push(this._browser.session.send("Browser.setIgnoreHTTPSErrors", { browserContextId, ignoreHTTPSErrors: true }));
|
||||
if (this._options.javaScriptEnabled === false)
|
||||
promises.push(this._browser.session.send("Browser.setJavaScriptDisabled", { browserContextId, javaScriptDisabled: true }));
|
||||
if (this._options.locale)
|
||||
promises.push(this._browser.session.send("Browser.setLocaleOverride", { browserContextId, locale: this._options.locale }));
|
||||
if (this._options.timezoneId)
|
||||
promises.push(this._browser.session.send("Browser.setTimezoneOverride", { browserContextId, timezoneId: this._options.timezoneId }));
|
||||
if (this._options.extraHTTPHeaders || this._options.locale)
|
||||
promises.push(this.doUpdateExtraHTTPHeaders());
|
||||
if (this._options.httpCredentials)
|
||||
promises.push(this.setHTTPCredentials(this._options.httpCredentials));
|
||||
if (this._options.geolocation)
|
||||
promises.push(this.setGeolocation(this._options.geolocation));
|
||||
if (this._options.offline)
|
||||
promises.push(this.doUpdateOffline());
|
||||
promises.push(this.doUpdateDefaultEmulatedMedia());
|
||||
if (this._options.recordVideo) {
|
||||
promises.push(this._ensureVideosPath().then(() => {
|
||||
return this._browser.session.send("Browser.setVideoRecordingOptions", {
|
||||
// validateBrowserContextOptions ensures correct video size.
|
||||
options: {
|
||||
...this._options.recordVideo.size,
|
||||
dir: this._options.recordVideo.dir
|
||||
},
|
||||
browserContextId: this._browserContextId
|
||||
});
|
||||
}));
|
||||
}
|
||||
const proxy = this._options.proxyOverride || this._options.proxy;
|
||||
if (proxy) {
|
||||
promises.push(this._browser.session.send("Browser.setContextProxy", {
|
||||
browserContextId: this._browserContextId,
|
||||
...toJugglerProxyOptions(proxy)
|
||||
}));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
}
|
||||
_ffPages() {
|
||||
return Array.from(this._browser._ffPages.values()).filter((ffPage) => ffPage._browserContext === this);
|
||||
}
|
||||
possiblyUninitializedPages() {
|
||||
return this._ffPages().map((ffPage) => ffPage._page);
|
||||
}
|
||||
async doCreateNewPage() {
|
||||
const { targetId } = await this._browser.session.send("Browser.newPage", {
|
||||
browserContextId: this._browserContextId
|
||||
}).catch((e) => {
|
||||
if (e.message.includes("Failed to override timezone"))
|
||||
throw new Error(`Invalid timezone ID: ${this._options.timezoneId}`);
|
||||
throw e;
|
||||
});
|
||||
return this._browser._ffPages.get(targetId)._page;
|
||||
}
|
||||
async doGetCookies(urls) {
|
||||
const { cookies } = await this._browser.session.send("Browser.getCookies", { browserContextId: this._browserContextId });
|
||||
return network.filterCookies(cookies.map((c) => {
|
||||
const { name, value, domain, path, expires, httpOnly, secure, sameSite } = c;
|
||||
return {
|
||||
name,
|
||||
value,
|
||||
domain,
|
||||
path,
|
||||
expires,
|
||||
httpOnly,
|
||||
secure,
|
||||
sameSite
|
||||
};
|
||||
}), urls);
|
||||
}
|
||||
async addCookies(cookies) {
|
||||
const cc = network.rewriteCookies(cookies).map((c) => {
|
||||
const { name, value, url, domain, path, expires, httpOnly, secure, sameSite } = c;
|
||||
return {
|
||||
name,
|
||||
value,
|
||||
url,
|
||||
domain,
|
||||
path,
|
||||
expires: expires === -1 ? void 0 : expires,
|
||||
httpOnly,
|
||||
secure,
|
||||
sameSite
|
||||
};
|
||||
});
|
||||
await this._browser.session.send("Browser.setCookies", { browserContextId: this._browserContextId, cookies: cc });
|
||||
}
|
||||
async doClearCookies() {
|
||||
await this._browser.session.send("Browser.clearCookies", { browserContextId: this._browserContextId });
|
||||
}
|
||||
async doGrantPermissions(origin, permissions) {
|
||||
const webPermissionToProtocol = /* @__PURE__ */ new Map([
|
||||
["geolocation", "geo"],
|
||||
["persistent-storage", "persistent-storage"],
|
||||
["push", "push"],
|
||||
["notifications", "desktop-notification"]
|
||||
]);
|
||||
const filtered = permissions.map((permission) => {
|
||||
const protocolPermission = webPermissionToProtocol.get(permission);
|
||||
if (!protocolPermission)
|
||||
throw new Error("Unknown permission: " + permission);
|
||||
return protocolPermission;
|
||||
});
|
||||
await this._browser.session.send("Browser.grantPermissions", { origin, browserContextId: this._browserContextId, permissions: filtered });
|
||||
}
|
||||
async doClearPermissions() {
|
||||
await this._browser.session.send("Browser.resetPermissions", { browserContextId: this._browserContextId });
|
||||
}
|
||||
async setGeolocation(geolocation) {
|
||||
(0, import_browserContext.verifyGeolocation)(geolocation);
|
||||
this._options.geolocation = geolocation;
|
||||
await this._browser.session.send("Browser.setGeolocationOverride", { browserContextId: this._browserContextId, geolocation: geolocation || null });
|
||||
}
|
||||
async doUpdateExtraHTTPHeaders() {
|
||||
let allHeaders = this._options.extraHTTPHeaders || [];
|
||||
if (this._options.locale)
|
||||
allHeaders = network.mergeHeaders([allHeaders, network.singleHeader("Accept-Language", this._options.locale)]);
|
||||
await this._browser.session.send("Browser.setExtraHTTPHeaders", { browserContextId: this._browserContextId, headers: allHeaders });
|
||||
}
|
||||
async setUserAgent(userAgent) {
|
||||
await this._browser.session.send("Browser.setUserAgentOverride", { browserContextId: this._browserContextId, userAgent: userAgent || null });
|
||||
}
|
||||
async doUpdateOffline() {
|
||||
await this._browser.session.send("Browser.setOnlineOverride", { browserContextId: this._browserContextId, override: this._options.offline ? "offline" : "online" });
|
||||
}
|
||||
async doSetHTTPCredentials(httpCredentials) {
|
||||
this._options.httpCredentials = httpCredentials;
|
||||
let credentials = null;
|
||||
if (httpCredentials) {
|
||||
const { username, password, origin } = httpCredentials;
|
||||
credentials = { username, password, origin };
|
||||
}
|
||||
await this._browser.session.send("Browser.setHTTPCredentials", { browserContextId: this._browserContextId, credentials });
|
||||
}
|
||||
async doAddInitScript(initScript) {
|
||||
await this._updateInitScripts();
|
||||
}
|
||||
async doRemoveInitScripts(initScripts) {
|
||||
await this._updateInitScripts();
|
||||
}
|
||||
async _updateInitScripts() {
|
||||
const bindingScripts = [...this._pageBindings.values()].map((binding) => binding.initScript.source);
|
||||
if (this.bindingsInitScript)
|
||||
bindingScripts.unshift(this.bindingsInitScript.source);
|
||||
const initScripts = this.initScripts.map((script) => script.source);
|
||||
await this._browser.session.send("Browser.setInitScripts", { browserContextId: this._browserContextId, scripts: [...bindingScripts, ...initScripts].map((script) => ({ script })) });
|
||||
}
|
||||
async doUpdateRequestInterception() {
|
||||
await Promise.all([
|
||||
this._browser.session.send("Browser.setRequestInterception", { browserContextId: this._browserContextId, enabled: this.requestInterceptors.length > 0 }),
|
||||
this._browser.session.send("Browser.setCacheDisabled", { browserContextId: this._browserContextId, cacheDisabled: this.requestInterceptors.length > 0 })
|
||||
]);
|
||||
}
|
||||
async doUpdateDefaultViewport() {
|
||||
if (!this._options.viewport)
|
||||
return;
|
||||
const viewport = {
|
||||
viewportSize: { width: this._options.viewport.width, height: this._options.viewport.height },
|
||||
deviceScaleFactor: this._options.deviceScaleFactor || 1
|
||||
};
|
||||
await this._browser.session.send("Browser.setDefaultViewport", { browserContextId: this._browserContextId, viewport });
|
||||
}
|
||||
async doUpdateDefaultEmulatedMedia() {
|
||||
if (this._options.colorScheme !== "no-override") {
|
||||
await this._browser.session.send("Browser.setColorScheme", {
|
||||
browserContextId: this._browserContextId,
|
||||
colorScheme: this._options.colorScheme !== void 0 ? this._options.colorScheme : "light"
|
||||
});
|
||||
}
|
||||
if (this._options.reducedMotion !== "no-override") {
|
||||
await this._browser.session.send("Browser.setReducedMotion", {
|
||||
browserContextId: this._browserContextId,
|
||||
reducedMotion: this._options.reducedMotion !== void 0 ? this._options.reducedMotion : "no-preference"
|
||||
});
|
||||
}
|
||||
if (this._options.forcedColors !== "no-override") {
|
||||
await this._browser.session.send("Browser.setForcedColors", {
|
||||
browserContextId: this._browserContextId,
|
||||
forcedColors: this._options.forcedColors !== void 0 ? this._options.forcedColors : "none"
|
||||
});
|
||||
}
|
||||
if (this._options.contrast !== "no-override") {
|
||||
await this._browser.session.send("Browser.setContrast", {
|
||||
browserContextId: this._browserContextId,
|
||||
contrast: this._options.contrast !== void 0 ? this._options.contrast : "no-preference"
|
||||
});
|
||||
}
|
||||
}
|
||||
async doExposePlaywrightBinding() {
|
||||
this._browser.session.send("Browser.addBinding", { browserContextId: this._browserContextId, name: import_page.PageBinding.kBindingName, script: "" });
|
||||
}
|
||||
onClosePersistent() {
|
||||
}
|
||||
async clearCache() {
|
||||
await this._browser.session.send("Browser.clearCache");
|
||||
}
|
||||
async doClose(reason) {
|
||||
if (!this._browserContextId) {
|
||||
if (this._options.recordVideo) {
|
||||
await this._browser.session.send("Browser.setVideoRecordingOptions", {
|
||||
options: void 0,
|
||||
browserContextId: this._browserContextId
|
||||
});
|
||||
}
|
||||
await this._browser.close({ reason });
|
||||
} else {
|
||||
await this._browser.session.send("Browser.removeBrowserContext", { browserContextId: this._browserContextId });
|
||||
this._browser._contexts.delete(this._browserContextId);
|
||||
}
|
||||
}
|
||||
async cancelDownload(uuid) {
|
||||
await this._browser.session.send("Browser.cancelDownload", { uuid });
|
||||
}
|
||||
}
|
||||
function toJugglerProxyOptions(proxy) {
|
||||
const proxyServer = new URL(proxy.server);
|
||||
let port = parseInt(proxyServer.port, 10);
|
||||
let type = "http";
|
||||
if (proxyServer.protocol === "socks5:")
|
||||
type = "socks";
|
||||
else if (proxyServer.protocol === "socks4:")
|
||||
type = "socks4";
|
||||
else if (proxyServer.protocol === "https:")
|
||||
type = "https";
|
||||
if (proxyServer.port === "") {
|
||||
if (proxyServer.protocol === "http:")
|
||||
port = 80;
|
||||
else if (proxyServer.protocol === "https:")
|
||||
port = 443;
|
||||
}
|
||||
return {
|
||||
type,
|
||||
bypass: proxy.bypass ? proxy.bypass.split(",").map((domain) => domain.trim()) : [],
|
||||
host: proxyServer.hostname,
|
||||
port,
|
||||
username: proxy.username,
|
||||
password: proxy.password
|
||||
};
|
||||
}
|
||||
const kBandaidFirefoxUserPrefs = {};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FFBrowser,
|
||||
FFBrowserContext
|
||||
});
|
||||
147
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffConnection.js
generated
vendored
Normal file
147
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffConnection.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffConnection_exports = {};
|
||||
__export(ffConnection_exports, {
|
||||
ConnectionEvents: () => ConnectionEvents,
|
||||
FFConnection: () => FFConnection,
|
||||
FFSession: () => FFSession,
|
||||
kBrowserCloseMessageId: () => kBrowserCloseMessageId
|
||||
});
|
||||
module.exports = __toCommonJS(ffConnection_exports);
|
||||
var import_events = require("events");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_helper = require("../helper");
|
||||
var import_protocolError = require("../protocolError");
|
||||
const ConnectionEvents = {
|
||||
Disconnected: Symbol("Disconnected")
|
||||
};
|
||||
const kBrowserCloseMessageId = -9999;
|
||||
class FFConnection extends import_events.EventEmitter {
|
||||
constructor(transport, protocolLogger, browserLogsCollector) {
|
||||
super();
|
||||
this.setMaxListeners(0);
|
||||
this._transport = transport;
|
||||
this._protocolLogger = protocolLogger;
|
||||
this._browserLogsCollector = browserLogsCollector;
|
||||
this._lastId = 0;
|
||||
this._sessions = /* @__PURE__ */ new Map();
|
||||
this._closed = false;
|
||||
this.rootSession = new FFSession(this, "", (message) => this._rawSend(message));
|
||||
this._sessions.set("", this.rootSession);
|
||||
this._transport.onmessage = this._onMessage.bind(this);
|
||||
this._transport.onclose = this._onClose.bind(this);
|
||||
}
|
||||
nextMessageId() {
|
||||
return ++this._lastId;
|
||||
}
|
||||
_rawSend(message) {
|
||||
this._protocolLogger("send", message);
|
||||
this._transport.send(message);
|
||||
}
|
||||
async _onMessage(message) {
|
||||
this._protocolLogger("receive", message);
|
||||
if (message.id === kBrowserCloseMessageId)
|
||||
return;
|
||||
const session = this._sessions.get(message.sessionId || "");
|
||||
if (session)
|
||||
session.dispatchMessage(message);
|
||||
}
|
||||
_onClose(reason) {
|
||||
this._closed = true;
|
||||
this._transport.onmessage = void 0;
|
||||
this._transport.onclose = void 0;
|
||||
this._browserDisconnectedLogs = import_helper.helper.formatBrowserLogs(this._browserLogsCollector.recentLogs(), reason);
|
||||
this.rootSession.dispose();
|
||||
Promise.resolve().then(() => this.emit(ConnectionEvents.Disconnected));
|
||||
}
|
||||
close() {
|
||||
if (!this._closed)
|
||||
this._transport.close();
|
||||
}
|
||||
createSession(sessionId) {
|
||||
const session = new FFSession(this, sessionId, (message) => this._rawSend({ ...message, sessionId }));
|
||||
this._sessions.set(sessionId, session);
|
||||
return session;
|
||||
}
|
||||
}
|
||||
class FFSession extends import_events.EventEmitter {
|
||||
constructor(connection, sessionId, rawSend) {
|
||||
super();
|
||||
this._disposed = false;
|
||||
this._crashed = false;
|
||||
this.setMaxListeners(0);
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._connection = connection;
|
||||
this._sessionId = sessionId;
|
||||
this._rawSend = rawSend;
|
||||
this.on = super.on;
|
||||
this.addListener = super.addListener;
|
||||
this.off = super.removeListener;
|
||||
this.removeListener = super.removeListener;
|
||||
this.once = super.once;
|
||||
}
|
||||
markAsCrashed() {
|
||||
this._crashed = true;
|
||||
}
|
||||
async send(method, params) {
|
||||
if (this._crashed || this._disposed || this._connection._closed || this._connection._browserDisconnectedLogs)
|
||||
throw new import_protocolError.ProtocolError(this._crashed ? "crashed" : "closed", void 0, this._connection._browserDisconnectedLogs);
|
||||
const id = this._connection.nextMessageId();
|
||||
this._rawSend({ method, params, id });
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject, error: new import_protocolError.ProtocolError("error", method) });
|
||||
});
|
||||
}
|
||||
sendMayFail(method, params) {
|
||||
return this.send(method, params).catch((error) => import_debugLogger.debugLogger.log("error", error));
|
||||
}
|
||||
dispatchMessage(object) {
|
||||
if (object.id) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
if (callback) {
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error) {
|
||||
callback.error.setMessage(object.error.message);
|
||||
callback.reject(callback.error);
|
||||
} else {
|
||||
callback.resolve(object.result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Promise.resolve().then(() => this.emit(object.method, object.params));
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
this._connection._sessions.delete(this._sessionId);
|
||||
for (const callback of this._callbacks.values()) {
|
||||
callback.error.type = this._crashed ? "crashed" : "closed";
|
||||
callback.error.logs = this._connection._browserDisconnectedLogs;
|
||||
callback.reject(callback.error);
|
||||
}
|
||||
this._callbacks.clear();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ConnectionEvents,
|
||||
FFConnection,
|
||||
FFSession,
|
||||
kBrowserCloseMessageId
|
||||
});
|
||||
150
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffExecutionContext.js
generated
vendored
Normal file
150
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffExecutionContext.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffExecutionContext_exports = {};
|
||||
__export(ffExecutionContext_exports, {
|
||||
FFExecutionContext: () => FFExecutionContext,
|
||||
createHandle: () => createHandle
|
||||
});
|
||||
module.exports = __toCommonJS(ffExecutionContext_exports);
|
||||
var import_assert = require("../../utils/isomorphic/assert");
|
||||
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
||||
var import_utilityScriptSerializers = require("../../utils/isomorphic/utilityScriptSerializers");
|
||||
var js = __toESM(require("../javascript"));
|
||||
var dom = __toESM(require("../dom"));
|
||||
var import_protocolError = require("../protocolError");
|
||||
class FFExecutionContext {
|
||||
constructor(session, executionContextId) {
|
||||
this._session = session;
|
||||
this._executionContextId = executionContextId;
|
||||
}
|
||||
async rawEvaluateJSON(expression) {
|
||||
const payload = await this._session.send("Runtime.evaluate", {
|
||||
expression,
|
||||
returnByValue: true,
|
||||
executionContextId: this._executionContextId
|
||||
}).catch(rewriteError);
|
||||
checkException(payload.exceptionDetails);
|
||||
return payload.result.value;
|
||||
}
|
||||
async rawEvaluateHandle(context, expression) {
|
||||
const payload = await this._session.send("Runtime.evaluate", {
|
||||
expression,
|
||||
returnByValue: false,
|
||||
executionContextId: this._executionContextId
|
||||
}).catch(rewriteError);
|
||||
checkException(payload.exceptionDetails);
|
||||
return createHandle(context, payload.result);
|
||||
}
|
||||
async evaluateWithArguments(expression, returnByValue, utilityScript, values, handles) {
|
||||
const payload = await this._session.send("Runtime.callFunction", {
|
||||
functionDeclaration: expression,
|
||||
args: [
|
||||
{ objectId: utilityScript._objectId, value: void 0 },
|
||||
...values.map((value) => ({ value })),
|
||||
...handles.map((handle) => ({ objectId: handle._objectId, value: void 0 }))
|
||||
],
|
||||
returnByValue,
|
||||
executionContextId: this._executionContextId
|
||||
}).catch(rewriteError);
|
||||
checkException(payload.exceptionDetails);
|
||||
if (returnByValue)
|
||||
return (0, import_utilityScriptSerializers.parseEvaluationResultValue)(payload.result.value);
|
||||
return createHandle(utilityScript._context, payload.result);
|
||||
}
|
||||
async getProperties(object) {
|
||||
const response = await this._session.send("Runtime.getObjectProperties", {
|
||||
executionContextId: this._executionContextId,
|
||||
objectId: object._objectId
|
||||
});
|
||||
const result = /* @__PURE__ */ new Map();
|
||||
for (const property of response.properties)
|
||||
result.set(property.name, createHandle(object._context, property.value));
|
||||
return result;
|
||||
}
|
||||
async releaseHandle(handle) {
|
||||
if (!handle._objectId)
|
||||
return;
|
||||
await this._session.send("Runtime.disposeObject", {
|
||||
executionContextId: this._executionContextId,
|
||||
objectId: handle._objectId
|
||||
});
|
||||
}
|
||||
}
|
||||
function checkException(exceptionDetails) {
|
||||
if (!exceptionDetails)
|
||||
return;
|
||||
if (exceptionDetails.value)
|
||||
throw new js.JavaScriptErrorInEvaluate(JSON.stringify(exceptionDetails.value));
|
||||
else
|
||||
throw new js.JavaScriptErrorInEvaluate(exceptionDetails.text + (exceptionDetails.stack ? "\n" + exceptionDetails.stack : ""));
|
||||
}
|
||||
function rewriteError(error) {
|
||||
if (error.message.includes("cyclic object value") || error.message.includes("Object is not serializable"))
|
||||
return { result: { type: "undefined", value: void 0 } };
|
||||
if (error instanceof TypeError && error.message.startsWith("Converting circular structure to JSON"))
|
||||
(0, import_stackTrace.rewriteErrorMessage)(error, error.message + " Are you passing a nested JSHandle?");
|
||||
if (!js.isJavaScriptErrorInEvaluate(error) && !(0, import_protocolError.isSessionClosedError)(error))
|
||||
throw new Error("Execution context was destroyed, most likely because of a navigation.");
|
||||
throw error;
|
||||
}
|
||||
function potentiallyUnserializableValue(remoteObject) {
|
||||
const value = remoteObject.value;
|
||||
const unserializableValue = remoteObject.unserializableValue;
|
||||
return unserializableValue ? js.parseUnserializableValue(unserializableValue) : value;
|
||||
}
|
||||
function renderPreview(object) {
|
||||
if (object.type === "undefined")
|
||||
return "undefined";
|
||||
if (object.unserializableValue)
|
||||
return String(object.unserializableValue);
|
||||
if (object.type === "symbol")
|
||||
return "Symbol()";
|
||||
if (object.subtype === "regexp")
|
||||
return "RegExp";
|
||||
if (object.subtype === "weakmap")
|
||||
return "WeakMap";
|
||||
if (object.subtype === "weakset")
|
||||
return "WeakSet";
|
||||
if (object.subtype)
|
||||
return object.subtype[0].toUpperCase() + object.subtype.slice(1);
|
||||
if ("value" in object)
|
||||
return String(object.value);
|
||||
}
|
||||
function createHandle(context, remoteObject) {
|
||||
if (remoteObject.subtype === "node") {
|
||||
(0, import_assert.assert)(context instanceof dom.FrameExecutionContext);
|
||||
return new dom.ElementHandle(context, remoteObject.objectId);
|
||||
}
|
||||
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type || "", renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FFExecutionContext,
|
||||
createHandle
|
||||
});
|
||||
159
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffInput.js
generated
vendored
Normal file
159
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffInput.js
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffInput_exports = {};
|
||||
__export(ffInput_exports, {
|
||||
RawKeyboardImpl: () => RawKeyboardImpl,
|
||||
RawMouseImpl: () => RawMouseImpl,
|
||||
RawTouchscreenImpl: () => RawTouchscreenImpl
|
||||
});
|
||||
module.exports = __toCommonJS(ffInput_exports);
|
||||
function toModifiersMask(modifiers) {
|
||||
let mask = 0;
|
||||
if (modifiers.has("Alt"))
|
||||
mask |= 1;
|
||||
if (modifiers.has("Control"))
|
||||
mask |= 2;
|
||||
if (modifiers.has("Shift"))
|
||||
mask |= 4;
|
||||
if (modifiers.has("Meta"))
|
||||
mask |= 8;
|
||||
return mask;
|
||||
}
|
||||
function toButtonNumber(button) {
|
||||
if (button === "left")
|
||||
return 0;
|
||||
if (button === "middle")
|
||||
return 1;
|
||||
if (button === "right")
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
function toButtonsMask(buttons) {
|
||||
let mask = 0;
|
||||
if (buttons.has("left"))
|
||||
mask |= 1;
|
||||
if (buttons.has("right"))
|
||||
mask |= 2;
|
||||
if (buttons.has("middle"))
|
||||
mask |= 4;
|
||||
return mask;
|
||||
}
|
||||
class RawKeyboardImpl {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
}
|
||||
async keydown(progress, modifiers, keyName, description, autoRepeat) {
|
||||
let text = description.text;
|
||||
if (text === "\r")
|
||||
text = "";
|
||||
const { code, key, location } = description;
|
||||
await progress.race(this._client.send("Page.dispatchKeyEvent", {
|
||||
type: "keydown",
|
||||
keyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
key,
|
||||
repeat: autoRepeat,
|
||||
location,
|
||||
text
|
||||
}));
|
||||
}
|
||||
async keyup(progress, modifiers, keyName, description) {
|
||||
const { code, key, location } = description;
|
||||
await progress.race(this._client.send("Page.dispatchKeyEvent", {
|
||||
type: "keyup",
|
||||
key,
|
||||
keyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
location,
|
||||
repeat: false
|
||||
}));
|
||||
}
|
||||
async sendText(progress, text) {
|
||||
await progress.race(this._client.send("Page.insertText", { text }));
|
||||
}
|
||||
}
|
||||
class RawMouseImpl {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
}
|
||||
async move(progress, x, y, button, buttons, modifiers, forClick) {
|
||||
await progress.race(this._client.send("Page.dispatchMouseEvent", {
|
||||
type: "mousemove",
|
||||
button: 0,
|
||||
buttons: toButtonsMask(buttons),
|
||||
x: Math.floor(x),
|
||||
y: Math.floor(y),
|
||||
modifiers: toModifiersMask(modifiers)
|
||||
}));
|
||||
}
|
||||
async down(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
await progress.race(this._client.send("Page.dispatchMouseEvent", {
|
||||
type: "mousedown",
|
||||
button: toButtonNumber(button),
|
||||
buttons: toButtonsMask(buttons),
|
||||
x: Math.floor(x),
|
||||
y: Math.floor(y),
|
||||
modifiers: toModifiersMask(modifiers),
|
||||
clickCount
|
||||
}));
|
||||
}
|
||||
async up(progress, x, y, button, buttons, modifiers, clickCount) {
|
||||
await progress.race(this._client.send("Page.dispatchMouseEvent", {
|
||||
type: "mouseup",
|
||||
button: toButtonNumber(button),
|
||||
buttons: toButtonsMask(buttons),
|
||||
x: Math.floor(x),
|
||||
y: Math.floor(y),
|
||||
modifiers: toModifiersMask(modifiers),
|
||||
clickCount
|
||||
}));
|
||||
}
|
||||
async wheel(progress, x, y, buttons, modifiers, deltaX, deltaY) {
|
||||
await this._page.mainFrame().evaluateExpression(`new Promise(requestAnimationFrame)`, { world: "utility" });
|
||||
await progress.race(this._client.send("Page.dispatchWheelEvent", {
|
||||
deltaX,
|
||||
deltaY,
|
||||
x: Math.floor(x),
|
||||
y: Math.floor(y),
|
||||
deltaZ: 0,
|
||||
modifiers: toModifiersMask(modifiers)
|
||||
}));
|
||||
}
|
||||
setPage(page) {
|
||||
this._page = page;
|
||||
}
|
||||
}
|
||||
class RawTouchscreenImpl {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
}
|
||||
async tap(progress, x, y, modifiers) {
|
||||
await progress.race(this._client.send("Page.dispatchTapEvent", {
|
||||
x,
|
||||
y,
|
||||
modifiers: toModifiersMask(modifiers)
|
||||
}));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
RawKeyboardImpl,
|
||||
RawMouseImpl,
|
||||
RawTouchscreenImpl
|
||||
});
|
||||
256
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffNetworkManager.js
generated
vendored
Normal file
256
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffNetworkManager.js
generated
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffNetworkManager_exports = {};
|
||||
__export(ffNetworkManager_exports, {
|
||||
FFNetworkManager: () => FFNetworkManager
|
||||
});
|
||||
module.exports = __toCommonJS(ffNetworkManager_exports);
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var network = __toESM(require("../network"));
|
||||
class FFNetworkManager {
|
||||
constructor(session, page) {
|
||||
this._session = session;
|
||||
this._requests = /* @__PURE__ */ new Map();
|
||||
this._page = page;
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestWillBeSent", this._onRequestWillBeSent.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.responseReceived", this._onResponseReceived.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestFinished", this._onRequestFinished.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(session, "Network.requestFailed", this._onRequestFailed.bind(this))
|
||||
];
|
||||
}
|
||||
dispose() {
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
}
|
||||
async setRequestInterception(enabled) {
|
||||
await Promise.all([
|
||||
this._session.send("Network.setRequestInterception", { enabled }),
|
||||
this._session.send("Page.setCacheDisabled", { cacheDisabled: enabled })
|
||||
]);
|
||||
}
|
||||
_onRequestWillBeSent(event) {
|
||||
const redirectedFrom = event.redirectedFrom ? this._requests.get(event.redirectedFrom) || null : null;
|
||||
const frame = redirectedFrom ? redirectedFrom.request.frame() : event.frameId ? this._page.frameManager.frame(event.frameId) : null;
|
||||
if (!frame)
|
||||
return;
|
||||
if (event.method === "OPTIONS" && !event.isIntercepted)
|
||||
return;
|
||||
if (redirectedFrom)
|
||||
this._requests.delete(redirectedFrom._id);
|
||||
const request = new InterceptableRequest(frame, redirectedFrom, event);
|
||||
let route;
|
||||
if (event.isIntercepted)
|
||||
route = new FFRouteImpl(this._session, request);
|
||||
this._requests.set(request._id, request);
|
||||
this._page.frameManager.requestStarted(request.request, route);
|
||||
}
|
||||
_onResponseReceived(event) {
|
||||
const request = this._requests.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
const getResponseBody = async () => {
|
||||
const response2 = await this._session.send("Network.getResponseBody", {
|
||||
requestId: request._id
|
||||
});
|
||||
if (response2.evicted)
|
||||
throw new Error(`Response body for ${request.request.method()} ${request.request.url()} was evicted!`);
|
||||
return Buffer.from(response2.base64body, "base64");
|
||||
};
|
||||
const startTime = event.timing.startTime;
|
||||
function relativeToStart(time) {
|
||||
if (!time)
|
||||
return -1;
|
||||
return (time - startTime) / 1e3;
|
||||
}
|
||||
const timing = {
|
||||
startTime: startTime / 1e3,
|
||||
domainLookupStart: relativeToStart(event.timing.domainLookupStart),
|
||||
domainLookupEnd: relativeToStart(event.timing.domainLookupEnd),
|
||||
connectStart: relativeToStart(event.timing.connectStart),
|
||||
secureConnectionStart: relativeToStart(event.timing.secureConnectionStart),
|
||||
connectEnd: relativeToStart(event.timing.connectEnd),
|
||||
requestStart: relativeToStart(event.timing.requestStart),
|
||||
responseStart: relativeToStart(event.timing.responseStart)
|
||||
};
|
||||
const response = new network.Response(request.request, event.status, event.statusText, parseMultivalueHeaders(event.headers), timing, getResponseBody, event.fromServiceWorker);
|
||||
if (event?.remoteIPAddress && typeof event?.remotePort === "number") {
|
||||
response._serverAddrFinished({
|
||||
ipAddress: event.remoteIPAddress,
|
||||
port: event.remotePort
|
||||
});
|
||||
} else {
|
||||
response._serverAddrFinished();
|
||||
}
|
||||
response._securityDetailsFinished({
|
||||
protocol: event?.securityDetails?.protocol,
|
||||
subjectName: event?.securityDetails?.subjectName,
|
||||
issuer: event?.securityDetails?.issuer,
|
||||
validFrom: event?.securityDetails?.validFrom,
|
||||
validTo: event?.securityDetails?.validTo
|
||||
});
|
||||
response.setRawResponseHeaders(null);
|
||||
response.setResponseHeadersSize(null);
|
||||
this._page.frameManager.requestReceivedResponse(response);
|
||||
}
|
||||
_onRequestFinished(event) {
|
||||
const request = this._requests.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
const response = request.request._existingResponse();
|
||||
response.setTransferSize(event.transferSize);
|
||||
response.setEncodedBodySize(event.encodedBodySize);
|
||||
const isRedirected = response.status() >= 300 && response.status() <= 399;
|
||||
const responseEndTime = event.responseEndTime ? event.responseEndTime / 1e3 - response.timing().startTime : -1;
|
||||
if (isRedirected) {
|
||||
response._requestFinished(responseEndTime);
|
||||
} else {
|
||||
this._requests.delete(request._id);
|
||||
response._requestFinished(responseEndTime);
|
||||
}
|
||||
if (event.protocolVersion)
|
||||
response._setHttpVersion(event.protocolVersion);
|
||||
this._page.frameManager.reportRequestFinished(request.request, response);
|
||||
}
|
||||
_onRequestFailed(event) {
|
||||
const request = this._requests.get(event.requestId);
|
||||
if (!request)
|
||||
return;
|
||||
this._requests.delete(request._id);
|
||||
const response = request.request._existingResponse();
|
||||
if (response) {
|
||||
response.setTransferSize(null);
|
||||
response.setEncodedBodySize(null);
|
||||
response._requestFinished(-1);
|
||||
}
|
||||
request.request._setFailureText(event.errorCode);
|
||||
this._page.frameManager.requestFailed(request.request, event.errorCode === "NS_BINDING_ABORTED");
|
||||
}
|
||||
}
|
||||
const causeToResourceType = {
|
||||
TYPE_INVALID: "other",
|
||||
TYPE_OTHER: "other",
|
||||
TYPE_SCRIPT: "script",
|
||||
TYPE_IMAGE: "image",
|
||||
TYPE_STYLESHEET: "stylesheet",
|
||||
TYPE_OBJECT: "other",
|
||||
TYPE_DOCUMENT: "document",
|
||||
TYPE_SUBDOCUMENT: "document",
|
||||
TYPE_REFRESH: "document",
|
||||
TYPE_XBL: "other",
|
||||
TYPE_PING: "other",
|
||||
TYPE_XMLHTTPREQUEST: "xhr",
|
||||
TYPE_OBJECT_SUBREQUEST: "other",
|
||||
TYPE_DTD: "other",
|
||||
TYPE_FONT: "font",
|
||||
TYPE_MEDIA: "media",
|
||||
TYPE_WEBSOCKET: "websocket",
|
||||
TYPE_CSP_REPORT: "other",
|
||||
TYPE_XSLT: "other",
|
||||
TYPE_BEACON: "other",
|
||||
TYPE_FETCH: "fetch",
|
||||
TYPE_IMAGESET: "image",
|
||||
TYPE_WEB_MANIFEST: "manifest"
|
||||
};
|
||||
const internalCauseToResourceType = {
|
||||
TYPE_INTERNAL_EVENTSOURCE: "eventsource"
|
||||
};
|
||||
class InterceptableRequest {
|
||||
constructor(frame, redirectedFrom, payload) {
|
||||
this._id = payload.requestId;
|
||||
if (redirectedFrom)
|
||||
redirectedFrom._redirectedTo = this;
|
||||
let postDataBuffer = null;
|
||||
if (payload.postData)
|
||||
postDataBuffer = Buffer.from(payload.postData, "base64");
|
||||
this.request = new network.Request(
|
||||
frame._page.browserContext,
|
||||
frame,
|
||||
null,
|
||||
redirectedFrom ? redirectedFrom.request : null,
|
||||
payload.navigationId,
|
||||
payload.url,
|
||||
internalCauseToResourceType[payload.internalCause] || causeToResourceType[payload.cause] || "other",
|
||||
payload.method,
|
||||
postDataBuffer,
|
||||
payload.headers
|
||||
);
|
||||
this.request.setRawRequestHeaders(null);
|
||||
}
|
||||
_finalRequest() {
|
||||
let request = this;
|
||||
while (request._redirectedTo)
|
||||
request = request._redirectedTo;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
class FFRouteImpl {
|
||||
constructor(session, request) {
|
||||
this._session = session;
|
||||
this._request = request;
|
||||
}
|
||||
async continue(overrides) {
|
||||
await this._session.sendMayFail("Network.resumeInterceptedRequest", {
|
||||
requestId: this._request._id,
|
||||
url: overrides.url,
|
||||
method: overrides.method,
|
||||
headers: overrides.headers,
|
||||
postData: overrides.postData ? Buffer.from(overrides.postData).toString("base64") : void 0
|
||||
});
|
||||
}
|
||||
async fulfill(response) {
|
||||
const base64body = response.isBase64 ? response.body : Buffer.from(response.body).toString("base64");
|
||||
await this._session.sendMayFail("Network.fulfillInterceptedRequest", {
|
||||
requestId: this._request._id,
|
||||
status: response.status,
|
||||
statusText: network.statusText(response.status),
|
||||
headers: response.headers,
|
||||
base64body
|
||||
});
|
||||
}
|
||||
async abort(errorCode) {
|
||||
await this._session.sendMayFail("Network.abortInterceptedRequest", {
|
||||
requestId: this._request._id,
|
||||
errorCode
|
||||
});
|
||||
}
|
||||
}
|
||||
function parseMultivalueHeaders(headers) {
|
||||
const result = [];
|
||||
for (const header of headers) {
|
||||
const separator = header.name.toLowerCase() === "set-cookie" ? "\n" : ",";
|
||||
const tokens = header.value.split(separator).map((s) => s.trim());
|
||||
for (const token of tokens)
|
||||
result.push({ name: header.name, value: token });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FFNetworkManager
|
||||
});
|
||||
500
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffPage.js
generated
vendored
Normal file
500
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/ffPage.js
generated
vendored
Normal file
@@ -0,0 +1,500 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ffPage_exports = {};
|
||||
__export(ffPage_exports, {
|
||||
FFPage: () => FFPage,
|
||||
UTILITY_WORLD_NAME: () => UTILITY_WORLD_NAME
|
||||
});
|
||||
module.exports = __toCommonJS(ffPage_exports);
|
||||
var import_eventsHelper = require("../utils/eventsHelper");
|
||||
var dialog = __toESM(require("../dialog"));
|
||||
var dom = __toESM(require("../dom"));
|
||||
var import_page = require("../page");
|
||||
var import_page2 = require("../page");
|
||||
var import_ffConnection = require("./ffConnection");
|
||||
var import_ffExecutionContext = require("./ffExecutionContext");
|
||||
var import_ffInput = require("./ffInput");
|
||||
var import_ffNetworkManager = require("./ffNetworkManager");
|
||||
var import_debugLogger = require("../utils/debugLogger");
|
||||
var import_stackTrace = require("../../utils/isomorphic/stackTrace");
|
||||
var import_errors = require("../errors");
|
||||
const UTILITY_WORLD_NAME = "__playwright_utility_world__";
|
||||
class FFPage {
|
||||
constructor(session, browserContext, opener) {
|
||||
this.cspErrorsAsynchronousForInlineScripts = true;
|
||||
this._reportedAsNew = false;
|
||||
this._workers = /* @__PURE__ */ new Map();
|
||||
this._initScripts = [];
|
||||
this._session = session;
|
||||
this._opener = opener;
|
||||
this.rawKeyboard = new import_ffInput.RawKeyboardImpl(session);
|
||||
this.rawMouse = new import_ffInput.RawMouseImpl(session);
|
||||
this.rawTouchscreen = new import_ffInput.RawTouchscreenImpl(session);
|
||||
this._contextIdToContext = /* @__PURE__ */ new Map();
|
||||
this._browserContext = browserContext;
|
||||
this._page = new import_page2.Page(this, browserContext);
|
||||
this.rawMouse.setPage(this._page);
|
||||
this._networkManager = new import_ffNetworkManager.FFNetworkManager(session, this._page);
|
||||
this._page.on(import_page2.Page.Events.FrameDetached, (frame) => this._removeContextsForFrame(frame));
|
||||
this._eventListeners = [
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.eventFired", this._onEventFired.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.frameAttached", this._onFrameAttached.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.frameDetached", this._onFrameDetached.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.navigationAborted", this._onNavigationAborted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.navigationCommitted", this._onNavigationCommitted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.navigationStarted", this._onNavigationStarted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.sameDocumentNavigation", this._onSameDocumentNavigation.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Runtime.executionContextCreated", this._onExecutionContextCreated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Runtime.executionContextDestroyed", this._onExecutionContextDestroyed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Runtime.executionContextsCleared", this._onExecutionContextsCleared.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.linkClicked", (event) => this._onLinkClicked(event.phase)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.uncaughtError", this._onUncaughtError.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Runtime.console", this._onConsole.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.dialogOpened", this._onDialogOpened.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.bindingCalled", this._onBindingCalled.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.fileChooserOpened", this._onFileChooserOpened.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.workerCreated", this._onWorkerCreated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.workerDestroyed", this._onWorkerDestroyed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.dispatchMessageFromWorker", this._onDispatchMessageFromWorker.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.crashed", this._onCrashed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.videoRecordingStarted", this._onVideoRecordingStarted.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketCreated", this._onWebSocketCreated.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketClosed", this._onWebSocketClosed.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameReceived", this._onWebSocketFrameReceived.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.webSocketFrameSent", this._onWebSocketFrameSent.bind(this)),
|
||||
import_eventsHelper.eventsHelper.addEventListener(this._session, "Page.screencastFrame", this._onScreencastFrame.bind(this))
|
||||
];
|
||||
this._session.once("Page.ready", () => {
|
||||
if (this._reportedAsNew)
|
||||
return;
|
||||
this._reportedAsNew = true;
|
||||
this._page.reportAsNew(this._opener?._page);
|
||||
});
|
||||
this.addInitScript(new import_page.InitScript(""), UTILITY_WORLD_NAME).catch((e) => this._markAsError(e));
|
||||
}
|
||||
async _markAsError(error) {
|
||||
if (this._reportedAsNew)
|
||||
return;
|
||||
this._reportedAsNew = true;
|
||||
this._page.reportAsNew(this._opener?._page, error);
|
||||
}
|
||||
_onWebSocketCreated(event) {
|
||||
this._page.frameManager.onWebSocketCreated(webSocketId(event.frameId, event.wsid), event.requestURL);
|
||||
this._page.frameManager.onWebSocketRequest(webSocketId(event.frameId, event.wsid));
|
||||
}
|
||||
_onWebSocketClosed(event) {
|
||||
if (event.error)
|
||||
this._page.frameManager.webSocketError(webSocketId(event.frameId, event.wsid), event.error);
|
||||
this._page.frameManager.webSocketClosed(webSocketId(event.frameId, event.wsid));
|
||||
}
|
||||
_onWebSocketFrameReceived(event) {
|
||||
this._page.frameManager.webSocketFrameReceived(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
}
|
||||
_onWebSocketFrameSent(event) {
|
||||
this._page.frameManager.onWebSocketFrameSent(webSocketId(event.frameId, event.wsid), event.opcode, event.data);
|
||||
}
|
||||
_onExecutionContextCreated(payload) {
|
||||
const { executionContextId, auxData } = payload;
|
||||
const frame = this._page.frameManager.frame(auxData.frameId);
|
||||
if (!frame)
|
||||
return;
|
||||
const delegate = new import_ffExecutionContext.FFExecutionContext(this._session, executionContextId);
|
||||
let worldName = null;
|
||||
if (auxData.name === UTILITY_WORLD_NAME)
|
||||
worldName = "utility";
|
||||
else if (!auxData.name)
|
||||
worldName = "main";
|
||||
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
||||
if (worldName)
|
||||
frame._contextCreated(worldName, context);
|
||||
this._contextIdToContext.set(executionContextId, context);
|
||||
}
|
||||
_onExecutionContextDestroyed(payload) {
|
||||
const { executionContextId } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId);
|
||||
if (!context)
|
||||
return;
|
||||
this._contextIdToContext.delete(executionContextId);
|
||||
context.frame._contextDestroyed(context);
|
||||
}
|
||||
_onExecutionContextsCleared() {
|
||||
for (const executionContextId of Array.from(this._contextIdToContext.keys()))
|
||||
this._onExecutionContextDestroyed({ executionContextId });
|
||||
}
|
||||
_removeContextsForFrame(frame) {
|
||||
for (const [contextId, context] of this._contextIdToContext) {
|
||||
if (context.frame === frame)
|
||||
this._contextIdToContext.delete(contextId);
|
||||
}
|
||||
}
|
||||
_onLinkClicked(phase) {
|
||||
if (phase === "before")
|
||||
this._page.frameManager.frameWillPotentiallyRequestNavigation();
|
||||
else
|
||||
this._page.frameManager.frameDidPotentiallyRequestNavigation();
|
||||
}
|
||||
_onNavigationStarted(params) {
|
||||
this._page.frameManager.frameRequestedNavigation(params.frameId, params.navigationId);
|
||||
}
|
||||
_onNavigationAborted(params) {
|
||||
this._page.frameManager.frameAbortedNavigation(params.frameId, params.errorText, params.navigationId);
|
||||
}
|
||||
_onNavigationCommitted(params) {
|
||||
for (const [workerId, worker] of this._workers) {
|
||||
if (worker.frameId === params.frameId)
|
||||
this._onWorkerDestroyed({ workerId });
|
||||
}
|
||||
this._page.frameManager.frameCommittedNewDocumentNavigation(params.frameId, params.url, params.name || "", params.navigationId || "", false);
|
||||
}
|
||||
_onSameDocumentNavigation(params) {
|
||||
this._page.frameManager.frameCommittedSameDocumentNavigation(params.frameId, params.url);
|
||||
}
|
||||
_onFrameAttached(params) {
|
||||
this._page.frameManager.frameAttached(params.frameId, params.parentFrameId);
|
||||
}
|
||||
_onFrameDetached(params) {
|
||||
this._page.frameManager.frameDetached(params.frameId);
|
||||
}
|
||||
_onEventFired(payload) {
|
||||
const { frameId, name } = payload;
|
||||
if (name === "load")
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, "load");
|
||||
if (name === "DOMContentLoaded")
|
||||
this._page.frameManager.frameLifecycleEvent(frameId, "domcontentloaded");
|
||||
}
|
||||
_onUncaughtError(params) {
|
||||
const { name, message } = (0, import_stackTrace.splitErrorMessage)(params.message);
|
||||
const error = new Error(message);
|
||||
error.stack = params.message + "\n" + params.stack.split("\n").filter(Boolean).map((a) => a.replace(/([^@]*)@(.*)/, " at $1 ($2)")).join("\n");
|
||||
error.name = name;
|
||||
this._page.addPageError(error);
|
||||
}
|
||||
_onConsole(payload) {
|
||||
const { type, args, executionContextId, location } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId);
|
||||
if (!context)
|
||||
return;
|
||||
this._page.addConsoleMessage(null, type === "warn" ? "warning" : type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
||||
}
|
||||
_onDialogOpened(params) {
|
||||
this._page.browserContext.dialogManager.dialogDidOpen(new dialog.Dialog(
|
||||
this._page,
|
||||
params.type,
|
||||
params.message,
|
||||
async (accept, promptText) => {
|
||||
await this._session.sendMayFail("Page.handleDialog", { dialogId: params.dialogId, accept, promptText });
|
||||
},
|
||||
params.defaultValue
|
||||
));
|
||||
}
|
||||
async _onBindingCalled(event) {
|
||||
const pageOrError = await this._page.waitForInitializedOrError();
|
||||
if (!(pageOrError instanceof Error)) {
|
||||
const context = this._contextIdToContext.get(event.executionContextId);
|
||||
if (context)
|
||||
await this._page.onBindingCalled(event.payload, context);
|
||||
}
|
||||
}
|
||||
async _onFileChooserOpened(payload) {
|
||||
const { executionContextId, element } = payload;
|
||||
const context = this._contextIdToContext.get(executionContextId);
|
||||
if (!context)
|
||||
return;
|
||||
const handle = (0, import_ffExecutionContext.createHandle)(context, element).asElement();
|
||||
await this._page._onFileChooserOpened(handle);
|
||||
}
|
||||
async _onWorkerCreated(event) {
|
||||
const workerId = event.workerId;
|
||||
const worker = new import_page2.Worker(this._page, event.url);
|
||||
const workerSession = new import_ffConnection.FFSession(this._session._connection, workerId, (message) => {
|
||||
this._session.send("Page.sendMessageToWorker", {
|
||||
frameId: event.frameId,
|
||||
workerId,
|
||||
message: JSON.stringify(message)
|
||||
}).catch((e) => {
|
||||
workerSession.dispatchMessage({ id: message.id, method: "", params: {}, error: { message: e.message, data: void 0 } });
|
||||
});
|
||||
});
|
||||
this._workers.set(workerId, { session: workerSession, frameId: event.frameId });
|
||||
this._page.addWorker(workerId, worker);
|
||||
workerSession.once("Runtime.executionContextCreated", (event2) => {
|
||||
worker.createExecutionContext(new import_ffExecutionContext.FFExecutionContext(workerSession, event2.executionContextId));
|
||||
worker.workerScriptLoaded();
|
||||
});
|
||||
workerSession.on("Runtime.console", (event2) => {
|
||||
const { type, args, location } = event2;
|
||||
const context = worker.existingExecutionContext;
|
||||
this._page.addConsoleMessage(worker, type, args.map((arg) => (0, import_ffExecutionContext.createHandle)(context, arg)), location);
|
||||
});
|
||||
}
|
||||
_onWorkerDestroyed(event) {
|
||||
const workerId = event.workerId;
|
||||
const worker = this._workers.get(workerId);
|
||||
if (!worker)
|
||||
return;
|
||||
worker.session.dispose();
|
||||
this._workers.delete(workerId);
|
||||
this._page.removeWorker(workerId);
|
||||
}
|
||||
async _onDispatchMessageFromWorker(event) {
|
||||
const worker = this._workers.get(event.workerId);
|
||||
if (!worker)
|
||||
return;
|
||||
worker.session.dispatchMessage(JSON.parse(event.message));
|
||||
}
|
||||
async _onCrashed(event) {
|
||||
this._session.markAsCrashed();
|
||||
this._page._didCrash();
|
||||
}
|
||||
_onVideoRecordingStarted(event) {
|
||||
this._browserContext._browser._videoStarted(this._browserContext, event.screencastId, event.file, this._page.waitForInitializedOrError());
|
||||
}
|
||||
didClose() {
|
||||
this._markAsError(new import_errors.TargetClosedError());
|
||||
this._session.dispose();
|
||||
import_eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);
|
||||
this._networkManager.dispose();
|
||||
this._page._didClose();
|
||||
}
|
||||
async navigateFrame(frame, url, referer) {
|
||||
const response = await this._session.send("Page.navigate", { url, referer, frameId: frame._id });
|
||||
return { newDocumentId: response.navigationId || void 0 };
|
||||
}
|
||||
async updateExtraHTTPHeaders() {
|
||||
await this._session.send("Network.setExtraHTTPHeaders", { headers: this._page.extraHTTPHeaders() || [] });
|
||||
}
|
||||
async updateEmulatedViewportSize() {
|
||||
const viewportSize = this._page.emulatedSize()?.viewport ?? null;
|
||||
await this._session.send("Page.setViewportSize", { viewportSize });
|
||||
}
|
||||
async bringToFront() {
|
||||
await this._session.send("Page.bringToFront", {});
|
||||
}
|
||||
async updateEmulateMedia() {
|
||||
const emulatedMedia = this._page.emulatedMedia();
|
||||
const colorScheme = emulatedMedia.colorScheme === "no-override" ? void 0 : emulatedMedia.colorScheme;
|
||||
const reducedMotion = emulatedMedia.reducedMotion === "no-override" ? void 0 : emulatedMedia.reducedMotion;
|
||||
const forcedColors = emulatedMedia.forcedColors === "no-override" ? void 0 : emulatedMedia.forcedColors;
|
||||
const contrast = emulatedMedia.contrast === "no-override" ? void 0 : emulatedMedia.contrast;
|
||||
await this._session.send("Page.setEmulatedMedia", {
|
||||
// Empty string means reset.
|
||||
type: emulatedMedia.media === "no-override" ? "" : emulatedMedia.media,
|
||||
colorScheme,
|
||||
reducedMotion,
|
||||
forcedColors,
|
||||
contrast
|
||||
});
|
||||
}
|
||||
async updateRequestInterception() {
|
||||
await this._networkManager.setRequestInterception(this._page.needsRequestInterception());
|
||||
}
|
||||
async updateFileChooserInterception() {
|
||||
const enabled = this._page.fileChooserIntercepted();
|
||||
await this._session.send("Page.setInterceptFileChooserDialog", { enabled }).catch(() => {
|
||||
});
|
||||
}
|
||||
async reload() {
|
||||
await this._session.send("Page.reload");
|
||||
}
|
||||
async goBack() {
|
||||
const { success } = await this._session.send("Page.goBack", { frameId: this._page.mainFrame()._id });
|
||||
return success;
|
||||
}
|
||||
async goForward() {
|
||||
const { success } = await this._session.send("Page.goForward", { frameId: this._page.mainFrame()._id });
|
||||
return success;
|
||||
}
|
||||
async requestGC() {
|
||||
await this._session.send("Heap.collectGarbage");
|
||||
}
|
||||
async addInitScript(initScript, worldName) {
|
||||
this._initScripts.push({ initScript, worldName });
|
||||
await this._updateInitScripts();
|
||||
}
|
||||
async removeInitScripts(initScripts) {
|
||||
const set = new Set(initScripts);
|
||||
this._initScripts = this._initScripts.filter((s) => !set.has(s.initScript));
|
||||
await this._updateInitScripts();
|
||||
}
|
||||
async _updateInitScripts() {
|
||||
await this._session.send("Page.setInitScripts", { scripts: this._initScripts.map((s) => ({ script: s.initScript.source, worldName: s.worldName })) });
|
||||
}
|
||||
async closePage(runBeforeUnload) {
|
||||
await this._session.send("Page.close", { runBeforeUnload });
|
||||
}
|
||||
async setBackgroundColor(color) {
|
||||
if (color)
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) {
|
||||
if (!documentRect) {
|
||||
const scrollOffset = await this._page.mainFrame().waitForFunctionValueInUtility(progress, () => ({ x: window.scrollX, y: window.scrollY }));
|
||||
documentRect = {
|
||||
x: viewportRect.x + scrollOffset.x,
|
||||
y: viewportRect.y + scrollOffset.y,
|
||||
width: viewportRect.width,
|
||||
height: viewportRect.height
|
||||
};
|
||||
}
|
||||
const { data } = await progress.race(this._session.send("Page.screenshot", {
|
||||
mimeType: "image/" + format,
|
||||
clip: documentRect,
|
||||
quality,
|
||||
omitDeviceScaleFactor: scale === "css"
|
||||
}));
|
||||
return Buffer.from(data, "base64");
|
||||
}
|
||||
async getContentFrame(handle) {
|
||||
const { contentFrameId } = await this._session.send("Page.describeNode", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId
|
||||
});
|
||||
if (!contentFrameId)
|
||||
return null;
|
||||
return this._page.frameManager.frame(contentFrameId);
|
||||
}
|
||||
async getOwnerFrame(handle) {
|
||||
const { ownerFrameId } = await this._session.send("Page.describeNode", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId
|
||||
});
|
||||
return ownerFrameId || null;
|
||||
}
|
||||
async getBoundingBox(handle) {
|
||||
const quads = await this.getContentQuads(handle);
|
||||
if (!quads || !quads.length)
|
||||
return null;
|
||||
let minX = Infinity;
|
||||
let maxX = -Infinity;
|
||||
let minY = Infinity;
|
||||
let maxY = -Infinity;
|
||||
for (const quad of quads) {
|
||||
for (const point of quad) {
|
||||
minX = Math.min(minX, point.x);
|
||||
maxX = Math.max(maxX, point.x);
|
||||
minY = Math.min(minY, point.y);
|
||||
maxY = Math.max(maxY, point.y);
|
||||
}
|
||||
}
|
||||
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
||||
}
|
||||
async scrollRectIntoViewIfNeeded(handle, rect) {
|
||||
return await this._session.send("Page.scrollIntoViewIfNeeded", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId,
|
||||
rect
|
||||
}).then(() => "done").catch((e) => {
|
||||
if (e instanceof Error && e.message.includes("Node is detached from document"))
|
||||
return "error:notconnected";
|
||||
if (e instanceof Error && e.message.includes("Node does not have a layout object"))
|
||||
return "error:notvisible";
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
async setScreencastOptions(options) {
|
||||
if (options) {
|
||||
const { screencastId } = await this._session.send("Page.startScreencast", options);
|
||||
this._screencastId = screencastId;
|
||||
} else {
|
||||
await this._session.send("Page.stopScreencast");
|
||||
}
|
||||
}
|
||||
_onScreencastFrame(event) {
|
||||
if (!this._screencastId)
|
||||
return;
|
||||
const screencastId = this._screencastId;
|
||||
this._page.throttleScreencastFrameAck(() => {
|
||||
this._session.send("Page.screencastFrameAck", { screencastId }).catch((e) => import_debugLogger.debugLogger.log("error", e));
|
||||
});
|
||||
const buffer = Buffer.from(event.data, "base64");
|
||||
this._page.emit(import_page2.Page.Events.ScreencastFrame, {
|
||||
buffer,
|
||||
width: event.deviceWidth,
|
||||
height: event.deviceHeight
|
||||
});
|
||||
}
|
||||
rafCountForStablePosition() {
|
||||
return 1;
|
||||
}
|
||||
async getContentQuads(handle) {
|
||||
const result = await this._session.sendMayFail("Page.getContentQuads", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId
|
||||
});
|
||||
if (!result)
|
||||
return null;
|
||||
return result.quads.map((quad) => [quad.p1, quad.p2, quad.p3, quad.p4]);
|
||||
}
|
||||
async setInputFilePaths(handle, files) {
|
||||
await this._session.send("Page.setFileInputFiles", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId,
|
||||
files
|
||||
});
|
||||
}
|
||||
async adoptElementHandle(handle, to) {
|
||||
const result = await this._session.send("Page.adoptNode", {
|
||||
frameId: handle._context.frame._id,
|
||||
objectId: handle._objectId,
|
||||
executionContextId: to.delegate._executionContextId
|
||||
});
|
||||
if (!result.remoteObject)
|
||||
throw new Error(dom.kUnableToAdoptErrorMessage);
|
||||
return (0, import_ffExecutionContext.createHandle)(to, result.remoteObject);
|
||||
}
|
||||
async inputActionEpilogue() {
|
||||
}
|
||||
async resetForReuse(progress) {
|
||||
await this.rawMouse.move(progress, -1, -1, "none", /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set(), false);
|
||||
}
|
||||
async getFrameElement(frame) {
|
||||
const parent = frame.parentFrame();
|
||||
if (!parent)
|
||||
throw new Error("Frame has been detached.");
|
||||
const context = await parent._mainContext();
|
||||
const result = await this._session.send("Page.adoptNode", {
|
||||
frameId: frame._id,
|
||||
executionContextId: context.delegate._executionContextId
|
||||
});
|
||||
if (!result.remoteObject)
|
||||
throw new Error("Frame has been detached.");
|
||||
return (0, import_ffExecutionContext.createHandle)(context, result.remoteObject);
|
||||
}
|
||||
shouldToggleStyleSheetToSyncAnimations() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function webSocketId(frameId, wsid) {
|
||||
return `${frameId}---${wsid}`;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FFPage,
|
||||
UTILITY_WORLD_NAME
|
||||
});
|
||||
116
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/firefox.js
generated
vendored
Normal file
116
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/firefox.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var firefox_exports = {};
|
||||
__export(firefox_exports, {
|
||||
Firefox: () => Firefox
|
||||
});
|
||||
module.exports = __toCommonJS(firefox_exports);
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_ffBrowser = require("./ffBrowser");
|
||||
var import_ffConnection = require("./ffConnection");
|
||||
var import_ascii = require("../utils/ascii");
|
||||
var import_browserType = require("../browserType");
|
||||
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
||||
class Firefox extends import_browserType.BrowserType {
|
||||
constructor(parent, bidiFirefox) {
|
||||
super(parent, "firefox");
|
||||
this._bidiFirefox = bidiFirefox;
|
||||
}
|
||||
launch(progress, options, protocolLogger) {
|
||||
if (options.channel?.startsWith("moz-"))
|
||||
return this._bidiFirefox.launch(progress, options, protocolLogger);
|
||||
return super.launch(progress, options, protocolLogger);
|
||||
}
|
||||
async launchPersistentContext(progress, userDataDir, options) {
|
||||
if (options.channel?.startsWith("moz-"))
|
||||
return this._bidiFirefox.launchPersistentContext(progress, userDataDir, options);
|
||||
return super.launchPersistentContext(progress, userDataDir, options);
|
||||
}
|
||||
connectToTransport(transport, options) {
|
||||
return import_ffBrowser.FFBrowser.connect(this.attribution.playwright, transport, options);
|
||||
}
|
||||
doRewriteStartupLog(error) {
|
||||
if (!error.logs)
|
||||
return error;
|
||||
if (error.logs.includes(`as root in a regular user's session is not supported.`))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.
|
||||
Workaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? " in your GitHub Actions workflow file" : ""} when running Playwright.`, 1);
|
||||
if (error.logs.includes("no DISPLAY environment variable specified"))
|
||||
error.logs = "\n" + (0, import_ascii.wrapInASCIIBox)(import_browserType.kNoXServerRunningError, 1);
|
||||
return error;
|
||||
}
|
||||
amendEnvironment(env) {
|
||||
if (!import_path.default.isAbsolute(import_os.default.homedir()))
|
||||
throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${import_os.default.platform() === "win32" ? "USERPROFILE" : "HOME"} to a relative path?`);
|
||||
if (import_os.default.platform() === "linux") {
|
||||
return { ...env, SNAP_NAME: void 0, SNAP_INSTANCE_NAME: void 0 };
|
||||
}
|
||||
return env;
|
||||
}
|
||||
attemptToGracefullyCloseBrowser(transport) {
|
||||
const message = { method: "Browser.close", params: {}, id: import_ffConnection.kBrowserCloseMessageId };
|
||||
transport.send(message);
|
||||
}
|
||||
async defaultArgs(options, isPersistent, userDataDir) {
|
||||
const { args = [], headless } = options;
|
||||
const userDataDirArg = args.find((arg) => arg.startsWith("-profile") || arg.startsWith("--profile"));
|
||||
if (userDataDirArg)
|
||||
throw this._createUserDataDirArgMisuseError("--profile");
|
||||
if (args.find((arg) => arg.startsWith("-juggler")))
|
||||
throw new Error("Use the port parameter instead of -juggler argument");
|
||||
const firefoxArguments = ["-no-remote"];
|
||||
if (headless) {
|
||||
firefoxArguments.push("-headless");
|
||||
} else {
|
||||
firefoxArguments.push("-wait-for-browser");
|
||||
firefoxArguments.push("-foreground");
|
||||
}
|
||||
firefoxArguments.push(`-profile`, userDataDir);
|
||||
firefoxArguments.push("-juggler-pipe");
|
||||
firefoxArguments.push(...args);
|
||||
if (isPersistent)
|
||||
firefoxArguments.push("about:blank");
|
||||
else
|
||||
firefoxArguments.push("-silent");
|
||||
return firefoxArguments;
|
||||
}
|
||||
waitForReadyState(options, browserLogsCollector) {
|
||||
const result = new import_manualPromise.ManualPromise();
|
||||
browserLogsCollector.onMessage((message) => {
|
||||
if (message.includes("Juggler listening to the pipe"))
|
||||
result.resolve({});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Firefox
|
||||
});
|
||||
16
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/protocol.d.js
generated
vendored
Normal file
16
.playwright-mcp/node_modules/playwright-core/lib/server/firefox/protocol.d.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var protocol_d_exports = {};
|
||||
module.exports = __toCommonJS(protocol_d_exports);
|
||||
147
.playwright-mcp/node_modules/playwright-core/lib/server/formData.js
generated
vendored
Normal file
147
.playwright-mcp/node_modules/playwright-core/lib/server/formData.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var formData_exports = {};
|
||||
__export(formData_exports, {
|
||||
MultipartFormData: () => MultipartFormData
|
||||
});
|
||||
module.exports = __toCommonJS(formData_exports);
|
||||
var import_utilsBundle = require("../utilsBundle");
|
||||
class MultipartFormData {
|
||||
constructor() {
|
||||
this._chunks = [];
|
||||
this._boundary = generateUniqueBoundaryString();
|
||||
}
|
||||
contentTypeHeader() {
|
||||
return `multipart/form-data; boundary=${this._boundary}`;
|
||||
}
|
||||
addField(name, value) {
|
||||
this._beginMultiPartHeader(name);
|
||||
this._finishMultiPartHeader();
|
||||
this._chunks.push(Buffer.from(value));
|
||||
this._finishMultiPartField();
|
||||
}
|
||||
addFileField(name, value) {
|
||||
this._beginMultiPartHeader(name);
|
||||
this._chunks.push(Buffer.from(`; filename="${value.name}"`));
|
||||
this._chunks.push(Buffer.from(`\r
|
||||
content-type: ${value.mimeType || import_utilsBundle.mime.getType(value.name) || "application/octet-stream"}`));
|
||||
this._finishMultiPartHeader();
|
||||
this._chunks.push(value.buffer);
|
||||
this._finishMultiPartField();
|
||||
}
|
||||
finish() {
|
||||
this._addBoundary(true);
|
||||
return Buffer.concat(this._chunks);
|
||||
}
|
||||
_beginMultiPartHeader(name) {
|
||||
this._addBoundary();
|
||||
this._chunks.push(Buffer.from(`content-disposition: form-data; name="${name}"`));
|
||||
}
|
||||
_finishMultiPartHeader() {
|
||||
this._chunks.push(Buffer.from(`\r
|
||||
\r
|
||||
`));
|
||||
}
|
||||
_finishMultiPartField() {
|
||||
this._chunks.push(Buffer.from(`\r
|
||||
`));
|
||||
}
|
||||
_addBoundary(isLastBoundary) {
|
||||
this._chunks.push(Buffer.from("--" + this._boundary));
|
||||
if (isLastBoundary)
|
||||
this._chunks.push(Buffer.from("--"));
|
||||
this._chunks.push(Buffer.from("\r\n"));
|
||||
}
|
||||
}
|
||||
const alphaNumericEncodingMap = [
|
||||
65,
|
||||
66,
|
||||
67,
|
||||
68,
|
||||
69,
|
||||
70,
|
||||
71,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
82,
|
||||
83,
|
||||
84,
|
||||
85,
|
||||
86,
|
||||
87,
|
||||
88,
|
||||
89,
|
||||
90,
|
||||
97,
|
||||
98,
|
||||
99,
|
||||
100,
|
||||
101,
|
||||
102,
|
||||
103,
|
||||
104,
|
||||
105,
|
||||
106,
|
||||
107,
|
||||
108,
|
||||
109,
|
||||
110,
|
||||
111,
|
||||
112,
|
||||
113,
|
||||
114,
|
||||
115,
|
||||
116,
|
||||
117,
|
||||
118,
|
||||
119,
|
||||
120,
|
||||
121,
|
||||
122,
|
||||
48,
|
||||
49,
|
||||
50,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57,
|
||||
65,
|
||||
66
|
||||
];
|
||||
function generateUniqueBoundaryString() {
|
||||
const charCodes = [];
|
||||
for (let i = 0; i < 16; i++)
|
||||
charCodes.push(alphaNumericEncodingMap[Math.floor(Math.random() * alphaNumericEncodingMap.length)]);
|
||||
return "----WebKitFormBoundary" + String.fromCharCode(...charCodes);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
MultipartFormData
|
||||
});
|
||||
154
.playwright-mcp/node_modules/playwright-core/lib/server/frameSelectors.js
generated
vendored
Normal file
154
.playwright-mcp/node_modules/playwright-core/lib/server/frameSelectors.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var frameSelectors_exports = {};
|
||||
__export(frameSelectors_exports, {
|
||||
FrameSelectors: () => FrameSelectors
|
||||
});
|
||||
module.exports = __toCommonJS(frameSelectors_exports);
|
||||
var import_utils = require("../utils");
|
||||
var import_selectorParser = require("../utils/isomorphic/selectorParser");
|
||||
class FrameSelectors {
|
||||
constructor(frame) {
|
||||
this.frame = frame;
|
||||
}
|
||||
_parseSelector(selector, options) {
|
||||
const strict = typeof options?.strict === "boolean" ? options.strict : !!this.frame._page.browserContext._options.strictSelectors;
|
||||
return this.frame._page.browserContext.selectors().parseSelector(selector, strict);
|
||||
}
|
||||
async query(selector, options, scope) {
|
||||
const resolved = await this.resolveInjectedForSelector(selector, options, scope);
|
||||
if (!resolved)
|
||||
return null;
|
||||
const handle = await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
|
||||
return injected.querySelector(info.parsed, scope2 || document, info.strict);
|
||||
}, { info: resolved.info, scope: resolved.scope });
|
||||
const elementHandle = handle.asElement();
|
||||
if (!elementHandle) {
|
||||
handle.dispose();
|
||||
return null;
|
||||
}
|
||||
return adoptIfNeeded(elementHandle, await resolved.frame._mainContext());
|
||||
}
|
||||
async queryArrayInMainWorld(selector, scope) {
|
||||
const resolved = await this.resolveInjectedForSelector(selector, { mainWorld: true }, scope);
|
||||
if (!resolved)
|
||||
throw new Error(`Failed to find frame for selector "${selector}"`);
|
||||
return await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
|
||||
return injected.querySelectorAll(info.parsed, scope2 || document);
|
||||
}, { info: resolved.info, scope: resolved.scope });
|
||||
}
|
||||
async queryCount(selector, options) {
|
||||
const resolved = await this.resolveInjectedForSelector(selector);
|
||||
if (!resolved)
|
||||
throw new Error(`Failed to find frame for selector "${selector}"`);
|
||||
await options.__testHookBeforeQuery?.();
|
||||
return await resolved.injected.evaluate((injected, { info }) => {
|
||||
return injected.querySelectorAll(info.parsed, document).length;
|
||||
}, { info: resolved.info });
|
||||
}
|
||||
async queryAll(selector, scope) {
|
||||
const resolved = await this.resolveInjectedForSelector(selector, {}, scope);
|
||||
if (!resolved)
|
||||
return [];
|
||||
const arrayHandle = await resolved.injected.evaluateHandle((injected, { info, scope: scope2 }) => {
|
||||
return injected.querySelectorAll(info.parsed, scope2 || document);
|
||||
}, { info: resolved.info, scope: resolved.scope });
|
||||
const properties = await arrayHandle.getProperties();
|
||||
arrayHandle.dispose();
|
||||
const targetContext = await resolved.frame._mainContext();
|
||||
const result = [];
|
||||
for (const property of properties.values()) {
|
||||
const elementHandle = property.asElement();
|
||||
if (elementHandle)
|
||||
result.push(adoptIfNeeded(elementHandle, targetContext));
|
||||
else
|
||||
property.dispose();
|
||||
}
|
||||
return Promise.all(result);
|
||||
}
|
||||
_jumpToAriaRefFrameIfNeeded(selector, info, frame) {
|
||||
if (info.parsed.parts[0].name !== "aria-ref")
|
||||
return frame;
|
||||
const body = info.parsed.parts[0].body;
|
||||
const match = body.match(/^f(\d+)e\d+$/);
|
||||
if (!match)
|
||||
return frame;
|
||||
const frameSeq = +match[1];
|
||||
const jumptToFrame = this.frame._page.frameManager.frames().find((frame2) => frame2.seq === frameSeq);
|
||||
if (!jumptToFrame)
|
||||
throw new import_selectorParser.InvalidSelectorError(`Invalid frame in aria-ref selector "${selector}"`);
|
||||
return jumptToFrame;
|
||||
}
|
||||
async resolveFrameForSelector(selector, options = {}, scope) {
|
||||
let frame = this.frame;
|
||||
const frameChunks = (0, import_selectorParser.splitSelectorByFrame)(selector);
|
||||
for (const chunk of frameChunks) {
|
||||
(0, import_selectorParser.visitAllSelectorParts)(chunk, (part, nested) => {
|
||||
if (nested && part.name === "internal:control" && part.body === "enter-frame") {
|
||||
const locator = (0, import_utils.asLocator)(this.frame._page.browserContext._browser.sdkLanguage(), selector);
|
||||
throw new import_selectorParser.InvalidSelectorError(`Frame locators are not allowed inside composite locators, while querying "${locator}"`);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < frameChunks.length - 1; ++i) {
|
||||
const info = this._parseSelector(frameChunks[i], options);
|
||||
frame = this._jumpToAriaRefFrameIfNeeded(selector, info, frame);
|
||||
const context = await frame._context(info.world);
|
||||
const injectedScript = await context.injectedScript();
|
||||
const handle = await injectedScript.evaluateHandle((injected, { info: info2, scope: scope2, selectorString }) => {
|
||||
const element2 = injected.querySelector(info2.parsed, scope2 || document, info2.strict);
|
||||
if (element2 && element2.nodeName !== "IFRAME" && element2.nodeName !== "FRAME")
|
||||
throw injected.createStacklessError(`Selector "${selectorString}" resolved to ${injected.previewNode(element2)}, <iframe> was expected`);
|
||||
return element2;
|
||||
}, { info, scope: i === 0 ? scope : void 0, selectorString: (0, import_selectorParser.stringifySelector)(info.parsed) });
|
||||
const element = handle.asElement();
|
||||
if (!element)
|
||||
return null;
|
||||
const maybeFrame = await frame._page.delegate.getContentFrame(element);
|
||||
element.dispose();
|
||||
if (!maybeFrame)
|
||||
return null;
|
||||
frame = maybeFrame;
|
||||
}
|
||||
if (frame !== this.frame)
|
||||
scope = void 0;
|
||||
const lastChunk = frame.selectors._parseSelector(frameChunks[frameChunks.length - 1], options);
|
||||
frame = this._jumpToAriaRefFrameIfNeeded(selector, lastChunk, frame);
|
||||
return { frame, info: lastChunk, scope };
|
||||
}
|
||||
async resolveInjectedForSelector(selector, options, scope) {
|
||||
const resolved = await this.resolveFrameForSelector(selector, options, scope);
|
||||
if (!resolved)
|
||||
return;
|
||||
const context = await resolved.frame._context(options?.mainWorld ? "main" : resolved.info.world);
|
||||
const injected = await context.injectedScript();
|
||||
return { injected, info: resolved.info, frame: resolved.frame, scope: resolved.scope };
|
||||
}
|
||||
}
|
||||
async function adoptIfNeeded(handle, context) {
|
||||
if (handle._context === context)
|
||||
return handle;
|
||||
const adopted = await handle._page.delegate.adoptElementHandle(handle, context);
|
||||
handle.dispose();
|
||||
return adopted;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FrameSelectors
|
||||
});
|
||||
1455
.playwright-mcp/node_modules/playwright-core/lib/server/frames.js
generated
vendored
Normal file
1455
.playwright-mcp/node_modules/playwright-core/lib/server/frames.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user