🚀 Auto-deploy: BotVPS atualizado em 02/05/2026 15:37:40
This commit is contained in:
233
node_modules/playwright-core/lib/tools/mcp/browserFactory.js
generated
vendored
Normal file
233
node_modules/playwright-core/lib/tools/mcp/browserFactory.js
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
"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 browserFactory_exports = {};
|
||||
__export(browserFactory_exports, {
|
||||
createBrowser: () => createBrowser,
|
||||
createBrowserWithInfo: () => createBrowserWithInfo,
|
||||
isProfileLocked: () => isProfileLocked
|
||||
});
|
||||
module.exports = __toCommonJS(browserFactory_exports);
|
||||
var import_crypto = __toESM(require("crypto"));
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_net = __toESM(require("net"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var playwright = __toESM(require("../../.."));
|
||||
var import_registry = require("../../server/registry/index");
|
||||
var import_log = require("./log");
|
||||
var import_context = require("../backend/context");
|
||||
var import_extensionContextFactory = require("./extensionContextFactory");
|
||||
var import_connect = require("../utils/connect");
|
||||
var import_serverRegistry = require("../../serverRegistry");
|
||||
var import_connect2 = require("../../client/connect");
|
||||
async function createBrowser(config, clientInfo) {
|
||||
const { browser } = await createBrowserWithInfo(config, clientInfo);
|
||||
return browser;
|
||||
}
|
||||
async function createBrowserWithInfo(config, clientInfo) {
|
||||
if (config.browser.remoteEndpoint)
|
||||
return await createRemoteBrowser(config);
|
||||
let browser;
|
||||
if (config.browser.cdpEndpoint)
|
||||
browser = await createCDPBrowser(config, clientInfo);
|
||||
else if (config.browser.isolated)
|
||||
browser = await createIsolatedBrowser(config, clientInfo);
|
||||
else if (config.extension)
|
||||
browser = await (0, import_extensionContextFactory.createExtensionBrowser)(config, clientInfo);
|
||||
else
|
||||
browser = await createPersistentBrowser(config, clientInfo);
|
||||
return { browser, browserInfo: browserInfo(browser, config) };
|
||||
}
|
||||
function browserInfo(browser, config) {
|
||||
return {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
guid: browser._guid,
|
||||
browserName: config.browser.browserName,
|
||||
launchOptions: config.browser.launchOptions,
|
||||
userDataDir: config.browser.userDataDir
|
||||
};
|
||||
}
|
||||
async function createIsolatedBrowser(config, clientInfo) {
|
||||
(0, import_log.testDebug)("create browser (isolated)");
|
||||
await injectCdpPort(config.browser);
|
||||
const browserType = playwright[config.browser.browserName];
|
||||
const tracesDir = await computeTracesDir(config, clientInfo);
|
||||
const browser = await browserType.launch({
|
||||
tracesDir,
|
||||
...config.browser.launchOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false
|
||||
}).catch((error) => {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throwBrowserIsNotInstalledError(config);
|
||||
throw error;
|
||||
});
|
||||
await startServer(browser, clientInfo);
|
||||
return browser;
|
||||
}
|
||||
async function createCDPBrowser(config, clientInfo) {
|
||||
(0, import_log.testDebug)("create browser (cdp)");
|
||||
const browser = await playwright.chromium.connectOverCDP(config.browser.cdpEndpoint, {
|
||||
headers: config.browser.cdpHeaders,
|
||||
timeout: config.browser.cdpTimeout
|
||||
});
|
||||
await startServer(browser, clientInfo);
|
||||
return browser;
|
||||
}
|
||||
async function createRemoteBrowser(config) {
|
||||
(0, import_log.testDebug)("create browser (remote)");
|
||||
const descriptor = await import_serverRegistry.serverRegistry.find(config.browser.remoteEndpoint);
|
||||
if (descriptor) {
|
||||
const browser2 = await (0, import_connect.connectToBrowserAcrossVersions)(descriptor);
|
||||
return {
|
||||
browser: browser2,
|
||||
browserInfo: {
|
||||
guid: descriptor.browser.guid,
|
||||
browserName: descriptor.browser.browserName,
|
||||
launchOptions: descriptor.browser.launchOptions,
|
||||
userDataDir: descriptor.browser.userDataDir
|
||||
}
|
||||
};
|
||||
}
|
||||
const endpoint = config.browser.remoteEndpoint;
|
||||
const playwrightObject = playwright;
|
||||
const browser = await (0, import_connect2.connectToBrowser)(playwrightObject, { endpoint });
|
||||
browser._connectToBrowserType(playwrightObject[browser._browserName], {}, void 0);
|
||||
return { browser, browserInfo: browserInfo(browser, config) };
|
||||
}
|
||||
async function createPersistentBrowser(config, clientInfo) {
|
||||
(0, import_log.testDebug)("create browser (persistent)");
|
||||
await injectCdpPort(config.browser);
|
||||
const userDataDir = config.browser.userDataDir ?? await createUserDataDir(config, clientInfo);
|
||||
const tracesDir = await computeTracesDir(config, clientInfo);
|
||||
if (await isProfileLocked5Times(userDataDir))
|
||||
throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
|
||||
const browserType = playwright[config.browser.browserName];
|
||||
const launchOptions = {
|
||||
tracesDir,
|
||||
...config.browser.launchOptions,
|
||||
...config.browser.contextOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false,
|
||||
ignoreDefaultArgs: [
|
||||
"--disable-extensions"
|
||||
]
|
||||
};
|
||||
try {
|
||||
const browserContext = await browserType.launchPersistentContext(userDataDir, launchOptions);
|
||||
const browser = browserContext.browser();
|
||||
await startServer(browser, clientInfo);
|
||||
return browser;
|
||||
} catch (error) {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throwBrowserIsNotInstalledError(config);
|
||||
if (error.message.includes("cannot open shared object file: No such file or directory")) {
|
||||
const browserName = launchOptions.channel ?? config.browser.browserName;
|
||||
throw new Error(`Missing system dependencies required to run browser ${browserName}. Install them with: sudo npx playwright install-deps ${browserName}`);
|
||||
}
|
||||
if (error.message.includes("ProcessSingleton") || error.message.includes("exitCode=21"))
|
||||
throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async function createUserDataDir(config, clientInfo) {
|
||||
const dir = process.env.PWMCP_PROFILES_DIR_FOR_TEST ?? import_registry.registryDirectory;
|
||||
const browserToken = config.browser.launchOptions?.channel ?? config.browser?.browserName;
|
||||
const rootPathToken = createHash(clientInfo.cwd);
|
||||
const result = import_path.default.join(dir, `mcp-${browserToken}-${rootPathToken}`);
|
||||
await import_fs.default.promises.mkdir(result, { recursive: true });
|
||||
return result;
|
||||
}
|
||||
async function injectCdpPort(browserConfig) {
|
||||
if (browserConfig.browserName === "chromium")
|
||||
browserConfig.launchOptions.cdpPort = await findFreePort();
|
||||
}
|
||||
async function findFreePort() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = import_net.default.createServer();
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
const { port } = server.address();
|
||||
server.close(() => resolve(port));
|
||||
});
|
||||
server.on("error", reject);
|
||||
});
|
||||
}
|
||||
function createHash(data) {
|
||||
return import_crypto.default.createHash("sha256").update(data).digest("hex").slice(0, 7);
|
||||
}
|
||||
async function computeTracesDir(config, clientInfo) {
|
||||
return import_path.default.resolve((0, import_context.outputDir)({ config, cwd: clientInfo.cwd }), "traces");
|
||||
}
|
||||
async function isProfileLocked5Times(userDataDir) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (!isProfileLocked(userDataDir))
|
||||
return false;
|
||||
await new Promise((f) => setTimeout(f, 1e3));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function isProfileLocked(userDataDir) {
|
||||
const lockFile = process.platform === "win32" ? "lockfile" : "SingletonLock";
|
||||
const lockPath = import_path.default.join(userDataDir, lockFile);
|
||||
if (process.platform === "win32") {
|
||||
try {
|
||||
const fd = import_fs.default.openSync(lockPath, "r+");
|
||||
import_fs.default.closeSync(fd);
|
||||
return false;
|
||||
} catch (e) {
|
||||
return e.code !== "ENOENT";
|
||||
}
|
||||
}
|
||||
try {
|
||||
const target = import_fs.default.readlinkSync(lockPath);
|
||||
const pid = parseInt(target.split("-").pop() || "", 10);
|
||||
if (isNaN(pid))
|
||||
return false;
|
||||
process.kill(pid, 0);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function throwBrowserIsNotInstalledError(config) {
|
||||
const channel = config.browser.launchOptions?.channel ?? config.browser.browserName;
|
||||
if (config.skillMode)
|
||||
throw new Error(`Browser "${channel}" is not installed. Run \`playwright-cli install-browser ${channel}\` to install`);
|
||||
else
|
||||
throw new Error(`Browser "${channel}" is not installed. Run \`npx @playwright/mcp install-browser ${channel}\` to install`);
|
||||
}
|
||||
async function startServer(browser, clientInfo) {
|
||||
if (clientInfo.sessionName)
|
||||
await browser.bind(clientInfo.sessionName, { workspaceDir: clientInfo.workspaceDir });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createBrowser,
|
||||
createBrowserWithInfo,
|
||||
isProfileLocked
|
||||
});
|
||||
352
node_modules/playwright-core/lib/tools/mcp/cdpRelay.js
generated
vendored
Normal file
352
node_modules/playwright-core/lib/tools/mcp/cdpRelay.js
generated
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
"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 cdpRelay_exports = {};
|
||||
__export(cdpRelay_exports, {
|
||||
CDPRelayServer: () => CDPRelayServer
|
||||
});
|
||||
module.exports = __toCommonJS(cdpRelay_exports);
|
||||
var import_child_process = require("child_process");
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
var import_registry = require("../../server/registry/index");
|
||||
var import_manualPromise = require("../../utils/isomorphic/manualPromise");
|
||||
var import_http2 = require("../utils/mcp/http");
|
||||
var import_log = require("./log");
|
||||
var protocol = __toESM(require("./protocol"));
|
||||
const debugLogger = (0, import_utilsBundle.debug)("pw:mcp:relay");
|
||||
class CDPRelayServer {
|
||||
constructor(server, browserChannel, userDataDir, executablePath) {
|
||||
this._playwrightConnection = null;
|
||||
this._extensionConnection = null;
|
||||
this._nextSessionId = 1;
|
||||
this._wsHost = (0, import_http2.addressToString)(server.address(), { protocol: "ws" });
|
||||
this._browserChannel = browserChannel;
|
||||
this._userDataDir = userDataDir;
|
||||
this._executablePath = executablePath;
|
||||
const uuid = crypto.randomUUID();
|
||||
this._cdpPath = `/cdp/${uuid}`;
|
||||
this._extensionPath = `/extension/${uuid}`;
|
||||
this._resetExtensionConnection();
|
||||
this._wss = new import_utilsBundle.wsServer({ server });
|
||||
this._wss.on("connection", this._onConnection.bind(this));
|
||||
}
|
||||
cdpEndpoint() {
|
||||
return `${this._wsHost}${this._cdpPath}`;
|
||||
}
|
||||
extensionEndpoint() {
|
||||
return `${this._wsHost}${this._extensionPath}`;
|
||||
}
|
||||
async ensureExtensionConnectionForMCPContext(clientInfo) {
|
||||
debugLogger("Ensuring extension connection for MCP context");
|
||||
if (this._extensionConnection)
|
||||
return;
|
||||
this._connectBrowser(clientInfo);
|
||||
debugLogger("Waiting for incoming extension connection");
|
||||
await Promise.race([
|
||||
this._extensionConnectionPromise,
|
||||
new Promise((_, reject) => setTimeout(() => {
|
||||
reject(new Error(`Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed. See https://github.com/microsoft/playwright-mcp/blob/main/packages/extension/README.md for installation instructions.`));
|
||||
}, process.env.PWMCP_TEST_CONNECTION_TIMEOUT ? parseInt(process.env.PWMCP_TEST_CONNECTION_TIMEOUT, 10) : 5e3))
|
||||
]);
|
||||
debugLogger("Extension connection established");
|
||||
}
|
||||
_connectBrowser(clientInfo) {
|
||||
const mcpRelayEndpoint = `${this._wsHost}${this._extensionPath}`;
|
||||
const url = new URL("chrome-extension://mmlmfjhmonkocbjadbfplnigmagldckm/connect.html");
|
||||
url.searchParams.set("mcpRelayUrl", mcpRelayEndpoint);
|
||||
const client = {
|
||||
name: "Playwright Agent",
|
||||
version: require("../../../package.json").version
|
||||
};
|
||||
url.searchParams.set("client", JSON.stringify(client));
|
||||
url.searchParams.set("protocolVersion", process.env.PWMCP_TEST_PROTOCOL_VERSION ?? protocol.VERSION.toString());
|
||||
const token = process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN;
|
||||
if (token)
|
||||
url.searchParams.set("token", token);
|
||||
const href = url.toString();
|
||||
const channel = import_registry.registry.isChromiumAlias(this._browserChannel) ? "chromium" : this._browserChannel;
|
||||
let executablePath = this._executablePath;
|
||||
if (!executablePath) {
|
||||
const executableInfo = import_registry.registry.findExecutable(channel);
|
||||
if (!executableInfo)
|
||||
throw new Error(`Unsupported channel: "${this._browserChannel}"`);
|
||||
executablePath = executableInfo.executablePath();
|
||||
if (!executablePath)
|
||||
throw new Error(`"${this._browserChannel}" executable not found. Make sure it is installed at a standard location.`);
|
||||
}
|
||||
const args = [];
|
||||
if (this._userDataDir)
|
||||
args.push(`--user-data-dir=${this._userDataDir}`);
|
||||
if (import_os.default.platform() === "linux" && channel === "chromium")
|
||||
args.push("--no-sandbox");
|
||||
args.push(href);
|
||||
(0, import_child_process.spawn)(executablePath, args, {
|
||||
windowsHide: true,
|
||||
detached: true,
|
||||
shell: false,
|
||||
stdio: "ignore"
|
||||
});
|
||||
}
|
||||
stop() {
|
||||
this.closeConnections("Server stopped");
|
||||
this._wss.close();
|
||||
}
|
||||
closeConnections(reason) {
|
||||
this._closePlaywrightConnection(reason);
|
||||
this._closeExtensionConnection(reason);
|
||||
}
|
||||
_onConnection(ws2, request) {
|
||||
const url = new URL(`http://localhost${request.url}`);
|
||||
debugLogger(`New connection to ${url.pathname}`);
|
||||
if (url.pathname === this._cdpPath) {
|
||||
this._handlePlaywrightConnection(ws2);
|
||||
} else if (url.pathname === this._extensionPath) {
|
||||
this._handleExtensionConnection(ws2);
|
||||
} else {
|
||||
debugLogger(`Invalid path: ${url.pathname}`);
|
||||
ws2.close(4004, "Invalid path");
|
||||
}
|
||||
}
|
||||
_handlePlaywrightConnection(ws2) {
|
||||
if (this._playwrightConnection) {
|
||||
debugLogger("Rejecting second Playwright connection");
|
||||
ws2.close(1e3, "Another CDP client already connected");
|
||||
return;
|
||||
}
|
||||
this._playwrightConnection = ws2;
|
||||
ws2.on("message", async (data) => {
|
||||
try {
|
||||
const message = JSON.parse(data.toString());
|
||||
await this._handlePlaywrightMessage(message);
|
||||
} catch (error) {
|
||||
debugLogger(`Error while handling Playwright message
|
||||
${data.toString()}
|
||||
`, error);
|
||||
}
|
||||
});
|
||||
ws2.on("close", () => {
|
||||
if (this._playwrightConnection !== ws2)
|
||||
return;
|
||||
this._playwrightConnection = null;
|
||||
this._closeExtensionConnection("Playwright client disconnected");
|
||||
debugLogger("Playwright WebSocket closed");
|
||||
});
|
||||
ws2.on("error", (error) => {
|
||||
debugLogger("Playwright WebSocket error:", error);
|
||||
});
|
||||
debugLogger("Playwright MCP connected");
|
||||
}
|
||||
_closeExtensionConnection(reason) {
|
||||
this._extensionConnection?.close(reason);
|
||||
this._extensionConnectionPromise.reject(new Error(reason));
|
||||
this._resetExtensionConnection();
|
||||
}
|
||||
_resetExtensionConnection() {
|
||||
this._connectedTabInfo = void 0;
|
||||
this._extensionConnection = null;
|
||||
this._extensionConnectionPromise = new import_manualPromise.ManualPromise();
|
||||
void this._extensionConnectionPromise.catch(import_log.logUnhandledError);
|
||||
}
|
||||
_closePlaywrightConnection(reason) {
|
||||
if (this._playwrightConnection?.readyState === import_utilsBundle.ws.OPEN)
|
||||
this._playwrightConnection.close(1e3, reason);
|
||||
this._playwrightConnection = null;
|
||||
}
|
||||
_handleExtensionConnection(ws2) {
|
||||
if (this._extensionConnection) {
|
||||
ws2.close(1e3, "Another extension connection already established");
|
||||
return;
|
||||
}
|
||||
this._extensionConnection = new ExtensionConnection(ws2);
|
||||
this._extensionConnection.onclose = (c, reason) => {
|
||||
debugLogger("Extension WebSocket closed:", reason, c === this._extensionConnection);
|
||||
if (this._extensionConnection !== c)
|
||||
return;
|
||||
this._resetExtensionConnection();
|
||||
this._closePlaywrightConnection(`Extension disconnected: ${reason}`);
|
||||
};
|
||||
this._extensionConnection.onmessage = this._handleExtensionMessage.bind(this);
|
||||
this._extensionConnectionPromise.resolve();
|
||||
}
|
||||
_handleExtensionMessage(method, params) {
|
||||
switch (method) {
|
||||
case "forwardCDPEvent":
|
||||
const sessionId = params.sessionId || this._connectedTabInfo?.sessionId;
|
||||
this._sendToPlaywright({
|
||||
sessionId,
|
||||
method: params.method,
|
||||
params: params.params
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
async _handlePlaywrightMessage(message) {
|
||||
debugLogger("\u2190 Playwright:", `${message.method} (id=${message.id})`);
|
||||
const { id, sessionId, method, params } = message;
|
||||
try {
|
||||
const result = await this._handleCDPCommand(method, params, sessionId);
|
||||
this._sendToPlaywright({ id, sessionId, result });
|
||||
} catch (e) {
|
||||
debugLogger("Error in the extension:", e);
|
||||
this._sendToPlaywright({
|
||||
id,
|
||||
sessionId,
|
||||
error: { message: e.message }
|
||||
});
|
||||
}
|
||||
}
|
||||
async _handleCDPCommand(method, params, sessionId) {
|
||||
switch (method) {
|
||||
case "Browser.getVersion": {
|
||||
return {
|
||||
protocolVersion: "1.3",
|
||||
product: "Chrome/Extension-Bridge",
|
||||
userAgent: "CDP-Bridge-Server/1.0.0"
|
||||
};
|
||||
}
|
||||
case "Browser.setDownloadBehavior": {
|
||||
return {};
|
||||
}
|
||||
case "Target.setAutoAttach": {
|
||||
if (sessionId)
|
||||
break;
|
||||
const { targetInfo } = await this._extensionConnection.send("attachToTab", {});
|
||||
this._connectedTabInfo = {
|
||||
targetInfo,
|
||||
sessionId: `pw-tab-${this._nextSessionId++}`
|
||||
};
|
||||
debugLogger("Simulating auto-attach");
|
||||
this._sendToPlaywright({
|
||||
method: "Target.attachedToTarget",
|
||||
params: {
|
||||
sessionId: this._connectedTabInfo.sessionId,
|
||||
targetInfo: {
|
||||
...this._connectedTabInfo.targetInfo,
|
||||
attached: true
|
||||
},
|
||||
waitingForDebugger: false
|
||||
}
|
||||
});
|
||||
return {};
|
||||
}
|
||||
case "Target.getTargetInfo": {
|
||||
return this._connectedTabInfo?.targetInfo;
|
||||
}
|
||||
}
|
||||
return await this._forwardToExtension(method, params, sessionId);
|
||||
}
|
||||
async _forwardToExtension(method, params, sessionId) {
|
||||
if (!this._extensionConnection)
|
||||
throw new Error("Extension not connected");
|
||||
if (this._connectedTabInfo?.sessionId === sessionId)
|
||||
sessionId = void 0;
|
||||
return await this._extensionConnection.send("forwardCDPCommand", { sessionId, method, params });
|
||||
}
|
||||
_sendToPlaywright(message) {
|
||||
debugLogger("\u2192 Playwright:", `${message.method ?? `response(id=${message.id})`}`);
|
||||
this._playwrightConnection?.send(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
class ExtensionConnection {
|
||||
constructor(ws2) {
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._lastId = 0;
|
||||
this._ws = ws2;
|
||||
this._ws.on("message", this._onMessage.bind(this));
|
||||
this._ws.on("close", this._onClose.bind(this));
|
||||
this._ws.on("error", this._onError.bind(this));
|
||||
}
|
||||
async send(method, params) {
|
||||
if (this._ws.readyState !== import_utilsBundle.ws.OPEN)
|
||||
throw new Error(`Unexpected WebSocket state: ${this._ws.readyState}`);
|
||||
const id = ++this._lastId;
|
||||
this._ws.send(JSON.stringify({ id, method, params }));
|
||||
const error = new Error(`Protocol error: ${method}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject, error });
|
||||
});
|
||||
}
|
||||
close(message) {
|
||||
debugLogger("closing extension connection:", message);
|
||||
if (this._ws.readyState === import_utilsBundle.ws.OPEN)
|
||||
this._ws.close(1e3, message);
|
||||
}
|
||||
_onMessage(event) {
|
||||
const eventData = event.toString();
|
||||
let parsedJson;
|
||||
try {
|
||||
parsedJson = JSON.parse(eventData);
|
||||
} catch (e) {
|
||||
debugLogger(`<closing ws> Closing websocket due to malformed JSON. eventData=${eventData} e=${e?.message}`);
|
||||
this._ws.close();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this._handleParsedMessage(parsedJson);
|
||||
} catch (e) {
|
||||
debugLogger(`<closing ws> Closing websocket due to failed onmessage callback. eventData=${eventData} e=${e?.message}`);
|
||||
this._ws.close();
|
||||
}
|
||||
}
|
||||
_handleParsedMessage(object) {
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error) {
|
||||
const error = callback.error;
|
||||
error.message = object.error;
|
||||
callback.reject(error);
|
||||
} else {
|
||||
callback.resolve(object.result);
|
||||
}
|
||||
} else if (object.id) {
|
||||
debugLogger("\u2190 Extension: unexpected response", object);
|
||||
} else {
|
||||
this.onmessage?.(object.method, object.params);
|
||||
}
|
||||
}
|
||||
_onClose(event) {
|
||||
debugLogger(`<ws closed> code=${event.code} reason=${event.reason}`);
|
||||
this._dispose();
|
||||
this.onclose?.(this, event.reason);
|
||||
}
|
||||
_onError(event) {
|
||||
debugLogger(`<ws error> message=${event.message} type=${event.type} target=${event.target}`);
|
||||
this._dispose();
|
||||
}
|
||||
_dispose() {
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(new Error("WebSocket closed"));
|
||||
this._callbacks.clear();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CDPRelayServer
|
||||
});
|
||||
7
node_modules/playwright-core/lib/tools/mcp/cli-stub.js
generated
vendored
Normal file
7
node_modules/playwright-core/lib/tools/mcp/cli-stub.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
var import_program = require("./program");
|
||||
const packageJSON = require("../../../package.json");
|
||||
const p = import_utilsBundle.program.version("Version " + packageJSON.version).name("Playwright MCP");
|
||||
(0, import_program.decorateMCPCommand)(p);
|
||||
void import_utilsBundle.program.parseAsync(process.argv);
|
||||
16
node_modules/playwright-core/lib/tools/mcp/config.d.js
generated
vendored
Normal file
16
node_modules/playwright-core/lib/tools/mcp/config.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 config_d_exports = {};
|
||||
module.exports = __toCommonJS(config_d_exports);
|
||||
446
node_modules/playwright-core/lib/tools/mcp/config.js
generated
vendored
Normal file
446
node_modules/playwright-core/lib/tools/mcp/config.js
generated
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
"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 config_exports = {};
|
||||
__export(config_exports, {
|
||||
commaSeparatedList: () => commaSeparatedList,
|
||||
configFromEnv: () => configFromEnv,
|
||||
dotenvFileLoader: () => dotenvFileLoader,
|
||||
enumParser: () => enumParser,
|
||||
headerParser: () => headerParser,
|
||||
loadConfig: () => loadConfig,
|
||||
numberParser: () => numberParser,
|
||||
resolutionParser: () => resolutionParser,
|
||||
resolveCLIConfigForCLI: () => resolveCLIConfigForCLI,
|
||||
resolveCLIConfigForMCP: () => resolveCLIConfigForMCP,
|
||||
resolveConfig: () => resolveConfig,
|
||||
semicolonSeparatedList: () => semicolonSeparatedList
|
||||
});
|
||||
module.exports = __toCommonJS(config_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import__ = require("../../..");
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
var import_configIni = require("./configIni");
|
||||
async function fileExistsAsync(resolved) {
|
||||
try {
|
||||
return (await import_fs.default.promises.stat(resolved)).isFile();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const defaultConfig = {
|
||||
browser: {
|
||||
launchOptions: {},
|
||||
contextOptions: {}
|
||||
},
|
||||
timeouts: {
|
||||
action: 5e3,
|
||||
navigation: 6e4,
|
||||
expect: 5e3
|
||||
}
|
||||
};
|
||||
async function resolveConfig(config) {
|
||||
const merged = mergeConfig(defaultConfig, config);
|
||||
const browser = await validateBrowserConfig(merged.browser);
|
||||
return { ...merged, browser };
|
||||
}
|
||||
async function resolveCLIConfigForMCP(cliOptions, env) {
|
||||
const envOverrides = configFromEnv(env);
|
||||
const cliOverrides = configFromCLIOptions(cliOptions);
|
||||
const configFile = cliOverrides.configFile ?? envOverrides.configFile;
|
||||
const configInFile = await loadConfig(configFile);
|
||||
let result = defaultConfig;
|
||||
result = mergeConfig(result, configInFile);
|
||||
result = mergeConfig(result, envOverrides);
|
||||
result = mergeConfig(result, cliOverrides);
|
||||
const browser = await validateBrowserConfig(result.browser);
|
||||
if (browser.launchOptions.headless === void 0)
|
||||
browser.launchOptions.headless = import_os.default.platform() === "linux" && !process.env.DISPLAY;
|
||||
return { ...result, browser, configFile };
|
||||
}
|
||||
async function resolveCLIConfigForCLI(daemonProfilesDir, sessionName, options, env) {
|
||||
const config = options.config ? import_path.default.resolve(options.config) : void 0;
|
||||
try {
|
||||
const defaultConfigFile = import_path.default.resolve(".playwright", "cli.config.json");
|
||||
if (!config && import_fs.default.existsSync(defaultConfigFile))
|
||||
options.config = defaultConfigFile;
|
||||
} catch {
|
||||
}
|
||||
const daemonOverrides = configFromCLIOptions({
|
||||
endpoint: options.endpoint,
|
||||
config: options.config,
|
||||
browser: options.browser,
|
||||
headless: options.headed ? false : void 0,
|
||||
extension: options.extension,
|
||||
userDataDir: options.profile,
|
||||
snapshotMode: "full"
|
||||
});
|
||||
const envOverrides = configFromEnv(env);
|
||||
const configFile = daemonOverrides.configFile ?? envOverrides.configFile;
|
||||
const configInFile = await loadConfig(configFile);
|
||||
const globalConfigPath = import_path.default.join((env ?? process.env)["PWTEST_CLI_GLOBAL_CONFIG"] ?? import_os.default.homedir(), ".playwright", "cli.config.json");
|
||||
const globalConfigInFile = await loadConfig(import_fs.default.existsSync(globalConfigPath) ? globalConfigPath : void 0);
|
||||
let result = defaultConfig;
|
||||
result = mergeConfig(result, globalConfigInFile);
|
||||
result = mergeConfig(result, configInFile);
|
||||
result = mergeConfig(result, envOverrides);
|
||||
result = mergeConfig(result, daemonOverrides);
|
||||
if (result.browser.isolated === void 0)
|
||||
result.browser.isolated = !options.profile && !options.persistent && !result.browser.userDataDir && !result.browser.remoteEndpoint && !result.extension;
|
||||
if (!result.extension && !result.browser.isolated && !result.browser.userDataDir && !result.browser.remoteEndpoint) {
|
||||
const browserToken = result.browser.launchOptions?.channel ?? result.browser?.browserName;
|
||||
const userDataDir = import_path.default.resolve(daemonProfilesDir, `ud-${sessionName}-${browserToken}`);
|
||||
result.browser.userDataDir = userDataDir;
|
||||
}
|
||||
if (result.browser.launchOptions.headless === void 0)
|
||||
result.browser.launchOptions.headless = true;
|
||||
const browser = await validateBrowserConfig(result.browser);
|
||||
return { ...result, browser, configFile, skillMode: true };
|
||||
}
|
||||
async function validateBrowserConfig(browser) {
|
||||
let browserName = browser.browserName;
|
||||
if (!browserName) {
|
||||
browserName = "chromium";
|
||||
if (browser.launchOptions.channel === void 0)
|
||||
browser.launchOptions.channel = "chrome";
|
||||
}
|
||||
if (browser.browserName === "chromium" && browser.launchOptions.chromiumSandbox === void 0) {
|
||||
if (process.platform === "linux")
|
||||
browser.launchOptions.chromiumSandbox = browser.launchOptions.channel !== "chromium" && browser.launchOptions.channel !== "chrome-for-testing";
|
||||
else
|
||||
browser.launchOptions.chromiumSandbox = true;
|
||||
}
|
||||
if (browser.isolated && browser.userDataDir)
|
||||
throw new Error("Browser userDataDir is not supported in isolated mode.");
|
||||
if (browser.initScript) {
|
||||
for (const script of browser.initScript) {
|
||||
if (!await fileExistsAsync(script))
|
||||
throw new Error(`Init script file does not exist: ${script}`);
|
||||
}
|
||||
}
|
||||
if (browser.initPage) {
|
||||
for (const page of browser.initPage) {
|
||||
if (!await fileExistsAsync(page))
|
||||
throw new Error(`Init page file does not exist: ${page}`);
|
||||
}
|
||||
}
|
||||
if (browser.contextOptions.viewport === void 0) {
|
||||
if (browser.launchOptions.headless)
|
||||
browser.contextOptions.viewport = { width: 1280, height: 720 };
|
||||
else
|
||||
browser.contextOptions.viewport = null;
|
||||
}
|
||||
return { ...browser, browserName };
|
||||
}
|
||||
function configFromCLIOptions(cliOptions) {
|
||||
let browserName;
|
||||
let channel;
|
||||
switch (cliOptions.browser) {
|
||||
case "chrome":
|
||||
case "chrome-beta":
|
||||
case "chrome-canary":
|
||||
case "chrome-dev":
|
||||
case "msedge":
|
||||
case "msedge-beta":
|
||||
case "msedge-canary":
|
||||
case "msedge-dev":
|
||||
browserName = "chromium";
|
||||
channel = cliOptions.browser;
|
||||
break;
|
||||
case "chromium":
|
||||
browserName = "chromium";
|
||||
channel = "chrome-for-testing";
|
||||
break;
|
||||
case "firefox":
|
||||
browserName = "firefox";
|
||||
break;
|
||||
case "webkit":
|
||||
browserName = "webkit";
|
||||
break;
|
||||
}
|
||||
const launchOptions = {
|
||||
channel,
|
||||
executablePath: cliOptions.executablePath,
|
||||
headless: cliOptions.headless
|
||||
};
|
||||
if (cliOptions.sandbox !== void 0)
|
||||
launchOptions.chromiumSandbox = cliOptions.sandbox;
|
||||
if (cliOptions.proxyServer) {
|
||||
launchOptions.proxy = {
|
||||
server: cliOptions.proxyServer
|
||||
};
|
||||
if (cliOptions.proxyBypass)
|
||||
launchOptions.proxy.bypass = cliOptions.proxyBypass;
|
||||
}
|
||||
if (cliOptions.device && cliOptions.cdpEndpoint)
|
||||
throw new Error("Device emulation is not supported with cdpEndpoint.");
|
||||
const contextOptions = cliOptions.device ? import__.devices[cliOptions.device] : {};
|
||||
if (cliOptions.storageState)
|
||||
contextOptions.storageState = cliOptions.storageState;
|
||||
if (cliOptions.userAgent)
|
||||
contextOptions.userAgent = cliOptions.userAgent;
|
||||
if (cliOptions.viewportSize)
|
||||
contextOptions.viewport = cliOptions.viewportSize;
|
||||
if (cliOptions.ignoreHttpsErrors)
|
||||
contextOptions.ignoreHTTPSErrors = true;
|
||||
if (cliOptions.blockServiceWorkers)
|
||||
contextOptions.serviceWorkers = "block";
|
||||
if (cliOptions.grantPermissions)
|
||||
contextOptions.permissions = cliOptions.grantPermissions;
|
||||
const config = {
|
||||
browser: {
|
||||
browserName,
|
||||
isolated: cliOptions.isolated,
|
||||
userDataDir: cliOptions.userDataDir,
|
||||
launchOptions,
|
||||
contextOptions,
|
||||
cdpEndpoint: cliOptions.cdpEndpoint,
|
||||
cdpHeaders: cliOptions.cdpHeader,
|
||||
cdpTimeout: cliOptions.cdpTimeout,
|
||||
initPage: cliOptions.initPage,
|
||||
initScript: cliOptions.initScript,
|
||||
remoteEndpoint: cliOptions.endpoint
|
||||
},
|
||||
extension: cliOptions.extension,
|
||||
server: {
|
||||
port: cliOptions.port,
|
||||
host: cliOptions.host,
|
||||
allowedHosts: cliOptions.allowedHosts
|
||||
},
|
||||
capabilities: cliOptions.caps,
|
||||
console: {
|
||||
level: cliOptions.consoleLevel
|
||||
},
|
||||
network: {
|
||||
allowedOrigins: cliOptions.allowedOrigins,
|
||||
blockedOrigins: cliOptions.blockedOrigins
|
||||
},
|
||||
allowUnrestrictedFileAccess: cliOptions.allowUnrestrictedFileAccess,
|
||||
codegen: cliOptions.codegen,
|
||||
saveSession: cliOptions.saveSession,
|
||||
secrets: cliOptions.secrets,
|
||||
sharedBrowserContext: cliOptions.sharedBrowserContext,
|
||||
snapshot: cliOptions.snapshotMode ? { mode: cliOptions.snapshotMode } : void 0,
|
||||
outputDir: cliOptions.outputDir,
|
||||
imageResponses: cliOptions.imageResponses,
|
||||
testIdAttribute: cliOptions.testIdAttribute,
|
||||
timeouts: {
|
||||
action: cliOptions.timeoutAction,
|
||||
navigation: cliOptions.timeoutNavigation
|
||||
}
|
||||
};
|
||||
return { ...config, configFile: cliOptions.config };
|
||||
}
|
||||
function configFromEnv(env) {
|
||||
const e = env ?? process.env;
|
||||
const options = {};
|
||||
options.allowedHosts = commaSeparatedList(e.PLAYWRIGHT_MCP_ALLOWED_HOSTS);
|
||||
options.allowedOrigins = semicolonSeparatedList(e.PLAYWRIGHT_MCP_ALLOWED_ORIGINS);
|
||||
options.allowUnrestrictedFileAccess = envToBoolean(e.PLAYWRIGHT_MCP_ALLOW_UNRESTRICTED_FILE_ACCESS);
|
||||
options.blockedOrigins = semicolonSeparatedList(e.PLAYWRIGHT_MCP_BLOCKED_ORIGINS);
|
||||
options.blockServiceWorkers = envToBoolean(e.PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS);
|
||||
options.browser = envToString(e.PLAYWRIGHT_MCP_BROWSER);
|
||||
options.caps = commaSeparatedList(e.PLAYWRIGHT_MCP_CAPS);
|
||||
options.cdpEndpoint = envToString(e.PLAYWRIGHT_MCP_CDP_ENDPOINT);
|
||||
options.cdpHeader = headerParser(envToString(e.PLAYWRIGHT_MCP_CDP_HEADERS));
|
||||
options.cdpTimeout = numberParser(e.PLAYWRIGHT_MCP_CDP_TIMEOUT);
|
||||
options.config = envToString(e.PLAYWRIGHT_MCP_CONFIG);
|
||||
if (e.PLAYWRIGHT_MCP_CONSOLE_LEVEL)
|
||||
options.consoleLevel = enumParser("--console-level", ["error", "warning", "info", "debug"], e.PLAYWRIGHT_MCP_CONSOLE_LEVEL);
|
||||
options.device = envToString(e.PLAYWRIGHT_MCP_DEVICE);
|
||||
options.executablePath = envToString(e.PLAYWRIGHT_MCP_EXECUTABLE_PATH);
|
||||
options.extension = envToBoolean(e.PLAYWRIGHT_MCP_EXTENSION);
|
||||
options.grantPermissions = commaSeparatedList(e.PLAYWRIGHT_MCP_GRANT_PERMISSIONS);
|
||||
options.headless = envToBoolean(e.PLAYWRIGHT_MCP_HEADLESS);
|
||||
options.host = envToString(e.PLAYWRIGHT_MCP_HOST);
|
||||
options.ignoreHttpsErrors = envToBoolean(e.PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS);
|
||||
const initPage = envToString(e.PLAYWRIGHT_MCP_INIT_PAGE);
|
||||
if (initPage)
|
||||
options.initPage = [initPage];
|
||||
const initScript = envToString(e.PLAYWRIGHT_MCP_INIT_SCRIPT);
|
||||
if (initScript)
|
||||
options.initScript = [initScript];
|
||||
options.isolated = envToBoolean(e.PLAYWRIGHT_MCP_ISOLATED);
|
||||
if (e.PLAYWRIGHT_MCP_IMAGE_RESPONSES)
|
||||
options.imageResponses = enumParser("--image-responses", ["allow", "omit"], e.PLAYWRIGHT_MCP_IMAGE_RESPONSES);
|
||||
options.sandbox = envToBoolean(e.PLAYWRIGHT_MCP_SANDBOX);
|
||||
options.outputDir = envToString(e.PLAYWRIGHT_MCP_OUTPUT_DIR);
|
||||
options.port = numberParser(e.PLAYWRIGHT_MCP_PORT);
|
||||
options.proxyBypass = envToString(e.PLAYWRIGHT_MCP_PROXY_BYPASS);
|
||||
options.proxyServer = envToString(e.PLAYWRIGHT_MCP_PROXY_SERVER);
|
||||
options.secrets = dotenvFileLoader(e.PLAYWRIGHT_MCP_SECRETS_FILE);
|
||||
options.storageState = envToString(e.PLAYWRIGHT_MCP_STORAGE_STATE);
|
||||
options.testIdAttribute = envToString(e.PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE);
|
||||
options.timeoutAction = numberParser(e.PLAYWRIGHT_MCP_TIMEOUT_ACTION);
|
||||
options.timeoutNavigation = numberParser(e.PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION);
|
||||
options.userAgent = envToString(e.PLAYWRIGHT_MCP_USER_AGENT);
|
||||
options.userDataDir = envToString(e.PLAYWRIGHT_MCP_USER_DATA_DIR);
|
||||
options.viewportSize = resolutionParser("--viewport-size", e.PLAYWRIGHT_MCP_VIEWPORT_SIZE);
|
||||
return configFromCLIOptions(options);
|
||||
}
|
||||
async function loadConfig(configFile) {
|
||||
if (!configFile)
|
||||
return {};
|
||||
if (configFile.endsWith(".ini"))
|
||||
return (0, import_configIni.configFromIniFile)(configFile);
|
||||
try {
|
||||
const data = await import_fs.default.promises.readFile(configFile, "utf8");
|
||||
return JSON.parse(data.charCodeAt(0) === 65279 ? data.slice(1) : data);
|
||||
} catch {
|
||||
return (0, import_configIni.configFromIniFile)(configFile);
|
||||
}
|
||||
}
|
||||
function pickDefined(obj) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj ?? {}).filter(([_, v]) => v !== void 0)
|
||||
);
|
||||
}
|
||||
function mergeConfig(base, overrides) {
|
||||
const browser = {
|
||||
...pickDefined(base.browser),
|
||||
...pickDefined(overrides.browser),
|
||||
browserName: overrides.browser?.browserName ?? base.browser?.browserName,
|
||||
isolated: overrides.browser?.isolated ?? base.browser?.isolated,
|
||||
launchOptions: {
|
||||
...pickDefined(base.browser?.launchOptions),
|
||||
...pickDefined(overrides.browser?.launchOptions),
|
||||
// Assistant mode is not a part of the public API.
|
||||
...{ assistantMode: true }
|
||||
},
|
||||
contextOptions: {
|
||||
...pickDefined(base.browser?.contextOptions),
|
||||
...pickDefined(overrides.browser?.contextOptions)
|
||||
}
|
||||
};
|
||||
if (browser.browserName !== "chromium" && browser.launchOptions)
|
||||
delete browser.launchOptions.channel;
|
||||
return {
|
||||
...pickDefined(base),
|
||||
...pickDefined(overrides),
|
||||
browser,
|
||||
console: {
|
||||
...pickDefined(base.console),
|
||||
...pickDefined(overrides.console)
|
||||
},
|
||||
network: {
|
||||
...pickDefined(base.network),
|
||||
...pickDefined(overrides.network)
|
||||
},
|
||||
server: {
|
||||
...pickDefined(base.server),
|
||||
...pickDefined(overrides.server)
|
||||
},
|
||||
snapshot: {
|
||||
...pickDefined(base.snapshot),
|
||||
...pickDefined(overrides.snapshot)
|
||||
},
|
||||
timeouts: {
|
||||
...pickDefined(base.timeouts),
|
||||
...pickDefined(overrides.timeouts)
|
||||
}
|
||||
};
|
||||
}
|
||||
function semicolonSeparatedList(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return value.split(";").map((v) => v.trim());
|
||||
}
|
||||
function commaSeparatedList(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return value.split(",").map((v) => v.trim());
|
||||
}
|
||||
function dotenvFileLoader(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return import_utilsBundle.dotenv.parse(import_fs.default.readFileSync(value, "utf8"));
|
||||
}
|
||||
function numberParser(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return +value;
|
||||
}
|
||||
function resolutionParser(name, value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
if (value.includes("x")) {
|
||||
const [width, height] = value.split("x").map((v) => +v);
|
||||
if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0)
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
return { width, height };
|
||||
}
|
||||
if (value.includes(",")) {
|
||||
const [width, height] = value.split(",").map((v) => +v);
|
||||
if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0)
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
return { width, height };
|
||||
}
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
}
|
||||
function headerParser(arg, previous) {
|
||||
if (!arg)
|
||||
return previous;
|
||||
const result = { ...previous ?? {} };
|
||||
const colonIndex = arg.indexOf(":");
|
||||
const name = colonIndex === -1 ? arg.trim() : arg.substring(0, colonIndex).trim();
|
||||
const value = colonIndex === -1 ? "" : arg.substring(colonIndex + 1).trim();
|
||||
result[name] = value;
|
||||
return result;
|
||||
}
|
||||
function enumParser(name, options, value) {
|
||||
if (!options.includes(value))
|
||||
throw new Error(`Invalid ${name}: ${value}. Valid values are: ${options.join(", ")}`);
|
||||
return value;
|
||||
}
|
||||
function envToBoolean(value) {
|
||||
if (value === "true" || value === "1")
|
||||
return true;
|
||||
if (value === "false" || value === "0")
|
||||
return false;
|
||||
return void 0;
|
||||
}
|
||||
function envToString(value) {
|
||||
return value ? value.trim() : void 0;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
commaSeparatedList,
|
||||
configFromEnv,
|
||||
dotenvFileLoader,
|
||||
enumParser,
|
||||
headerParser,
|
||||
loadConfig,
|
||||
numberParser,
|
||||
resolutionParser,
|
||||
resolveCLIConfigForCLI,
|
||||
resolveCLIConfigForMCP,
|
||||
resolveConfig,
|
||||
semicolonSeparatedList
|
||||
});
|
||||
189
node_modules/playwright-core/lib/tools/mcp/configIni.js
generated
vendored
Normal file
189
node_modules/playwright-core/lib/tools/mcp/configIni.js
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
"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 configIni_exports = {};
|
||||
__export(configIni_exports, {
|
||||
configFromIniFile: () => configFromIniFile,
|
||||
configsFromIniFile: () => configsFromIniFile
|
||||
});
|
||||
module.exports = __toCommonJS(configIni_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
function configFromIniFile(filePath) {
|
||||
const content = import_fs.default.readFileSync(filePath, "utf8");
|
||||
const parsed = import_utilsBundle.ini.parse(content);
|
||||
return iniEntriesToConfig(parsed);
|
||||
}
|
||||
function configsFromIniFile(filePath) {
|
||||
const content = import_fs.default.readFileSync(filePath, "utf8");
|
||||
const parsed = import_utilsBundle.ini.parse(content);
|
||||
const result = /* @__PURE__ */ new Map();
|
||||
for (const [sectionName, sectionData] of Object.entries(parsed)) {
|
||||
if (typeof sectionData !== "object" || sectionData === null)
|
||||
continue;
|
||||
result.set(sectionName, iniEntriesToConfig(sectionData));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function iniEntriesToConfig(entries) {
|
||||
const config = {};
|
||||
for (const [targetPath, rawValue] of Object.entries(entries)) {
|
||||
const type = longhandTypes[targetPath];
|
||||
const value = type ? coerceToType(rawValue, type) : coerceIniValue(rawValue);
|
||||
setNestedValue(config, targetPath, value);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
function coerceToType(value, type) {
|
||||
switch (type) {
|
||||
case "string":
|
||||
return String(value);
|
||||
case "number":
|
||||
return Number(value);
|
||||
case "boolean":
|
||||
if (typeof value === "boolean")
|
||||
return value;
|
||||
return value === "true" || value === "1";
|
||||
case "string[]":
|
||||
if (Array.isArray(value))
|
||||
return value.map(String);
|
||||
return [String(value)];
|
||||
case "size": {
|
||||
if (typeof value === "string" && value.includes("x")) {
|
||||
const [w, h] = value.split("x").map(Number);
|
||||
if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0)
|
||||
return { width: w, height: h };
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
function coerceIniValue(value) {
|
||||
if (typeof value !== "string")
|
||||
return value;
|
||||
const trimmed = value.trim();
|
||||
if (trimmed === "")
|
||||
return trimmed;
|
||||
const num = Number(trimmed);
|
||||
if (!isNaN(num))
|
||||
return num;
|
||||
return value;
|
||||
}
|
||||
function setNestedValue(obj, dotPath, value) {
|
||||
const parts = dotPath.split(".");
|
||||
let current = obj;
|
||||
for (let i = 0; i < parts.length - 1; i++) {
|
||||
const part = parts[i];
|
||||
if (!(part in current) || typeof current[part] !== "object" || current[part] === null)
|
||||
current[part] = {};
|
||||
current = current[part];
|
||||
}
|
||||
current[parts[parts.length - 1]] = value;
|
||||
}
|
||||
const longhandTypes = {
|
||||
// browser direct
|
||||
"browser.browserName": "string",
|
||||
"browser.isolated": "boolean",
|
||||
"browser.userDataDir": "string",
|
||||
"browser.cdpEndpoint": "string",
|
||||
"browser.cdpTimeout": "number",
|
||||
"browser.remoteEndpoint": "string",
|
||||
"browser.initPage": "string[]",
|
||||
"browser.initScript": "string[]",
|
||||
// browser.launchOptions
|
||||
"browser.launchOptions.channel": "string",
|
||||
"browser.launchOptions.headless": "boolean",
|
||||
"browser.launchOptions.executablePath": "string",
|
||||
"browser.launchOptions.chromiumSandbox": "boolean",
|
||||
"browser.launchOptions.args": "string[]",
|
||||
"browser.launchOptions.downloadsPath": "string",
|
||||
"browser.launchOptions.handleSIGHUP": "boolean",
|
||||
"browser.launchOptions.handleSIGINT": "boolean",
|
||||
"browser.launchOptions.handleSIGTERM": "boolean",
|
||||
"browser.launchOptions.slowMo": "number",
|
||||
"browser.launchOptions.timeout": "number",
|
||||
"browser.launchOptions.tracesDir": "string",
|
||||
"browser.launchOptions.proxy.server": "string",
|
||||
"browser.launchOptions.proxy.bypass": "string",
|
||||
"browser.launchOptions.proxy.username": "string",
|
||||
"browser.launchOptions.proxy.password": "string",
|
||||
// browser.contextOptions
|
||||
"browser.contextOptions.acceptDownloads": "boolean",
|
||||
"browser.contextOptions.baseURL": "string",
|
||||
"browser.contextOptions.bypassCSP": "boolean",
|
||||
"browser.contextOptions.colorScheme": "string",
|
||||
"browser.contextOptions.contrast": "string",
|
||||
"browser.contextOptions.deviceScaleFactor": "number",
|
||||
"browser.contextOptions.forcedColors": "string",
|
||||
"browser.contextOptions.hasTouch": "boolean",
|
||||
"browser.contextOptions.ignoreHTTPSErrors": "boolean",
|
||||
"browser.contextOptions.isMobile": "boolean",
|
||||
"browser.contextOptions.javaScriptEnabled": "boolean",
|
||||
"browser.contextOptions.locale": "string",
|
||||
"browser.contextOptions.offline": "boolean",
|
||||
"browser.contextOptions.permissions": "string[]",
|
||||
"browser.contextOptions.reducedMotion": "string",
|
||||
"browser.contextOptions.screen": "size",
|
||||
"browser.contextOptions.serviceWorkers": "string",
|
||||
"browser.contextOptions.storageState": "string",
|
||||
"browser.contextOptions.strictSelectors": "boolean",
|
||||
"browser.contextOptions.timezoneId": "string",
|
||||
"browser.contextOptions.userAgent": "string",
|
||||
"browser.contextOptions.viewport": "size",
|
||||
// top-level
|
||||
"extension": "boolean",
|
||||
"capabilities": "string[]",
|
||||
"saveSession": "boolean",
|
||||
"saveTrace": "boolean",
|
||||
"saveVideo": "size",
|
||||
"sharedBrowserContext": "boolean",
|
||||
"outputDir": "string",
|
||||
"imageResponses": "string",
|
||||
"allowUnrestrictedFileAccess": "boolean",
|
||||
"codegen": "string",
|
||||
"testIdAttribute": "string",
|
||||
// server
|
||||
"server.port": "number",
|
||||
"server.host": "string",
|
||||
"server.allowedHosts": "string[]",
|
||||
// console
|
||||
"console.level": "string",
|
||||
// network
|
||||
"network.allowedOrigins": "string[]",
|
||||
"network.blockedOrigins": "string[]",
|
||||
// timeouts
|
||||
"timeouts.action": "number",
|
||||
"timeouts.navigation": "number",
|
||||
// snapshot
|
||||
"snapshot.mode": "string"
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
configFromIniFile,
|
||||
configsFromIniFile
|
||||
});
|
||||
55
node_modules/playwright-core/lib/tools/mcp/extensionContextFactory.js
generated
vendored
Normal file
55
node_modules/playwright-core/lib/tools/mcp/extensionContextFactory.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
"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 extensionContextFactory_exports = {};
|
||||
__export(extensionContextFactory_exports, {
|
||||
createExtensionBrowser: () => createExtensionBrowser
|
||||
});
|
||||
module.exports = __toCommonJS(extensionContextFactory_exports);
|
||||
var playwright = __toESM(require("../../.."));
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
var import_network = require("../../server/utils/network");
|
||||
var import_cdpRelay = require("./cdpRelay");
|
||||
const debugLogger = (0, import_utilsBundle.debug)("pw:mcp:relay");
|
||||
async function createExtensionBrowser(config, clientInfo) {
|
||||
const httpServer = (0, import_network.createHttpServer)();
|
||||
await (0, import_network.startHttpServer)(httpServer, {});
|
||||
const relay = new import_cdpRelay.CDPRelayServer(
|
||||
httpServer,
|
||||
config.browser.launchOptions.channel || "chrome",
|
||||
config.browser.userDataDir,
|
||||
config.browser.launchOptions.executablePath
|
||||
);
|
||||
debugLogger(`CDP relay server started, extension endpoint: ${relay.extensionEndpoint()}.`);
|
||||
await relay.ensureExtensionConnectionForMCPContext(clientInfo);
|
||||
return await playwright.chromium.connectOverCDP(relay.cdpEndpoint(), { isLocal: true });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createExtensionBrowser
|
||||
});
|
||||
62
node_modules/playwright-core/lib/tools/mcp/index.js
generated
vendored
Normal file
62
node_modules/playwright-core/lib/tools/mcp/index.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"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 mcp_exports = {};
|
||||
__export(mcp_exports, {
|
||||
createConnection: () => createConnection
|
||||
});
|
||||
module.exports = __toCommonJS(mcp_exports);
|
||||
var import_config = require("./config");
|
||||
var import_tools = require("../backend/tools");
|
||||
var import_browserFactory = require("./browserFactory");
|
||||
var import_browserBackend = require("../backend/browserBackend");
|
||||
var import_server = require("../utils/mcp/server");
|
||||
const packageJSON = require("../../../package.json");
|
||||
async function createConnection(userConfig = {}, contextGetter) {
|
||||
const config = await (0, import_config.resolveConfig)(userConfig);
|
||||
const tools = (0, import_tools.filteredTools)(config);
|
||||
const backendFactory = {
|
||||
name: "api",
|
||||
nameInConfig: "api",
|
||||
version: packageJSON.version,
|
||||
toolSchemas: tools.map((tool) => tool.schema),
|
||||
create: async (clientInfo) => {
|
||||
const browser = contextGetter ? new SimpleBrowser(await contextGetter()) : await (0, import_browserFactory.createBrowser)(config, clientInfo);
|
||||
const context = config.browser.isolated ? await browser.newContext(config.browser.contextOptions) : browser.contexts()[0];
|
||||
return new import_browserBackend.BrowserBackend(config, context, tools);
|
||||
},
|
||||
disposed: async () => {
|
||||
}
|
||||
};
|
||||
return (0, import_server.createServer)("api", packageJSON.version, backendFactory, false);
|
||||
}
|
||||
class SimpleBrowser {
|
||||
constructor(context) {
|
||||
this._context = context;
|
||||
}
|
||||
contexts() {
|
||||
return [this._context];
|
||||
}
|
||||
async newContext() {
|
||||
throw new Error("Creating a new context is not supported in SimpleBrowserContextFactory.");
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createConnection
|
||||
});
|
||||
35
node_modules/playwright-core/lib/tools/mcp/log.js
generated
vendored
Normal file
35
node_modules/playwright-core/lib/tools/mcp/log.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
"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 log_exports = {};
|
||||
__export(log_exports, {
|
||||
logUnhandledError: () => logUnhandledError,
|
||||
testDebug: () => testDebug
|
||||
});
|
||||
module.exports = __toCommonJS(log_exports);
|
||||
var import_utilsBundle = require("../../utilsBundle");
|
||||
const errorDebug = (0, import_utilsBundle.debug)("pw:mcp:error");
|
||||
function logUnhandledError(error) {
|
||||
errorDebug(error);
|
||||
}
|
||||
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
logUnhandledError,
|
||||
testDebug
|
||||
});
|
||||
107
node_modules/playwright-core/lib/tools/mcp/program.js
generated
vendored
Normal file
107
node_modules/playwright-core/lib/tools/mcp/program.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
28
node_modules/playwright-core/lib/tools/mcp/protocol.js
generated
vendored
Normal file
28
node_modules/playwright-core/lib/tools/mcp/protocol.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
"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 protocol_exports = {};
|
||||
__export(protocol_exports, {
|
||||
VERSION: () => VERSION
|
||||
});
|
||||
module.exports = __toCommonJS(protocol_exports);
|
||||
const VERSION = 1;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
VERSION
|
||||
});
|
||||
44
node_modules/playwright-core/lib/tools/mcp/watchdog.js
generated
vendored
Normal file
44
node_modules/playwright-core/lib/tools/mcp/watchdog.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 watchdog_exports = {};
|
||||
__export(watchdog_exports, {
|
||||
setupExitWatchdog: () => setupExitWatchdog
|
||||
});
|
||||
module.exports = __toCommonJS(watchdog_exports);
|
||||
var import_utils = require("../../utils");
|
||||
var import_log = require("./log");
|
||||
function setupExitWatchdog() {
|
||||
let isExiting = false;
|
||||
const handleExit = async (signal) => {
|
||||
if (isExiting)
|
||||
return;
|
||||
isExiting = true;
|
||||
setTimeout(() => process.exit(0), 15e3);
|
||||
(0, import_log.testDebug)("gracefully closing " + import_utils.gracefullyCloseSet.size);
|
||||
await (0, import_utils.gracefullyCloseAll)();
|
||||
process.exit(0);
|
||||
};
|
||||
process.stdin.on("close", () => handleExit("close"));
|
||||
process.on("SIGINT", () => handleExit("SIGINT"));
|
||||
process.on("SIGTERM", () => handleExit("SIGTERM"));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
setupExitWatchdog
|
||||
});
|
||||
Reference in New Issue
Block a user