mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-19 16:50:12 +01:00
Add form submission debugging to login page
This commit is contained in:
parent
90234ee58b
commit
29fd18839f
517 changed files with 154163 additions and 1 deletions
16
node_modules/playwright/lib/mcp/browser/actions.d.js
generated
vendored
Normal file
16
node_modules/playwright/lib/mcp/browser/actions.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 actions_d_exports = {};
|
||||
module.exports = __toCommonJS(actions_d_exports);
|
||||
296
node_modules/playwright/lib/mcp/browser/browserContextFactory.js
generated
vendored
Normal file
296
node_modules/playwright/lib/mcp/browser/browserContextFactory.js
generated
vendored
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
"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 browserContextFactory_exports = {};
|
||||
__export(browserContextFactory_exports, {
|
||||
SharedContextFactory: () => SharedContextFactory,
|
||||
contextFactory: () => contextFactory
|
||||
});
|
||||
module.exports = __toCommonJS(browserContextFactory_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("playwright-core"));
|
||||
var import_registry = require("playwright-core/lib/server/registry/index");
|
||||
var import_server = require("playwright-core/lib/server");
|
||||
var import_log = require("../log");
|
||||
var import_config = require("./config");
|
||||
var import_server2 = require("../sdk/server");
|
||||
function contextFactory(config) {
|
||||
if (config.sharedBrowserContext)
|
||||
return SharedContextFactory.create(config);
|
||||
if (config.browser.remoteEndpoint)
|
||||
return new RemoteContextFactory(config);
|
||||
if (config.browser.cdpEndpoint)
|
||||
return new CdpContextFactory(config);
|
||||
if (config.browser.isolated)
|
||||
return new IsolatedContextFactory(config);
|
||||
return new PersistentContextFactory(config);
|
||||
}
|
||||
class BaseContextFactory {
|
||||
constructor(name, config) {
|
||||
this._logName = name;
|
||||
this.config = config;
|
||||
}
|
||||
async _obtainBrowser(clientInfo) {
|
||||
if (this._browserPromise)
|
||||
return this._browserPromise;
|
||||
(0, import_log.testDebug)(`obtain browser (${this._logName})`);
|
||||
this._browserPromise = this._doObtainBrowser(clientInfo);
|
||||
void this._browserPromise.then((browser) => {
|
||||
browser.on("disconnected", () => {
|
||||
this._browserPromise = void 0;
|
||||
});
|
||||
}).catch(() => {
|
||||
this._browserPromise = void 0;
|
||||
});
|
||||
return this._browserPromise;
|
||||
}
|
||||
async _doObtainBrowser(clientInfo) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async createContext(clientInfo) {
|
||||
(0, import_log.testDebug)(`create browser context (${this._logName})`);
|
||||
const browser = await this._obtainBrowser(clientInfo);
|
||||
const browserContext = await this._doCreateContext(browser);
|
||||
await addInitScript(browserContext, this.config.browser.initScript);
|
||||
return {
|
||||
browserContext,
|
||||
close: (afterClose) => this._closeBrowserContext(browserContext, browser, afterClose)
|
||||
};
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async _closeBrowserContext(browserContext, browser, afterClose) {
|
||||
(0, import_log.testDebug)(`close browser context (${this._logName})`);
|
||||
if (browser.contexts().length === 1)
|
||||
this._browserPromise = void 0;
|
||||
await browserContext.close().catch(import_log.logUnhandledError);
|
||||
await afterClose();
|
||||
if (browser.contexts().length === 0) {
|
||||
(0, import_log.testDebug)(`close browser (${this._logName})`);
|
||||
await browser.close().catch(import_log.logUnhandledError);
|
||||
}
|
||||
}
|
||||
}
|
||||
class IsolatedContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("isolated", config);
|
||||
}
|
||||
async _doObtainBrowser(clientInfo) {
|
||||
await injectCdpPort(this.config.browser);
|
||||
const browserType = playwright[this.config.browser.browserName];
|
||||
const tracesDir = await computeTracesDir(this.config, clientInfo);
|
||||
if (tracesDir && this.config.saveTrace)
|
||||
await startTraceServer(this.config, tracesDir);
|
||||
return browserType.launch({
|
||||
tracesDir,
|
||||
...this.config.browser.launchOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false
|
||||
}).catch((error) => {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return browser.newContext(this.config.browser.contextOptions);
|
||||
}
|
||||
}
|
||||
class CdpContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("cdp", config);
|
||||
}
|
||||
async _doObtainBrowser() {
|
||||
return playwright.chromium.connectOverCDP(this.config.browser.cdpEndpoint, { headers: this.config.browser.cdpHeaders });
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return this.config.browser.isolated ? await browser.newContext() : browser.contexts()[0];
|
||||
}
|
||||
}
|
||||
class RemoteContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("remote", config);
|
||||
}
|
||||
async _doObtainBrowser() {
|
||||
const url = new URL(this.config.browser.remoteEndpoint);
|
||||
url.searchParams.set("browser", this.config.browser.browserName);
|
||||
if (this.config.browser.launchOptions)
|
||||
url.searchParams.set("launch-options", JSON.stringify(this.config.browser.launchOptions));
|
||||
return playwright[this.config.browser.browserName].connect(String(url));
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return browser.newContext();
|
||||
}
|
||||
}
|
||||
class PersistentContextFactory {
|
||||
constructor(config) {
|
||||
this.name = "persistent";
|
||||
this.description = "Create a new persistent browser context";
|
||||
this._userDataDirs = /* @__PURE__ */ new Set();
|
||||
this.config = config;
|
||||
}
|
||||
async createContext(clientInfo) {
|
||||
await injectCdpPort(this.config.browser);
|
||||
(0, import_log.testDebug)("create browser context (persistent)");
|
||||
const userDataDir = this.config.browser.userDataDir ?? await this._createUserDataDir(clientInfo);
|
||||
const tracesDir = await computeTracesDir(this.config, clientInfo);
|
||||
if (tracesDir && this.config.saveTrace)
|
||||
await startTraceServer(this.config, tracesDir);
|
||||
this._userDataDirs.add(userDataDir);
|
||||
(0, import_log.testDebug)("lock user data dir", userDataDir);
|
||||
const browserType = playwright[this.config.browser.browserName];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const launchOptions = {
|
||||
tracesDir,
|
||||
...this.config.browser.launchOptions,
|
||||
...this.config.browser.contextOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false,
|
||||
ignoreDefaultArgs: [
|
||||
"--disable-extensions"
|
||||
],
|
||||
assistantMode: true
|
||||
};
|
||||
try {
|
||||
const browserContext = await browserType.launchPersistentContext(userDataDir, launchOptions);
|
||||
await addInitScript(browserContext, this.config.browser.initScript);
|
||||
const close = (afterClose) => this._closeBrowserContext(browserContext, userDataDir, afterClose);
|
||||
return { browserContext, close };
|
||||
} catch (error) {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
|
||||
if (error.message.includes("ProcessSingleton") || error.message.includes("Invalid URL")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
|
||||
}
|
||||
async _closeBrowserContext(browserContext, userDataDir, afterClose) {
|
||||
(0, import_log.testDebug)("close browser context (persistent)");
|
||||
(0, import_log.testDebug)("release user data dir", userDataDir);
|
||||
await browserContext.close().catch(() => {
|
||||
});
|
||||
await afterClose();
|
||||
this._userDataDirs.delete(userDataDir);
|
||||
(0, import_log.testDebug)("close browser context complete (persistent)");
|
||||
}
|
||||
async _createUserDataDir(clientInfo) {
|
||||
const dir = process.env.PWMCP_PROFILES_DIR_FOR_TEST ?? import_registry.registryDirectory;
|
||||
const browserToken = this.config.browser.launchOptions?.channel ?? this.config.browser?.browserName;
|
||||
const rootPath = (0, import_server2.firstRootPath)(clientInfo);
|
||||
const rootPathToken = rootPath ? `-${createHash(rootPath)}` : "";
|
||||
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, () => {
|
||||
const { port } = server.address();
|
||||
server.close(() => resolve(port));
|
||||
});
|
||||
server.on("error", reject);
|
||||
});
|
||||
}
|
||||
async function startTraceServer(config, tracesDir) {
|
||||
if (!config.saveTrace)
|
||||
return;
|
||||
const server = await (0, import_server.startTraceViewerServer)();
|
||||
const urlPrefix = server.urlPrefix("human-readable");
|
||||
const url = urlPrefix + "/trace/index.html?trace=" + tracesDir + "/trace.json";
|
||||
console.error("\nTrace viewer listening on " + url);
|
||||
}
|
||||
function createHash(data) {
|
||||
return import_crypto.default.createHash("sha256").update(data).digest("hex").slice(0, 7);
|
||||
}
|
||||
async function addInitScript(browserContext, initScript) {
|
||||
for (const scriptPath of initScript ?? [])
|
||||
await browserContext.addInitScript({ path: import_path.default.resolve(scriptPath) });
|
||||
}
|
||||
class SharedContextFactory {
|
||||
static create(config) {
|
||||
if (SharedContextFactory._instance)
|
||||
throw new Error("SharedContextFactory already exists");
|
||||
const baseConfig = { ...config, sharedBrowserContext: false };
|
||||
const baseFactory = contextFactory(baseConfig);
|
||||
SharedContextFactory._instance = new SharedContextFactory(baseFactory);
|
||||
return SharedContextFactory._instance;
|
||||
}
|
||||
constructor(baseFactory) {
|
||||
this._baseFactory = baseFactory;
|
||||
}
|
||||
async createContext(clientInfo, abortSignal, toolName) {
|
||||
if (!this._contextPromise) {
|
||||
(0, import_log.testDebug)("create shared browser context");
|
||||
this._contextPromise = this._baseFactory.createContext(clientInfo, abortSignal, toolName);
|
||||
}
|
||||
const { browserContext } = await this._contextPromise;
|
||||
(0, import_log.testDebug)(`shared context client connected`);
|
||||
return {
|
||||
browserContext,
|
||||
close: async () => {
|
||||
(0, import_log.testDebug)(`shared context client disconnected`);
|
||||
}
|
||||
};
|
||||
}
|
||||
static async dispose() {
|
||||
await SharedContextFactory._instance?._dispose();
|
||||
}
|
||||
async _dispose() {
|
||||
const contextPromise = this._contextPromise;
|
||||
this._contextPromise = void 0;
|
||||
if (!contextPromise)
|
||||
return;
|
||||
const { close } = await contextPromise;
|
||||
await close(async () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
async function computeTracesDir(config, clientInfo) {
|
||||
if (!config.saveTrace && !config.capabilities?.includes("tracing"))
|
||||
return;
|
||||
return await (0, import_config.outputFile)(config, clientInfo, `traces`, { origin: "code", reason: "Collecting trace" });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SharedContextFactory,
|
||||
contextFactory
|
||||
});
|
||||
76
node_modules/playwright/lib/mcp/browser/browserServerBackend.js
generated
vendored
Normal file
76
node_modules/playwright/lib/mcp/browser/browserServerBackend.js
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"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 browserServerBackend_exports = {};
|
||||
__export(browserServerBackend_exports, {
|
||||
BrowserServerBackend: () => BrowserServerBackend
|
||||
});
|
||||
module.exports = __toCommonJS(browserServerBackend_exports);
|
||||
var import_context = require("./context");
|
||||
var import_log = require("../log");
|
||||
var import_response = require("./response");
|
||||
var import_sessionLog = require("./sessionLog");
|
||||
var import_tools = require("./tools");
|
||||
var import_tool = require("../sdk/tool");
|
||||
class BrowserServerBackend {
|
||||
constructor(config, factory) {
|
||||
this._config = config;
|
||||
this._browserContextFactory = factory;
|
||||
this._tools = (0, import_tools.filteredTools)(config);
|
||||
}
|
||||
async initialize(server, clientInfo) {
|
||||
this._sessionLog = this._config.saveSession ? await import_sessionLog.SessionLog.create(this._config, clientInfo) : void 0;
|
||||
this._context = new import_context.Context({
|
||||
config: this._config,
|
||||
browserContextFactory: this._browserContextFactory,
|
||||
sessionLog: this._sessionLog,
|
||||
clientInfo
|
||||
});
|
||||
}
|
||||
async listTools() {
|
||||
return this._tools.map((tool) => (0, import_tool.toMcpTool)(tool.schema));
|
||||
}
|
||||
async callTool(name, rawArguments) {
|
||||
const tool = this._tools.find((tool2) => tool2.schema.name === name);
|
||||
if (!tool)
|
||||
throw new Error(`Tool "${name}" not found`);
|
||||
const parsedArguments = tool.schema.inputSchema.parse(rawArguments || {});
|
||||
const context = this._context;
|
||||
const response = new import_response.Response(context, name, parsedArguments);
|
||||
response.logBegin();
|
||||
context.setRunningTool(name);
|
||||
try {
|
||||
await tool.handle(context, parsedArguments, response);
|
||||
await response.finish();
|
||||
this._sessionLog?.logResponse(response);
|
||||
} catch (error) {
|
||||
response.addError(String(error));
|
||||
} finally {
|
||||
context.setRunningTool(void 0);
|
||||
}
|
||||
response.logEnd();
|
||||
return response.serialize();
|
||||
}
|
||||
serverClosed() {
|
||||
void this._context?.dispose().catch(import_log.logUnhandledError);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserServerBackend
|
||||
});
|
||||
66
node_modules/playwright/lib/mcp/browser/codegen.js
generated
vendored
Normal file
66
node_modules/playwright/lib/mcp/browser/codegen.js
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"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 codegen_exports = {};
|
||||
__export(codegen_exports, {
|
||||
escapeWithQuotes: () => escapeWithQuotes,
|
||||
formatObject: () => formatObject,
|
||||
quote: () => quote
|
||||
});
|
||||
module.exports = __toCommonJS(codegen_exports);
|
||||
function escapeWithQuotes(text, char = "'") {
|
||||
const stringified = JSON.stringify(text);
|
||||
const escapedText = stringified.substring(1, stringified.length - 1).replace(/\\"/g, '"');
|
||||
if (char === "'")
|
||||
return char + escapedText.replace(/[']/g, "\\'") + char;
|
||||
if (char === '"')
|
||||
return char + escapedText.replace(/["]/g, '\\"') + char;
|
||||
if (char === "`")
|
||||
return char + escapedText.replace(/[`]/g, "\\`") + char;
|
||||
throw new Error("Invalid escape char");
|
||||
}
|
||||
function quote(text) {
|
||||
return escapeWithQuotes(text, "'");
|
||||
}
|
||||
function formatObject(value, indent = " ", mode = "multiline") {
|
||||
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])}`);
|
||||
if (mode === "multiline")
|
||||
return `{
|
||||
${tokens.join(`,
|
||||
${indent}`)}
|
||||
}`;
|
||||
return `{ ${tokens.join(", ")} }`;
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
escapeWithQuotes,
|
||||
formatObject,
|
||||
quote
|
||||
});
|
||||
383
node_modules/playwright/lib/mcp/browser/config.js
generated
vendored
Normal file
383
node_modules/playwright/lib/mcp/browser/config.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 config_exports = {};
|
||||
__export(config_exports, {
|
||||
commaSeparatedList: () => commaSeparatedList,
|
||||
configFromCLIOptions: () => configFromCLIOptions,
|
||||
defaultConfig: () => defaultConfig,
|
||||
dotenvFileLoader: () => dotenvFileLoader,
|
||||
headerParser: () => headerParser,
|
||||
numberParser: () => numberParser,
|
||||
outputDir: () => outputDir,
|
||||
outputFile: () => outputFile,
|
||||
resolutionParser: () => resolutionParser,
|
||||
resolveCLIConfig: () => resolveCLIConfig,
|
||||
resolveConfig: () => resolveConfig,
|
||||
semicolonSeparatedList: () => semicolonSeparatedList
|
||||
});
|
||||
module.exports = __toCommonJS(config_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_playwright_core = require("playwright-core");
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_util = require("../../util");
|
||||
var import_server = require("../sdk/server");
|
||||
const defaultConfig = {
|
||||
browser: {
|
||||
browserName: "chromium",
|
||||
launchOptions: {
|
||||
channel: "chrome",
|
||||
headless: import_os.default.platform() === "linux" && !process.env.DISPLAY,
|
||||
chromiumSandbox: true
|
||||
},
|
||||
contextOptions: {
|
||||
viewport: null
|
||||
}
|
||||
},
|
||||
network: {
|
||||
allowedOrigins: void 0,
|
||||
blockedOrigins: void 0
|
||||
},
|
||||
server: {},
|
||||
saveTrace: false,
|
||||
timeouts: {
|
||||
action: 5e3,
|
||||
navigation: 6e4
|
||||
}
|
||||
};
|
||||
async function resolveConfig(config) {
|
||||
return mergeConfig(defaultConfig, config);
|
||||
}
|
||||
async function resolveCLIConfig(cliOptions) {
|
||||
const configInFile = await loadConfig(cliOptions.config);
|
||||
const envOverrides = configFromEnv();
|
||||
const cliOverrides = configFromCLIOptions(cliOptions);
|
||||
let result = defaultConfig;
|
||||
result = mergeConfig(result, configInFile);
|
||||
result = mergeConfig(result, envOverrides);
|
||||
result = mergeConfig(result, cliOverrides);
|
||||
await validateConfig(result);
|
||||
return result;
|
||||
}
|
||||
async function validateConfig(config) {
|
||||
if (config.browser.initScript) {
|
||||
for (const script of config.browser.initScript) {
|
||||
if (!await (0, import_util.fileExistsAsync)(script))
|
||||
throw new Error(`Init script file does not exist: ${script}`);
|
||||
}
|
||||
}
|
||||
if (config.sharedBrowserContext && config.saveVideo)
|
||||
throw new Error("saveVideo is not supported when sharedBrowserContext is true");
|
||||
}
|
||||
function configFromCLIOptions(cliOptions) {
|
||||
let browserName;
|
||||
let channel;
|
||||
switch (cliOptions.browser) {
|
||||
case "chrome":
|
||||
case "chrome-beta":
|
||||
case "chrome-canary":
|
||||
case "chrome-dev":
|
||||
case "chromium":
|
||||
case "msedge":
|
||||
case "msedge-beta":
|
||||
case "msedge-canary":
|
||||
case "msedge-dev":
|
||||
browserName = "chromium";
|
||||
channel = cliOptions.browser;
|
||||
break;
|
||||
case "firefox":
|
||||
browserName = "firefox";
|
||||
break;
|
||||
case "webkit":
|
||||
browserName = "webkit";
|
||||
break;
|
||||
}
|
||||
const launchOptions = {
|
||||
channel,
|
||||
executablePath: cliOptions.executablePath,
|
||||
headless: cliOptions.headless
|
||||
};
|
||||
if (cliOptions.sandbox === false)
|
||||
launchOptions.chromiumSandbox = false;
|
||||
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_playwright_core.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;
|
||||
if (cliOptions.saveVideo) {
|
||||
contextOptions.recordVideo = {
|
||||
// Videos are moved to output directory on saveAs.
|
||||
dir: tmpDir(),
|
||||
size: cliOptions.saveVideo
|
||||
};
|
||||
}
|
||||
const result = {
|
||||
browser: {
|
||||
browserName,
|
||||
isolated: cliOptions.isolated,
|
||||
userDataDir: cliOptions.userDataDir,
|
||||
launchOptions,
|
||||
contextOptions,
|
||||
cdpEndpoint: cliOptions.cdpEndpoint,
|
||||
cdpHeaders: cliOptions.cdpHeader,
|
||||
initScript: cliOptions.initScript
|
||||
},
|
||||
server: {
|
||||
port: cliOptions.port,
|
||||
host: cliOptions.host,
|
||||
allowedHosts: cliOptions.allowedHosts
|
||||
},
|
||||
capabilities: cliOptions.caps,
|
||||
network: {
|
||||
allowedOrigins: cliOptions.allowedOrigins,
|
||||
blockedOrigins: cliOptions.blockedOrigins
|
||||
},
|
||||
saveSession: cliOptions.saveSession,
|
||||
saveTrace: cliOptions.saveTrace,
|
||||
saveVideo: cliOptions.saveVideo,
|
||||
secrets: cliOptions.secrets,
|
||||
sharedBrowserContext: cliOptions.sharedBrowserContext,
|
||||
outputDir: cliOptions.outputDir,
|
||||
imageResponses: cliOptions.imageResponses,
|
||||
timeouts: {
|
||||
action: cliOptions.timeoutAction,
|
||||
navigation: cliOptions.timeoutNavigation
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function configFromEnv() {
|
||||
const options = {};
|
||||
options.allowedHosts = commaSeparatedList(process.env.PLAYWRIGHT_MCP_ALLOWED_HOSTNAMES);
|
||||
options.allowedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_ALLOWED_ORIGINS);
|
||||
options.blockedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_BLOCKED_ORIGINS);
|
||||
options.blockServiceWorkers = envToBoolean(process.env.PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS);
|
||||
options.browser = envToString(process.env.PLAYWRIGHT_MCP_BROWSER);
|
||||
options.caps = commaSeparatedList(process.env.PLAYWRIGHT_MCP_CAPS);
|
||||
options.cdpEndpoint = envToString(process.env.PLAYWRIGHT_MCP_CDP_ENDPOINT);
|
||||
options.cdpHeader = headerParser(process.env.PLAYWRIGHT_MCP_CDP_HEADERS, {});
|
||||
options.config = envToString(process.env.PLAYWRIGHT_MCP_CONFIG);
|
||||
options.device = envToString(process.env.PLAYWRIGHT_MCP_DEVICE);
|
||||
options.executablePath = envToString(process.env.PLAYWRIGHT_MCP_EXECUTABLE_PATH);
|
||||
options.grantPermissions = commaSeparatedList(process.env.PLAYWRIGHT_MCP_GRANT_PERMISSIONS);
|
||||
options.headless = envToBoolean(process.env.PLAYWRIGHT_MCP_HEADLESS);
|
||||
options.host = envToString(process.env.PLAYWRIGHT_MCP_HOST);
|
||||
options.ignoreHttpsErrors = envToBoolean(process.env.PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS);
|
||||
const initScript = envToString(process.env.PLAYWRIGHT_MCP_INIT_SCRIPT);
|
||||
if (initScript)
|
||||
options.initScript = [initScript];
|
||||
options.isolated = envToBoolean(process.env.PLAYWRIGHT_MCP_ISOLATED);
|
||||
if (process.env.PLAYWRIGHT_MCP_IMAGE_RESPONSES === "omit")
|
||||
options.imageResponses = "omit";
|
||||
options.sandbox = envToBoolean(process.env.PLAYWRIGHT_MCP_SANDBOX);
|
||||
options.outputDir = envToString(process.env.PLAYWRIGHT_MCP_OUTPUT_DIR);
|
||||
options.port = numberParser(process.env.PLAYWRIGHT_MCP_PORT);
|
||||
options.proxyBypass = envToString(process.env.PLAYWRIGHT_MCP_PROXY_BYPASS);
|
||||
options.proxyServer = envToString(process.env.PLAYWRIGHT_MCP_PROXY_SERVER);
|
||||
options.saveTrace = envToBoolean(process.env.PLAYWRIGHT_MCP_SAVE_TRACE);
|
||||
options.saveVideo = resolutionParser("--save-video", process.env.PLAYWRIGHT_MCP_SAVE_VIDEO);
|
||||
options.secrets = dotenvFileLoader(process.env.PLAYWRIGHT_MCP_SECRETS_FILE);
|
||||
options.storageState = envToString(process.env.PLAYWRIGHT_MCP_STORAGE_STATE);
|
||||
options.timeoutAction = numberParser(process.env.PLAYWRIGHT_MCP_TIMEOUT_ACTION);
|
||||
options.timeoutNavigation = numberParser(process.env.PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION);
|
||||
options.userAgent = envToString(process.env.PLAYWRIGHT_MCP_USER_AGENT);
|
||||
options.userDataDir = envToString(process.env.PLAYWRIGHT_MCP_USER_DATA_DIR);
|
||||
options.viewportSize = resolutionParser("--viewport-size", process.env.PLAYWRIGHT_MCP_VIEWPORT_SIZE);
|
||||
return configFromCLIOptions(options);
|
||||
}
|
||||
async function loadConfig(configFile) {
|
||||
if (!configFile)
|
||||
return {};
|
||||
try {
|
||||
return JSON.parse(await import_fs.default.promises.readFile(configFile, "utf8"));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to load config file: ${configFile}, ${error}`);
|
||||
}
|
||||
}
|
||||
function tmpDir() {
|
||||
return import_path.default.join(process.env.PW_TMPDIR_FOR_TEST ?? import_os.default.tmpdir(), "playwright-mcp-output");
|
||||
}
|
||||
function outputDir(config, clientInfo) {
|
||||
const rootPath = (0, import_server.firstRootPath)(clientInfo);
|
||||
return config.outputDir ?? (rootPath ? import_path.default.join(rootPath, ".playwright-mcp") : void 0) ?? import_path.default.join(tmpDir(), String(clientInfo.timestamp));
|
||||
}
|
||||
async function outputFile(config, clientInfo, fileName, options) {
|
||||
const file = await resolveFile(config, clientInfo, fileName, options);
|
||||
(0, import_utilsBundle.debug)("pw:mcp:file")(options.reason, file);
|
||||
return file;
|
||||
}
|
||||
async function resolveFile(config, clientInfo, fileName, options) {
|
||||
const dir = outputDir(config, clientInfo);
|
||||
if (options.origin === "code")
|
||||
return import_path.default.resolve(dir, fileName);
|
||||
if (options.origin === "llm") {
|
||||
fileName = fileName.split("\\").join("/");
|
||||
const resolvedFile = import_path.default.resolve(dir, fileName);
|
||||
if (!resolvedFile.startsWith(import_path.default.resolve(dir) + import_path.default.sep))
|
||||
throw new Error(`Resolved file path for ${fileName} is outside of the output directory`);
|
||||
return resolvedFile;
|
||||
}
|
||||
return import_path.default.join(dir, sanitizeForFilePath(fileName));
|
||||
}
|
||||
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 ?? "chromium",
|
||||
isolated: overrides.browser?.isolated ?? base.browser?.isolated ?? false,
|
||||
launchOptions: {
|
||||
...pickDefined(base.browser?.launchOptions),
|
||||
...pickDefined(overrides.browser?.launchOptions),
|
||||
...{ 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,
|
||||
network: {
|
||||
...pickDefined(base.network),
|
||||
...pickDefined(overrides.network)
|
||||
},
|
||||
server: {
|
||||
...pickDefined(base.server),
|
||||
...pickDefined(overrides.server)
|
||||
},
|
||||
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 [name, value] = arg.split(":").map((v) => v.trim());
|
||||
result[name] = value;
|
||||
return result;
|
||||
}
|
||||
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;
|
||||
}
|
||||
function sanitizeForFilePath(s) {
|
||||
const sanitize = (s2) => s2.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, "-");
|
||||
const separator = s.lastIndexOf(".");
|
||||
if (separator === -1)
|
||||
return sanitize(s);
|
||||
return sanitize(s.substring(0, separator)) + "." + sanitize(s.substring(separator + 1));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
commaSeparatedList,
|
||||
configFromCLIOptions,
|
||||
defaultConfig,
|
||||
dotenvFileLoader,
|
||||
headerParser,
|
||||
numberParser,
|
||||
outputDir,
|
||||
outputFile,
|
||||
resolutionParser,
|
||||
resolveCLIConfig,
|
||||
resolveConfig,
|
||||
semicolonSeparatedList
|
||||
});
|
||||
284
node_modules/playwright/lib/mcp/browser/context.js
generated
vendored
Normal file
284
node_modules/playwright/lib/mcp/browser/context.js
generated
vendored
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
"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 context_exports = {};
|
||||
__export(context_exports, {
|
||||
Context: () => Context,
|
||||
InputRecorder: () => InputRecorder
|
||||
});
|
||||
module.exports = __toCommonJS(context_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_log = require("../log");
|
||||
var import_tab = require("./tab");
|
||||
var import_config = require("./config");
|
||||
var codegen = __toESM(require("./codegen"));
|
||||
var import_utils = require("./tools/utils");
|
||||
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
||||
class Context {
|
||||
constructor(options) {
|
||||
this._tabs = [];
|
||||
this._abortController = new AbortController();
|
||||
this.config = options.config;
|
||||
this.sessionLog = options.sessionLog;
|
||||
this.options = options;
|
||||
this._browserContextFactory = options.browserContextFactory;
|
||||
this._clientInfo = options.clientInfo;
|
||||
testDebug("create context");
|
||||
Context._allContexts.add(this);
|
||||
}
|
||||
static {
|
||||
this._allContexts = /* @__PURE__ */ new Set();
|
||||
}
|
||||
static async disposeAll() {
|
||||
await Promise.all([...Context._allContexts].map((context) => context.dispose()));
|
||||
}
|
||||
tabs() {
|
||||
return this._tabs;
|
||||
}
|
||||
currentTab() {
|
||||
return this._currentTab;
|
||||
}
|
||||
currentTabOrDie() {
|
||||
if (!this._currentTab)
|
||||
throw new Error('No open pages available. Use the "browser_navigate" tool to navigate to a page first.');
|
||||
return this._currentTab;
|
||||
}
|
||||
async newTab() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
const page = await browserContext.newPage();
|
||||
this._currentTab = this._tabs.find((t) => t.page === page);
|
||||
return this._currentTab;
|
||||
}
|
||||
async selectTab(index) {
|
||||
const tab = this._tabs[index];
|
||||
if (!tab)
|
||||
throw new Error(`Tab ${index} not found`);
|
||||
await tab.page.bringToFront();
|
||||
this._currentTab = tab;
|
||||
return tab;
|
||||
}
|
||||
async ensureTab() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
if (!this._currentTab)
|
||||
await browserContext.newPage();
|
||||
return this._currentTab;
|
||||
}
|
||||
async closeTab(index) {
|
||||
const tab = index === void 0 ? this._currentTab : this._tabs[index];
|
||||
if (!tab)
|
||||
throw new Error(`Tab ${index} not found`);
|
||||
const url = tab.page.url();
|
||||
await tab.page.close();
|
||||
return url;
|
||||
}
|
||||
async outputFile(fileName, options) {
|
||||
return (0, import_config.outputFile)(this.config, this._clientInfo, fileName, options);
|
||||
}
|
||||
_onPageCreated(page) {
|
||||
const tab = new import_tab.Tab(this, page, (tab2) => this._onPageClosed(tab2));
|
||||
this._tabs.push(tab);
|
||||
if (!this._currentTab)
|
||||
this._currentTab = tab;
|
||||
}
|
||||
_onPageClosed(tab) {
|
||||
const index = this._tabs.indexOf(tab);
|
||||
if (index === -1)
|
||||
return;
|
||||
this._tabs.splice(index, 1);
|
||||
if (this._currentTab === tab)
|
||||
this._currentTab = this._tabs[Math.min(index, this._tabs.length - 1)];
|
||||
if (!this._tabs.length)
|
||||
void this.closeBrowserContext();
|
||||
}
|
||||
async closeBrowserContext() {
|
||||
if (!this._closeBrowserContextPromise)
|
||||
this._closeBrowserContextPromise = this._closeBrowserContextImpl().catch(import_log.logUnhandledError);
|
||||
await this._closeBrowserContextPromise;
|
||||
this._closeBrowserContextPromise = void 0;
|
||||
}
|
||||
isRunningTool() {
|
||||
return this._runningToolName !== void 0;
|
||||
}
|
||||
setRunningTool(name) {
|
||||
this._runningToolName = name;
|
||||
}
|
||||
async _closeBrowserContextImpl() {
|
||||
if (!this._browserContextPromise)
|
||||
return;
|
||||
testDebug("close context");
|
||||
const promise = this._browserContextPromise;
|
||||
this._browserContextPromise = void 0;
|
||||
await promise.then(async ({ browserContext, close }) => {
|
||||
if (this.config.saveTrace)
|
||||
await browserContext.tracing.stop();
|
||||
const videos = this.config.saveVideo ? browserContext.pages().map((page) => page.video()).filter((video) => !!video) : [];
|
||||
await close(async () => {
|
||||
for (const video of videos) {
|
||||
const name = await this.outputFile((0, import_utils.dateAsFileName)("webm"), { origin: "code", reason: "Saving video" });
|
||||
await import_fs.default.promises.mkdir(import_path.default.dirname(name), { recursive: true });
|
||||
const p = await video.path();
|
||||
if (import_fs.default.existsSync(p)) {
|
||||
try {
|
||||
await import_fs.default.promises.rename(p, name);
|
||||
} catch (e) {
|
||||
if (e.code !== "EXDEV")
|
||||
(0, import_log.logUnhandledError)(e);
|
||||
try {
|
||||
await import_fs.default.promises.copyFile(p, name);
|
||||
await import_fs.default.promises.unlink(p);
|
||||
} catch (e2) {
|
||||
(0, import_log.logUnhandledError)(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
async dispose() {
|
||||
this._abortController.abort("MCP context disposed");
|
||||
await this.closeBrowserContext();
|
||||
Context._allContexts.delete(this);
|
||||
}
|
||||
async _setupRequestInterception(context) {
|
||||
if (this.config.network?.allowedOrigins?.length) {
|
||||
await context.route("**", (route) => route.abort("blockedbyclient"));
|
||||
for (const origin of this.config.network.allowedOrigins)
|
||||
await context.route(originOrHostGlob(origin), (route) => route.continue());
|
||||
}
|
||||
if (this.config.network?.blockedOrigins?.length) {
|
||||
for (const origin of this.config.network.blockedOrigins)
|
||||
await context.route(originOrHostGlob(origin), (route) => route.abort("blockedbyclient"));
|
||||
}
|
||||
}
|
||||
async ensureBrowserContext() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
return browserContext;
|
||||
}
|
||||
_ensureBrowserContext() {
|
||||
if (!this._browserContextPromise) {
|
||||
this._browserContextPromise = this._setupBrowserContext();
|
||||
this._browserContextPromise.catch(() => {
|
||||
this._browserContextPromise = void 0;
|
||||
});
|
||||
}
|
||||
return this._browserContextPromise;
|
||||
}
|
||||
async _setupBrowserContext() {
|
||||
if (this._closeBrowserContextPromise)
|
||||
throw new Error("Another browser context is being closed.");
|
||||
const result = await this._browserContextFactory.createContext(this._clientInfo, this._abortController.signal, this._runningToolName);
|
||||
const { browserContext } = result;
|
||||
await this._setupRequestInterception(browserContext);
|
||||
if (this.sessionLog)
|
||||
await InputRecorder.create(this, browserContext);
|
||||
for (const page of browserContext.pages())
|
||||
this._onPageCreated(page);
|
||||
browserContext.on("page", (page) => this._onPageCreated(page));
|
||||
if (this.config.saveTrace) {
|
||||
await browserContext.tracing.start({
|
||||
name: "trace-" + Date.now(),
|
||||
screenshots: true,
|
||||
snapshots: true,
|
||||
_live: true
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
lookupSecret(secretName) {
|
||||
if (!this.config.secrets?.[secretName])
|
||||
return { value: secretName, code: codegen.quote(secretName) };
|
||||
return {
|
||||
value: this.config.secrets[secretName],
|
||||
code: `process.env['${secretName}']`
|
||||
};
|
||||
}
|
||||
}
|
||||
function originOrHostGlob(originOrHost) {
|
||||
try {
|
||||
const url = new URL(originOrHost);
|
||||
if (url.origin !== "null")
|
||||
return `${url.origin}/**`;
|
||||
} catch {
|
||||
}
|
||||
return `*://${originOrHost}/**`;
|
||||
}
|
||||
class InputRecorder {
|
||||
constructor(context, browserContext) {
|
||||
this._context = context;
|
||||
this._browserContext = browserContext;
|
||||
}
|
||||
static async create(context, browserContext) {
|
||||
const recorder = new InputRecorder(context, browserContext);
|
||||
await recorder._initialize();
|
||||
return recorder;
|
||||
}
|
||||
async _initialize() {
|
||||
const sessionLog = this._context.sessionLog;
|
||||
await this._browserContext._enableRecorder({
|
||||
mode: "recording",
|
||||
recorderMode: "api"
|
||||
}, {
|
||||
actionAdded: (page, data, code) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
if (tab)
|
||||
sessionLog.logUserAction(data.action, tab, code, false);
|
||||
},
|
||||
actionUpdated: (page, data, code) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
if (tab)
|
||||
sessionLog.logUserAction(data.action, tab, code, true);
|
||||
},
|
||||
signalAdded: (page, data) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
if (data.signal.name !== "navigation")
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
const navigateAction = {
|
||||
name: "navigate",
|
||||
url: data.signal.url,
|
||||
signals: []
|
||||
};
|
||||
if (tab)
|
||||
sessionLog.logUserAction(navigateAction, tab, `await page.goto('${data.signal.url}');`, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Context,
|
||||
InputRecorder
|
||||
});
|
||||
228
node_modules/playwright/lib/mcp/browser/response.js
generated
vendored
Normal file
228
node_modules/playwright/lib/mcp/browser/response.js
generated
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
"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 response_exports = {};
|
||||
__export(response_exports, {
|
||||
Response: () => Response,
|
||||
parseResponse: () => parseResponse,
|
||||
requestDebug: () => requestDebug
|
||||
});
|
||||
module.exports = __toCommonJS(response_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_tab = require("./tab");
|
||||
const requestDebug = (0, import_utilsBundle.debug)("pw:mcp:request");
|
||||
class Response {
|
||||
constructor(context, toolName, toolArgs) {
|
||||
this._result = [];
|
||||
this._code = [];
|
||||
this._images = [];
|
||||
this._includeSnapshot = false;
|
||||
this._includeTabs = false;
|
||||
this._context = context;
|
||||
this.toolName = toolName;
|
||||
this.toolArgs = toolArgs;
|
||||
}
|
||||
addResult(result) {
|
||||
this._result.push(result);
|
||||
}
|
||||
addError(error) {
|
||||
this._result.push(error);
|
||||
this._isError = true;
|
||||
}
|
||||
isError() {
|
||||
return this._isError;
|
||||
}
|
||||
result() {
|
||||
return this._result.join("\n");
|
||||
}
|
||||
addCode(code) {
|
||||
this._code.push(code);
|
||||
}
|
||||
code() {
|
||||
return this._code.join("\n");
|
||||
}
|
||||
addImage(image) {
|
||||
this._images.push(image);
|
||||
}
|
||||
images() {
|
||||
return this._images;
|
||||
}
|
||||
setIncludeSnapshot() {
|
||||
this._includeSnapshot = true;
|
||||
}
|
||||
setIncludeTabs() {
|
||||
this._includeTabs = true;
|
||||
}
|
||||
async finish() {
|
||||
if (this._includeSnapshot && this._context.currentTab())
|
||||
this._tabSnapshot = await this._context.currentTabOrDie().captureSnapshot();
|
||||
for (const tab of this._context.tabs())
|
||||
await tab.updateTitle();
|
||||
}
|
||||
tabSnapshot() {
|
||||
return this._tabSnapshot;
|
||||
}
|
||||
logBegin() {
|
||||
if (requestDebug.enabled)
|
||||
requestDebug(this.toolName, this.toolArgs);
|
||||
}
|
||||
logEnd() {
|
||||
if (requestDebug.enabled)
|
||||
requestDebug(this.serialize({ omitSnapshot: true, omitBlobs: true }));
|
||||
}
|
||||
serialize(options = {}) {
|
||||
const response = [];
|
||||
if (this._result.length) {
|
||||
response.push("### Result");
|
||||
response.push(this._result.join("\n"));
|
||||
response.push("");
|
||||
}
|
||||
if (this._code.length) {
|
||||
response.push(`### Ran Playwright code
|
||||
\`\`\`js
|
||||
${this._code.join("\n")}
|
||||
\`\`\``);
|
||||
response.push("");
|
||||
}
|
||||
if (this._includeSnapshot || this._includeTabs)
|
||||
response.push(...renderTabsMarkdown(this._context.tabs(), this._includeTabs));
|
||||
if (this._tabSnapshot?.modalStates.length) {
|
||||
response.push(...(0, import_tab.renderModalStates)(this._context, this._tabSnapshot.modalStates));
|
||||
response.push("");
|
||||
} else if (this._tabSnapshot) {
|
||||
response.push(renderTabSnapshot(this._tabSnapshot, options));
|
||||
response.push("");
|
||||
}
|
||||
const content = [
|
||||
{ type: "text", text: response.join("\n") }
|
||||
];
|
||||
if (this._context.config.imageResponses !== "omit") {
|
||||
for (const image of this._images)
|
||||
content.push({ type: "image", data: options.omitBlobs ? "<blob>" : image.data.toString("base64"), mimeType: image.contentType });
|
||||
}
|
||||
this._redactSecrets(content);
|
||||
return { content, isError: this._isError };
|
||||
}
|
||||
_redactSecrets(content) {
|
||||
if (!this._context.config.secrets)
|
||||
return;
|
||||
for (const item of content) {
|
||||
if (item.type !== "text")
|
||||
continue;
|
||||
for (const [secretName, secretValue] of Object.entries(this._context.config.secrets))
|
||||
item.text = item.text.replaceAll(secretValue, `<secret>${secretName}</secret>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
function renderTabSnapshot(tabSnapshot, options = {}) {
|
||||
const lines = [];
|
||||
if (tabSnapshot.consoleMessages.length) {
|
||||
lines.push(`### New console messages`);
|
||||
for (const message of tabSnapshot.consoleMessages)
|
||||
lines.push(`- ${trim(message.toString(), 100)}`);
|
||||
lines.push("");
|
||||
}
|
||||
if (tabSnapshot.downloads.length) {
|
||||
lines.push(`### Downloads`);
|
||||
for (const entry of tabSnapshot.downloads) {
|
||||
if (entry.finished)
|
||||
lines.push(`- Downloaded file ${entry.download.suggestedFilename()} to ${entry.outputFile}`);
|
||||
else
|
||||
lines.push(`- Downloading file ${entry.download.suggestedFilename()} ...`);
|
||||
}
|
||||
lines.push("");
|
||||
}
|
||||
lines.push(`### Page state`);
|
||||
lines.push(`- Page URL: ${tabSnapshot.url}`);
|
||||
lines.push(`- Page Title: ${tabSnapshot.title}`);
|
||||
lines.push(`- Page Snapshot:`);
|
||||
lines.push("```yaml");
|
||||
lines.push(options.omitSnapshot ? "<snapshot>" : tabSnapshot.ariaSnapshot);
|
||||
lines.push("```");
|
||||
return lines.join("\n");
|
||||
}
|
||||
function renderTabsMarkdown(tabs, force = false) {
|
||||
if (tabs.length === 1 && !force)
|
||||
return [];
|
||||
if (!tabs.length) {
|
||||
return [
|
||||
"### Open tabs",
|
||||
'No open tabs. Use the "browser_navigate" tool to navigate to a page first.',
|
||||
""
|
||||
];
|
||||
}
|
||||
const lines = ["### Open tabs"];
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
const tab = tabs[i];
|
||||
const current = tab.isCurrentTab() ? " (current)" : "";
|
||||
lines.push(`- ${i}:${current} [${tab.lastTitle()}] (${tab.page.url()})`);
|
||||
}
|
||||
lines.push("");
|
||||
return lines;
|
||||
}
|
||||
function trim(text, maxLength) {
|
||||
if (text.length <= maxLength)
|
||||
return text;
|
||||
return text.slice(0, maxLength) + "...";
|
||||
}
|
||||
function parseSections(text) {
|
||||
const sections = /* @__PURE__ */ new Map();
|
||||
const sectionHeaders = text.split(/^### /m).slice(1);
|
||||
for (const section of sectionHeaders) {
|
||||
const firstNewlineIndex = section.indexOf("\n");
|
||||
if (firstNewlineIndex === -1)
|
||||
continue;
|
||||
const sectionName = section.substring(0, firstNewlineIndex);
|
||||
const sectionContent = section.substring(firstNewlineIndex + 1).trim();
|
||||
sections.set(sectionName, sectionContent);
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
function parseResponse(response) {
|
||||
if (response.content?.[0].type !== "text")
|
||||
return void 0;
|
||||
const text = response.content[0].text;
|
||||
const sections = parseSections(text);
|
||||
const result = sections.get("Result");
|
||||
const code = sections.get("Ran Playwright code");
|
||||
const tabs = sections.get("Open tabs");
|
||||
const pageState = sections.get("Page state");
|
||||
const consoleMessages = sections.get("New console messages");
|
||||
const modalState = sections.get("Modal state");
|
||||
const downloads = sections.get("Downloads");
|
||||
const codeNoFrame = code?.replace(/^```js\n/, "").replace(/\n```$/, "");
|
||||
const isError = response.isError;
|
||||
const attachments = response.content.slice(1);
|
||||
return {
|
||||
result,
|
||||
code: codeNoFrame,
|
||||
tabs,
|
||||
pageState,
|
||||
consoleMessages,
|
||||
modalState,
|
||||
downloads,
|
||||
isError,
|
||||
attachments
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Response,
|
||||
parseResponse,
|
||||
requestDebug
|
||||
});
|
||||
160
node_modules/playwright/lib/mcp/browser/sessionLog.js
generated
vendored
Normal file
160
node_modules/playwright/lib/mcp/browser/sessionLog.js
generated
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
"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 sessionLog_exports = {};
|
||||
__export(sessionLog_exports, {
|
||||
SessionLog: () => SessionLog
|
||||
});
|
||||
module.exports = __toCommonJS(sessionLog_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_log = require("../log");
|
||||
var import_config = require("./config");
|
||||
class SessionLog {
|
||||
constructor(sessionFolder) {
|
||||
this._ordinal = 0;
|
||||
this._pendingEntries = [];
|
||||
this._sessionFileQueue = Promise.resolve();
|
||||
this._folder = sessionFolder;
|
||||
this._file = import_path.default.join(this._folder, "session.md");
|
||||
}
|
||||
static async create(config, clientInfo) {
|
||||
const sessionFolder = await (0, import_config.outputFile)(config, clientInfo, `session-${Date.now()}`, { origin: "code", reason: "Saving session" });
|
||||
await import_fs.default.promises.mkdir(sessionFolder, { recursive: true });
|
||||
console.error(`Session: ${sessionFolder}`);
|
||||
return new SessionLog(sessionFolder);
|
||||
}
|
||||
logResponse(response) {
|
||||
const entry = {
|
||||
timestamp: performance.now(),
|
||||
toolCall: {
|
||||
toolName: response.toolName,
|
||||
toolArgs: response.toolArgs,
|
||||
result: response.result(),
|
||||
isError: response.isError()
|
||||
},
|
||||
code: response.code(),
|
||||
tabSnapshot: response.tabSnapshot()
|
||||
};
|
||||
this._appendEntry(entry);
|
||||
}
|
||||
logUserAction(action, tab, code, isUpdate) {
|
||||
code = code.trim();
|
||||
if (isUpdate) {
|
||||
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
||||
if (lastEntry?.userAction?.name === action.name) {
|
||||
lastEntry.userAction = action;
|
||||
lastEntry.code = code;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (action.name === "navigate") {
|
||||
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
||||
if (lastEntry?.tabSnapshot?.url === action.url)
|
||||
return;
|
||||
}
|
||||
const entry = {
|
||||
timestamp: performance.now(),
|
||||
userAction: action,
|
||||
code,
|
||||
tabSnapshot: {
|
||||
url: tab.page.url(),
|
||||
title: "",
|
||||
ariaSnapshot: action.ariaSnapshot || "",
|
||||
modalStates: [],
|
||||
consoleMessages: [],
|
||||
downloads: []
|
||||
}
|
||||
};
|
||||
this._appendEntry(entry);
|
||||
}
|
||||
_appendEntry(entry) {
|
||||
this._pendingEntries.push(entry);
|
||||
if (this._flushEntriesTimeout)
|
||||
clearTimeout(this._flushEntriesTimeout);
|
||||
this._flushEntriesTimeout = setTimeout(() => this._flushEntries(), 1e3);
|
||||
}
|
||||
async _flushEntries() {
|
||||
clearTimeout(this._flushEntriesTimeout);
|
||||
const entries = this._pendingEntries;
|
||||
this._pendingEntries = [];
|
||||
const lines = [""];
|
||||
for (const entry of entries) {
|
||||
const ordinal = (++this._ordinal).toString().padStart(3, "0");
|
||||
if (entry.toolCall) {
|
||||
lines.push(
|
||||
`### Tool call: ${entry.toolCall.toolName}`,
|
||||
`- Args`,
|
||||
"```json",
|
||||
JSON.stringify(entry.toolCall.toolArgs, null, 2),
|
||||
"```"
|
||||
);
|
||||
if (entry.toolCall.result) {
|
||||
lines.push(
|
||||
entry.toolCall.isError ? `- Error` : `- Result`,
|
||||
"```",
|
||||
entry.toolCall.result,
|
||||
"```"
|
||||
);
|
||||
}
|
||||
}
|
||||
if (entry.userAction) {
|
||||
const actionData = { ...entry.userAction };
|
||||
delete actionData.ariaSnapshot;
|
||||
delete actionData.selector;
|
||||
delete actionData.signals;
|
||||
lines.push(
|
||||
`### User action: ${entry.userAction.name}`,
|
||||
`- Args`,
|
||||
"```json",
|
||||
JSON.stringify(actionData, null, 2),
|
||||
"```"
|
||||
);
|
||||
}
|
||||
if (entry.code) {
|
||||
lines.push(
|
||||
`- Code`,
|
||||
"```js",
|
||||
entry.code,
|
||||
"```"
|
||||
);
|
||||
}
|
||||
if (entry.tabSnapshot) {
|
||||
const fileName = `${ordinal}.snapshot.yml`;
|
||||
import_fs.default.promises.writeFile(import_path.default.join(this._folder, fileName), entry.tabSnapshot.ariaSnapshot).catch(import_log.logUnhandledError);
|
||||
lines.push(`- Snapshot: ${fileName}`);
|
||||
}
|
||||
lines.push("", "");
|
||||
}
|
||||
this._sessionFileQueue = this._sessionFileQueue.then(() => import_fs.default.promises.appendFile(this._file, lines.join("\n")));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SessionLog
|
||||
});
|
||||
277
node_modules/playwright/lib/mcp/browser/tab.js
generated
vendored
Normal file
277
node_modules/playwright/lib/mcp/browser/tab.js
generated
vendored
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
"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 tab_exports = {};
|
||||
__export(tab_exports, {
|
||||
Tab: () => Tab,
|
||||
TabEvents: () => TabEvents,
|
||||
renderModalStates: () => renderModalStates
|
||||
});
|
||||
module.exports = __toCommonJS(tab_exports);
|
||||
var import_events = require("events");
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_utils2 = require("./tools/utils");
|
||||
var import_log = require("../log");
|
||||
var import_dialogs = require("./tools/dialogs");
|
||||
var import_files = require("./tools/files");
|
||||
const TabEvents = {
|
||||
modalState: "modalState"
|
||||
};
|
||||
class Tab extends import_events.EventEmitter {
|
||||
constructor(context, page, onPageClose) {
|
||||
super();
|
||||
this._lastTitle = "about:blank";
|
||||
this._consoleMessages = [];
|
||||
this._recentConsoleMessages = [];
|
||||
this._requests = /* @__PURE__ */ new Set();
|
||||
this._modalStates = [];
|
||||
this._downloads = [];
|
||||
this.context = context;
|
||||
this.page = page;
|
||||
this._onPageClose = onPageClose;
|
||||
page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
|
||||
page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
|
||||
page.on("request", (request) => this._requests.add(request));
|
||||
page.on("close", () => this._onClose());
|
||||
page.on("filechooser", (chooser) => {
|
||||
this.setModalState({
|
||||
type: "fileChooser",
|
||||
description: "File chooser",
|
||||
fileChooser: chooser,
|
||||
clearedBy: import_files.uploadFile.schema.name
|
||||
});
|
||||
});
|
||||
page.on("dialog", (dialog) => this._dialogShown(dialog));
|
||||
page.on("download", (download) => {
|
||||
void this._downloadStarted(download);
|
||||
});
|
||||
page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
|
||||
page.setDefaultTimeout(this.context.config.timeouts.action);
|
||||
page[tabSymbol] = this;
|
||||
this._initializedPromise = this._initialize();
|
||||
}
|
||||
static forPage(page) {
|
||||
return page[tabSymbol];
|
||||
}
|
||||
static async collectConsoleMessages(page) {
|
||||
const result = [];
|
||||
const messages = await page.consoleMessages().catch(() => []);
|
||||
for (const message of messages)
|
||||
result.push(messageToConsoleMessage(message));
|
||||
const errors = await page.pageErrors().catch(() => []);
|
||||
for (const error of errors)
|
||||
result.push(pageErrorToConsoleMessage(error));
|
||||
return result;
|
||||
}
|
||||
async _initialize() {
|
||||
for (const message of await Tab.collectConsoleMessages(this.page))
|
||||
this._handleConsoleMessage(message);
|
||||
const requests = await this.page.requests().catch(() => []);
|
||||
for (const request of requests)
|
||||
this._requests.add(request);
|
||||
}
|
||||
modalStates() {
|
||||
return this._modalStates;
|
||||
}
|
||||
setModalState(modalState) {
|
||||
this._modalStates.push(modalState);
|
||||
this.emit(TabEvents.modalState, modalState);
|
||||
}
|
||||
clearModalState(modalState) {
|
||||
this._modalStates = this._modalStates.filter((state) => state !== modalState);
|
||||
}
|
||||
modalStatesMarkdown() {
|
||||
return renderModalStates(this.context, this.modalStates());
|
||||
}
|
||||
_dialogShown(dialog) {
|
||||
this.setModalState({
|
||||
type: "dialog",
|
||||
description: `"${dialog.type()}" dialog with message "${dialog.message()}"`,
|
||||
dialog,
|
||||
clearedBy: import_dialogs.handleDialog.schema.name
|
||||
});
|
||||
}
|
||||
async _downloadStarted(download) {
|
||||
const entry = {
|
||||
download,
|
||||
finished: false,
|
||||
outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", reason: "Saving download" })
|
||||
};
|
||||
this._downloads.push(entry);
|
||||
await download.saveAs(entry.outputFile);
|
||||
entry.finished = true;
|
||||
}
|
||||
_clearCollectedArtifacts() {
|
||||
this._consoleMessages.length = 0;
|
||||
this._recentConsoleMessages.length = 0;
|
||||
this._requests.clear();
|
||||
}
|
||||
_handleConsoleMessage(message) {
|
||||
this._consoleMessages.push(message);
|
||||
this._recentConsoleMessages.push(message);
|
||||
}
|
||||
_onClose() {
|
||||
this._clearCollectedArtifacts();
|
||||
this._onPageClose(this);
|
||||
}
|
||||
async updateTitle() {
|
||||
await this._raceAgainstModalStates(async () => {
|
||||
this._lastTitle = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
|
||||
});
|
||||
}
|
||||
lastTitle() {
|
||||
return this._lastTitle;
|
||||
}
|
||||
isCurrentTab() {
|
||||
return this === this.context.currentTab();
|
||||
}
|
||||
async waitForLoadState(state, options) {
|
||||
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForLoadState(state, options).catch(import_log.logUnhandledError));
|
||||
}
|
||||
async navigate(url) {
|
||||
this._clearCollectedArtifacts();
|
||||
const downloadEvent = (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForEvent("download").catch(import_log.logUnhandledError));
|
||||
try {
|
||||
await this.page.goto(url, { waitUntil: "domcontentloaded" });
|
||||
} catch (_e) {
|
||||
const e = _e;
|
||||
const mightBeDownload = e.message.includes("net::ERR_ABORTED") || e.message.includes("Download is starting");
|
||||
if (!mightBeDownload)
|
||||
throw e;
|
||||
const download = await Promise.race([
|
||||
downloadEvent,
|
||||
new Promise((resolve) => setTimeout(resolve, 3e3))
|
||||
]);
|
||||
if (!download)
|
||||
throw e;
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
return;
|
||||
}
|
||||
await this.waitForLoadState("load", { timeout: 5e3 });
|
||||
}
|
||||
async consoleMessages(type) {
|
||||
await this._initializedPromise;
|
||||
return this._consoleMessages.filter((message) => type ? message.type === type : true);
|
||||
}
|
||||
async requests() {
|
||||
await this._initializedPromise;
|
||||
return this._requests;
|
||||
}
|
||||
async captureSnapshot() {
|
||||
let tabSnapshot;
|
||||
const modalStates = await this._raceAgainstModalStates(async () => {
|
||||
const snapshot = await this.page._snapshotForAI();
|
||||
tabSnapshot = {
|
||||
url: this.page.url(),
|
||||
title: await this.page.title(),
|
||||
ariaSnapshot: snapshot,
|
||||
modalStates: [],
|
||||
consoleMessages: [],
|
||||
downloads: this._downloads
|
||||
};
|
||||
});
|
||||
if (tabSnapshot) {
|
||||
tabSnapshot.consoleMessages = this._recentConsoleMessages;
|
||||
this._recentConsoleMessages = [];
|
||||
}
|
||||
return tabSnapshot ?? {
|
||||
url: this.page.url(),
|
||||
title: "",
|
||||
ariaSnapshot: "",
|
||||
modalStates,
|
||||
consoleMessages: [],
|
||||
downloads: []
|
||||
};
|
||||
}
|
||||
_javaScriptBlocked() {
|
||||
return this._modalStates.some((state) => state.type === "dialog");
|
||||
}
|
||||
async _raceAgainstModalStates(action) {
|
||||
if (this.modalStates().length)
|
||||
return this.modalStates();
|
||||
const promise = new import_utils.ManualPromise();
|
||||
const listener = (modalState) => promise.resolve([modalState]);
|
||||
this.once(TabEvents.modalState, listener);
|
||||
return await Promise.race([
|
||||
action().then(() => {
|
||||
this.off(TabEvents.modalState, listener);
|
||||
return [];
|
||||
}),
|
||||
promise
|
||||
]);
|
||||
}
|
||||
async waitForCompletion(callback) {
|
||||
await this._raceAgainstModalStates(() => (0, import_utils2.waitForCompletion)(this, callback));
|
||||
}
|
||||
async refLocator(params) {
|
||||
return (await this.refLocators([params]))[0];
|
||||
}
|
||||
async refLocators(params) {
|
||||
const snapshot = await this.page._snapshotForAI();
|
||||
return params.map((param) => {
|
||||
if (!snapshot.includes(`[ref=${param.ref}]`))
|
||||
throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);
|
||||
return this.page.locator(`aria-ref=${param.ref}`).describe(param.element);
|
||||
});
|
||||
}
|
||||
async waitForTimeout(time) {
|
||||
if (this._javaScriptBlocked()) {
|
||||
await new Promise((f) => setTimeout(f, time));
|
||||
return;
|
||||
}
|
||||
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => {
|
||||
return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3)));
|
||||
});
|
||||
}
|
||||
}
|
||||
function messageToConsoleMessage(message) {
|
||||
return {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
toString: () => `[${message.type().toUpperCase()}] ${message.text()} @ ${message.location().url}:${message.location().lineNumber}`
|
||||
};
|
||||
}
|
||||
function pageErrorToConsoleMessage(errorOrValue) {
|
||||
if (errorOrValue instanceof Error) {
|
||||
return {
|
||||
type: "error",
|
||||
text: errorOrValue.message,
|
||||
toString: () => errorOrValue.stack || errorOrValue.message
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "error",
|
||||
text: String(errorOrValue),
|
||||
toString: () => String(errorOrValue)
|
||||
};
|
||||
}
|
||||
function renderModalStates(context, modalStates) {
|
||||
const result = ["### Modal state"];
|
||||
if (modalStates.length === 0)
|
||||
result.push("- There is no modal state present");
|
||||
for (const state of modalStates)
|
||||
result.push(`- [${state.description}]: can be handled by the "${state.clearedBy}" tool`);
|
||||
return result;
|
||||
}
|
||||
const tabSymbol = Symbol("tabSymbol");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Tab,
|
||||
TabEvents,
|
||||
renderModalStates
|
||||
});
|
||||
80
node_modules/playwright/lib/mcp/browser/tools.js
generated
vendored
Normal file
80
node_modules/playwright/lib/mcp/browser/tools.js
generated
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
"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 tools_exports = {};
|
||||
__export(tools_exports, {
|
||||
browserTools: () => browserTools,
|
||||
filteredTools: () => filteredTools
|
||||
});
|
||||
module.exports = __toCommonJS(tools_exports);
|
||||
var import_common = __toESM(require("./tools/common"));
|
||||
var import_console = __toESM(require("./tools/console"));
|
||||
var import_dialogs = __toESM(require("./tools/dialogs"));
|
||||
var import_evaluate = __toESM(require("./tools/evaluate"));
|
||||
var import_files = __toESM(require("./tools/files"));
|
||||
var import_form = __toESM(require("./tools/form"));
|
||||
var import_install = __toESM(require("./tools/install"));
|
||||
var import_keyboard = __toESM(require("./tools/keyboard"));
|
||||
var import_mouse = __toESM(require("./tools/mouse"));
|
||||
var import_navigate = __toESM(require("./tools/navigate"));
|
||||
var import_network = __toESM(require("./tools/network"));
|
||||
var import_pdf = __toESM(require("./tools/pdf"));
|
||||
var import_snapshot = __toESM(require("./tools/snapshot"));
|
||||
var import_screenshot = __toESM(require("./tools/screenshot"));
|
||||
var import_tabs = __toESM(require("./tools/tabs"));
|
||||
var import_tracing = __toESM(require("./tools/tracing"));
|
||||
var import_wait = __toESM(require("./tools/wait"));
|
||||
var import_verify = __toESM(require("./tools/verify"));
|
||||
const browserTools = [
|
||||
...import_common.default,
|
||||
...import_console.default,
|
||||
...import_dialogs.default,
|
||||
...import_evaluate.default,
|
||||
...import_files.default,
|
||||
...import_form.default,
|
||||
...import_install.default,
|
||||
...import_keyboard.default,
|
||||
...import_navigate.default,
|
||||
...import_network.default,
|
||||
...import_mouse.default,
|
||||
...import_pdf.default,
|
||||
...import_screenshot.default,
|
||||
...import_snapshot.default,
|
||||
...import_tabs.default,
|
||||
...import_tracing.default,
|
||||
...import_wait.default,
|
||||
...import_verify.default
|
||||
];
|
||||
function filteredTools(config) {
|
||||
return browserTools.filter((tool) => tool.capability.startsWith("core") || config.capabilities?.includes(tool.capability));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
browserTools,
|
||||
filteredTools
|
||||
});
|
||||
63
node_modules/playwright/lib/mcp/browser/tools/common.js
generated
vendored
Normal file
63
node_modules/playwright/lib/mcp/browser/tools/common.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"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 common_exports = {};
|
||||
__export(common_exports, {
|
||||
default: () => common_default
|
||||
});
|
||||
module.exports = __toCommonJS(common_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const close = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_close",
|
||||
title: "Close browser",
|
||||
description: "Close the page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
await context.closeBrowserContext();
|
||||
response.setIncludeTabs();
|
||||
response.addCode(`await page.close()`);
|
||||
}
|
||||
});
|
||||
const resize = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_resize",
|
||||
title: "Resize browser window",
|
||||
description: "Resize the browser window",
|
||||
inputSchema: import_bundle.z.object({
|
||||
width: import_bundle.z.number().describe("Width of the browser window"),
|
||||
height: import_bundle.z.number().describe("Height of the browser window")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.setViewportSize({ width: params.width, height: params.height });
|
||||
});
|
||||
}
|
||||
});
|
||||
var common_default = [
|
||||
close,
|
||||
resize
|
||||
];
|
||||
44
node_modules/playwright/lib/mcp/browser/tools/console.js
generated
vendored
Normal file
44
node_modules/playwright/lib/mcp/browser/tools/console.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 console_exports = {};
|
||||
__export(console_exports, {
|
||||
default: () => console_default
|
||||
});
|
||||
module.exports = __toCommonJS(console_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const console = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_console_messages",
|
||||
title: "Get console messages",
|
||||
description: "Returns all console messages",
|
||||
inputSchema: import_bundle.z.object({
|
||||
onlyErrors: import_bundle.z.boolean().optional().describe("Only return error messages")
|
||||
}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const messages = await tab.consoleMessages(params.onlyErrors ? "error" : void 0);
|
||||
messages.map((message) => response.addResult(message.toString()));
|
||||
}
|
||||
});
|
||||
var console_default = [
|
||||
console
|
||||
];
|
||||
60
node_modules/playwright/lib/mcp/browser/tools/dialogs.js
generated
vendored
Normal file
60
node_modules/playwright/lib/mcp/browser/tools/dialogs.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"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 dialogs_exports = {};
|
||||
__export(dialogs_exports, {
|
||||
default: () => dialogs_default,
|
||||
handleDialog: () => handleDialog
|
||||
});
|
||||
module.exports = __toCommonJS(dialogs_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const handleDialog = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_handle_dialog",
|
||||
title: "Handle a dialog",
|
||||
description: "Handle a dialog",
|
||||
inputSchema: import_bundle.z.object({
|
||||
accept: import_bundle.z.boolean().describe("Whether to accept the dialog."),
|
||||
promptText: import_bundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const dialogState = tab.modalStates().find((state) => state.type === "dialog");
|
||||
if (!dialogState)
|
||||
throw new Error("No dialog visible");
|
||||
tab.clearModalState(dialogState);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.accept)
|
||||
await dialogState.dialog.accept(params.promptText);
|
||||
else
|
||||
await dialogState.dialog.dismiss();
|
||||
});
|
||||
},
|
||||
clearsModalState: "dialog"
|
||||
});
|
||||
var dialogs_default = [
|
||||
handleDialog
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
handleDialog
|
||||
});
|
||||
70
node_modules/playwright/lib/mcp/browser/tools/evaluate.js
generated
vendored
Normal file
70
node_modules/playwright/lib/mcp/browser/tools/evaluate.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 evaluate_exports = {};
|
||||
__export(evaluate_exports, {
|
||||
default: () => evaluate_default
|
||||
});
|
||||
module.exports = __toCommonJS(evaluate_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const evaluateSchema = import_bundle.z.object({
|
||||
function: import_bundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
|
||||
element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
|
||||
ref: import_bundle.z.string().optional().describe("Exact target element reference from the page snapshot")
|
||||
});
|
||||
const evaluate = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_evaluate",
|
||||
title: "Evaluate JavaScript",
|
||||
description: "Evaluate JavaScript expression on page or element",
|
||||
inputSchema: evaluateSchema,
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
let locator;
|
||||
if (params.ref && params.element) {
|
||||
locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.evaluate(${javascript.quote(params.function)});`);
|
||||
} else {
|
||||
response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);
|
||||
}
|
||||
await tab.waitForCompletion(async () => {
|
||||
const receiver = locator ?? tab.page;
|
||||
const result = await receiver._evaluateFunction(params.function);
|
||||
response.addResult(JSON.stringify(result, null, 2) || "undefined");
|
||||
});
|
||||
}
|
||||
});
|
||||
var evaluate_default = [
|
||||
evaluate
|
||||
];
|
||||
58
node_modules/playwright/lib/mcp/browser/tools/files.js
generated
vendored
Normal file
58
node_modules/playwright/lib/mcp/browser/tools/files.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 files_exports = {};
|
||||
__export(files_exports, {
|
||||
default: () => files_default,
|
||||
uploadFile: () => uploadFile
|
||||
});
|
||||
module.exports = __toCommonJS(files_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const uploadFile = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_file_upload",
|
||||
title: "Upload files",
|
||||
description: "Upload one or multiple files",
|
||||
inputSchema: import_bundle.z.object({
|
||||
paths: import_bundle.z.array(import_bundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const modalState = tab.modalStates().find((state) => state.type === "fileChooser");
|
||||
if (!modalState)
|
||||
throw new Error("No file chooser visible");
|
||||
response.addCode(`await fileChooser.setFiles(${JSON.stringify(params.paths)})`);
|
||||
tab.clearModalState(modalState);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.paths)
|
||||
await modalState.fileChooser.setFiles(params.paths);
|
||||
});
|
||||
},
|
||||
clearsModalState: "fileChooser"
|
||||
});
|
||||
var files_default = [
|
||||
uploadFile
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
uploadFile
|
||||
});
|
||||
74
node_modules/playwright/lib/mcp/browser/tools/form.js
generated
vendored
Normal file
74
node_modules/playwright/lib/mcp/browser/tools/form.js
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"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 form_exports = {};
|
||||
__export(form_exports, {
|
||||
default: () => form_default
|
||||
});
|
||||
module.exports = __toCommonJS(form_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var import_utils = require("./utils");
|
||||
var codegen = __toESM(require("../codegen"));
|
||||
const fillForm = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_fill_form",
|
||||
title: "Fill form",
|
||||
description: "Fill multiple form fields",
|
||||
inputSchema: import_bundle.z.object({
|
||||
fields: import_bundle.z.array(import_bundle.z.object({
|
||||
name: import_bundle.z.string().describe("Human-readable field name"),
|
||||
type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
|
||||
ref: import_bundle.z.string().describe("Exact target field reference from the page snapshot"),
|
||||
value: import_bundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
|
||||
})).describe("Fields to fill in")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
for (const field of params.fields) {
|
||||
const locator = await tab.refLocator({ element: field.name, ref: field.ref });
|
||||
const locatorSource = `await page.${await (0, import_utils.generateLocator)(locator)}`;
|
||||
if (field.type === "textbox" || field.type === "slider") {
|
||||
const secret = tab.context.lookupSecret(field.value);
|
||||
await locator.fill(secret.value);
|
||||
response.addCode(`${locatorSource}.fill(${secret.code});`);
|
||||
} else if (field.type === "checkbox" || field.type === "radio") {
|
||||
await locator.setChecked(field.value === "true");
|
||||
response.addCode(`${locatorSource}.setChecked(${field.value});`);
|
||||
} else if (field.type === "combobox") {
|
||||
await locator.selectOption({ label: field.value });
|
||||
response.addCode(`${locatorSource}.selectOption(${codegen.quote(field.value)});`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var form_default = [
|
||||
fillForm
|
||||
];
|
||||
69
node_modules/playwright/lib/mcp/browser/tools/install.js
generated
vendored
Normal file
69
node_modules/playwright/lib/mcp/browser/tools/install.js
generated
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"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 install_exports = {};
|
||||
__export(install_exports, {
|
||||
default: () => install_default
|
||||
});
|
||||
module.exports = __toCommonJS(install_exports);
|
||||
var import_child_process = require("child_process");
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const install = (0, import_tool.defineTool)({
|
||||
capability: "core-install",
|
||||
schema: {
|
||||
name: "browser_install",
|
||||
title: "Install the browser specified in the config",
|
||||
description: "Install the browser specified in the config. Call this if you get an error about the browser not being installed.",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? "chrome";
|
||||
const cliPath = import_path.default.join(require.resolve("playwright/package.json"), "../cli.js");
|
||||
const child = (0, import_child_process.fork)(cliPath, ["install", channel], {
|
||||
stdio: "pipe"
|
||||
});
|
||||
const output = [];
|
||||
child.stdout?.on("data", (data) => output.push(data.toString()));
|
||||
child.stderr?.on("data", (data) => output.push(data.toString()));
|
||||
await new Promise((resolve, reject) => {
|
||||
child.on("close", (code) => {
|
||||
if (code === 0)
|
||||
resolve();
|
||||
else
|
||||
reject(new Error(`Failed to install browser: ${output.join("")}`));
|
||||
});
|
||||
});
|
||||
response.setIncludeTabs();
|
||||
}
|
||||
});
|
||||
var install_default = [
|
||||
install
|
||||
];
|
||||
85
node_modules/playwright/lib/mcp/browser/tools/keyboard.js
generated
vendored
Normal file
85
node_modules/playwright/lib/mcp/browser/tools/keyboard.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 keyboard_exports = {};
|
||||
__export(keyboard_exports, {
|
||||
default: () => keyboard_default
|
||||
});
|
||||
module.exports = __toCommonJS(keyboard_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var import_snapshot = require("./snapshot");
|
||||
var import_utils = require("./utils");
|
||||
const pressKey = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_press_key",
|
||||
title: "Press a key",
|
||||
description: "Press a key on the keyboard",
|
||||
inputSchema: import_bundle.z.object({
|
||||
key: import_bundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Press ${params.key}`);
|
||||
response.addCode(`await page.keyboard.press('${params.key}');`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.keyboard.press(params.key);
|
||||
});
|
||||
}
|
||||
});
|
||||
const typeSchema = import_snapshot.elementSchema.extend({
|
||||
text: import_bundle.z.string().describe("Text to type into the element"),
|
||||
submit: import_bundle.z.boolean().optional().describe("Whether to submit entered text (press Enter after)"),
|
||||
slowly: import_bundle.z.boolean().optional().describe("Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.")
|
||||
});
|
||||
const type = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_type",
|
||||
title: "Type text",
|
||||
description: "Type text into editable element",
|
||||
inputSchema: typeSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator(params);
|
||||
const secret = tab.context.lookupSecret(params.text);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.slowly) {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.pressSequentially(${secret.code});`);
|
||||
await locator.pressSequentially(secret.value);
|
||||
} else {
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.fill(${secret.code});`);
|
||||
await locator.fill(secret.value);
|
||||
}
|
||||
if (params.submit) {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.press('Enter');`);
|
||||
await locator.press("Enter");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
var keyboard_default = [
|
||||
pressKey,
|
||||
type
|
||||
];
|
||||
107
node_modules/playwright/lib/mcp/browser/tools/mouse.js
generated
vendored
Normal file
107
node_modules/playwright/lib/mcp/browser/tools/mouse.js
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"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 mouse_exports = {};
|
||||
__export(mouse_exports, {
|
||||
default: () => mouse_default
|
||||
});
|
||||
module.exports = __toCommonJS(mouse_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const elementSchema = import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable element description used to obtain permission to interact with the element")
|
||||
});
|
||||
const mouseMove = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_move_xy",
|
||||
title: "Move mouse",
|
||||
description: "Move mouse to a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
x: import_bundle.z.number().describe("X coordinate"),
|
||||
y: import_bundle.z.number().describe("Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.addCode(`// Move mouse to (${params.x}, ${params.y})`);
|
||||
response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.x, params.y);
|
||||
});
|
||||
}
|
||||
});
|
||||
const mouseClick = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_click_xy",
|
||||
title: "Click",
|
||||
description: "Click left mouse button at a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
x: import_bundle.z.number().describe("X coordinate"),
|
||||
y: import_bundle.z.number().describe("Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Click mouse at coordinates (${params.x}, ${params.y})`);
|
||||
response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);
|
||||
response.addCode(`await page.mouse.down();`);
|
||||
response.addCode(`await page.mouse.up();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.x, params.y);
|
||||
await tab.page.mouse.down();
|
||||
await tab.page.mouse.up();
|
||||
});
|
||||
}
|
||||
});
|
||||
const mouseDrag = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_drag_xy",
|
||||
title: "Drag mouse",
|
||||
description: "Drag left mouse button to a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
startX: import_bundle.z.number().describe("Start X coordinate"),
|
||||
startY: import_bundle.z.number().describe("Start Y coordinate"),
|
||||
endX: import_bundle.z.number().describe("End X coordinate"),
|
||||
endY: import_bundle.z.number().describe("End Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Drag mouse from (${params.startX}, ${params.startY}) to (${params.endX}, ${params.endY})`);
|
||||
response.addCode(`await page.mouse.move(${params.startX}, ${params.startY});`);
|
||||
response.addCode(`await page.mouse.down();`);
|
||||
response.addCode(`await page.mouse.move(${params.endX}, ${params.endY});`);
|
||||
response.addCode(`await page.mouse.up();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.startX, params.startY);
|
||||
await tab.page.mouse.down();
|
||||
await tab.page.mouse.move(params.endX, params.endY);
|
||||
await tab.page.mouse.up();
|
||||
});
|
||||
}
|
||||
});
|
||||
var mouse_default = [
|
||||
mouseMove,
|
||||
mouseClick,
|
||||
mouseDrag
|
||||
];
|
||||
62
node_modules/playwright/lib/mcp/browser/tools/navigate.js
generated
vendored
Normal file
62
node_modules/playwright/lib/mcp/browser/tools/navigate.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 navigate_exports = {};
|
||||
__export(navigate_exports, {
|
||||
default: () => navigate_default
|
||||
});
|
||||
module.exports = __toCommonJS(navigate_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const navigate = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_navigate",
|
||||
title: "Navigate to a URL",
|
||||
description: "Navigate to a URL",
|
||||
inputSchema: import_bundle.z.object({
|
||||
url: import_bundle.z.string().describe("The URL to navigate to")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const tab = await context.ensureTab();
|
||||
await tab.navigate(params.url);
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.goto('${params.url}');`);
|
||||
}
|
||||
});
|
||||
const goBack = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_navigate_back",
|
||||
title: "Go back",
|
||||
description: "Go back to the previous page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
await tab.page.goBack();
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.goBack();`);
|
||||
}
|
||||
});
|
||||
var navigate_default = [
|
||||
navigate,
|
||||
goBack
|
||||
];
|
||||
54
node_modules/playwright/lib/mcp/browser/tools/network.js
generated
vendored
Normal file
54
node_modules/playwright/lib/mcp/browser/tools/network.js
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"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 network_exports = {};
|
||||
__export(network_exports, {
|
||||
default: () => network_default
|
||||
});
|
||||
module.exports = __toCommonJS(network_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const requests = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_network_requests",
|
||||
title: "List network requests",
|
||||
description: "Returns all network requests since loading the page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const requests2 = await tab.requests();
|
||||
for (const request of requests2)
|
||||
response.addResult(await renderRequest(request));
|
||||
}
|
||||
});
|
||||
async function renderRequest(request) {
|
||||
const result = [];
|
||||
result.push(`[${request.method().toUpperCase()}] ${request.url()}`);
|
||||
const hasResponse = request._hasResponse;
|
||||
if (hasResponse) {
|
||||
const response = await request.response();
|
||||
if (response)
|
||||
result.push(`=> [${response.status()}] ${response.statusText()}`);
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
var network_default = [
|
||||
requests
|
||||
];
|
||||
59
node_modules/playwright/lib/mcp/browser/tools/pdf.js
generated
vendored
Normal file
59
node_modules/playwright/lib/mcp/browser/tools/pdf.js
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"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 pdf_exports = {};
|
||||
__export(pdf_exports, {
|
||||
default: () => pdf_default
|
||||
});
|
||||
module.exports = __toCommonJS(pdf_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const pdfSchema = import_bundle.z.object({
|
||||
filename: import_bundle.z.string().optional().describe("File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.")
|
||||
});
|
||||
const pdf = (0, import_tool.defineTabTool)({
|
||||
capability: "pdf",
|
||||
schema: {
|
||||
name: "browser_pdf_save",
|
||||
title: "Save as PDF",
|
||||
description: "Save page as PDF",
|
||||
inputSchema: pdfSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const fileName = await tab.context.outputFile(params.filename ?? (0, import_utils.dateAsFileName)("pdf"), { origin: "llm", reason: "Saving PDF" });
|
||||
response.addCode(`await page.pdf(${javascript.formatObject({ path: fileName })});`);
|
||||
response.addResult(`Saved page as ${fileName}`);
|
||||
await tab.page.pdf({ path: fileName });
|
||||
}
|
||||
});
|
||||
var pdf_default = [
|
||||
pdf
|
||||
];
|
||||
88
node_modules/playwright/lib/mcp/browser/tools/screenshot.js
generated
vendored
Normal file
88
node_modules/playwright/lib/mcp/browser/tools/screenshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"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 screenshot_exports = {};
|
||||
__export(screenshot_exports, {
|
||||
default: () => screenshot_default
|
||||
});
|
||||
module.exports = __toCommonJS(screenshot_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const screenshotSchema = import_bundle.z.object({
|
||||
type: import_bundle.z.enum(["png", "jpeg"]).default("png").describe("Image format for the screenshot. Default is png."),
|
||||
filename: import_bundle.z.string().optional().describe("File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified."),
|
||||
element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too."),
|
||||
ref: import_bundle.z.string().optional().describe("Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too."),
|
||||
fullPage: import_bundle.z.boolean().optional().describe("When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.")
|
||||
});
|
||||
const screenshot = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_take_screenshot",
|
||||
title: "Take a screenshot",
|
||||
description: `Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.`,
|
||||
inputSchema: screenshotSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
if (!!params.element !== !!params.ref)
|
||||
throw new Error("Both element and ref must be provided or neither.");
|
||||
if (params.fullPage && params.ref)
|
||||
throw new Error("fullPage cannot be used with element screenshots.");
|
||||
const fileType = params.type || "png";
|
||||
const fileName = await tab.context.outputFile(params.filename ?? (0, import_utils.dateAsFileName)(fileType), { origin: "llm", reason: "Saving screenshot" });
|
||||
const options = {
|
||||
type: fileType,
|
||||
quality: fileType === "png" ? void 0 : 90,
|
||||
scale: "css",
|
||||
path: fileName,
|
||||
...params.fullPage !== void 0 && { fullPage: params.fullPage }
|
||||
};
|
||||
const isElementScreenshot = params.element && params.ref;
|
||||
const screenshotTarget = isElementScreenshot ? params.element : params.fullPage ? "full page" : "viewport";
|
||||
response.addCode(`// Screenshot ${screenshotTarget} and save it as ${fileName}`);
|
||||
const locator = params.ref ? await tab.refLocator({ element: params.element || "", ref: params.ref }) : null;
|
||||
if (locator)
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.screenshot(${javascript.formatObject(options)});`);
|
||||
else
|
||||
response.addCode(`await page.screenshot(${javascript.formatObject(options)});`);
|
||||
const buffer = locator ? await locator.screenshot(options) : await tab.page.screenshot(options);
|
||||
response.addResult(`Took the ${screenshotTarget} screenshot and saved it as ${fileName}`);
|
||||
if (!params.fullPage) {
|
||||
response.addImage({
|
||||
contentType: fileType === "png" ? "image/png" : "image/jpeg",
|
||||
data: buffer
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
var screenshot_default = [
|
||||
screenshot
|
||||
];
|
||||
182
node_modules/playwright/lib/mcp/browser/tools/snapshot.js
generated
vendored
Normal file
182
node_modules/playwright/lib/mcp/browser/tools/snapshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
"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 snapshot_exports = {};
|
||||
__export(snapshot_exports, {
|
||||
default: () => snapshot_default,
|
||||
elementSchema: () => elementSchema
|
||||
});
|
||||
module.exports = __toCommonJS(snapshot_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const snapshot = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_snapshot",
|
||||
title: "Page snapshot",
|
||||
description: "Capture accessibility snapshot of the current page, this is better than screenshot",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
await context.ensureTab();
|
||||
response.setIncludeSnapshot();
|
||||
}
|
||||
});
|
||||
const elementSchema = import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable element description used to obtain permission to interact with the element"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference from the page snapshot")
|
||||
});
|
||||
const clickSchema = elementSchema.extend({
|
||||
doubleClick: import_bundle.z.boolean().optional().describe("Whether to perform a double click instead of a single click"),
|
||||
button: import_bundle.z.enum(["left", "right", "middle"]).optional().describe("Button to click, defaults to left"),
|
||||
modifiers: import_bundle.z.array(import_bundle.z.enum(["Alt", "Control", "ControlOrMeta", "Meta", "Shift"])).optional().describe("Modifier keys to press")
|
||||
});
|
||||
const click = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_click",
|
||||
title: "Click",
|
||||
description: "Perform click on a web page",
|
||||
inputSchema: clickSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
const options = {
|
||||
button: params.button,
|
||||
modifiers: params.modifiers
|
||||
};
|
||||
const formatted = javascript.formatObject(options, " ", "oneline");
|
||||
const optionsAttr = formatted !== "{}" ? formatted : "";
|
||||
if (params.doubleClick)
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.dblclick(${optionsAttr});`);
|
||||
else
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.click(${optionsAttr});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.doubleClick)
|
||||
await locator.dblclick(options);
|
||||
else
|
||||
await locator.click(options);
|
||||
});
|
||||
}
|
||||
});
|
||||
const drag = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_drag",
|
||||
title: "Drag mouse",
|
||||
description: "Perform drag and drop between two elements",
|
||||
inputSchema: import_bundle.z.object({
|
||||
startElement: import_bundle.z.string().describe("Human-readable source element description used to obtain the permission to interact with the element"),
|
||||
startRef: import_bundle.z.string().describe("Exact source element reference from the page snapshot"),
|
||||
endElement: import_bundle.z.string().describe("Human-readable target element description used to obtain the permission to interact with the element"),
|
||||
endRef: import_bundle.z.string().describe("Exact target element reference from the page snapshot")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const [startLocator, endLocator] = await tab.refLocators([
|
||||
{ ref: params.startRef, element: params.startElement },
|
||||
{ ref: params.endRef, element: params.endElement }
|
||||
]);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await startLocator.dragTo(endLocator);
|
||||
});
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(startLocator)}.dragTo(page.${await (0, import_utils.generateLocator)(endLocator)});`);
|
||||
}
|
||||
});
|
||||
const hover = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_hover",
|
||||
title: "Hover mouse",
|
||||
description: "Hover over element on page",
|
||||
inputSchema: elementSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.hover();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await locator.hover();
|
||||
});
|
||||
}
|
||||
});
|
||||
const selectOptionSchema = elementSchema.extend({
|
||||
values: import_bundle.z.array(import_bundle.z.string()).describe("Array of values to select in the dropdown. This can be a single value or multiple values.")
|
||||
});
|
||||
const selectOption = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_select_option",
|
||||
title: "Select option",
|
||||
description: "Select an option in a dropdown",
|
||||
inputSchema: selectOptionSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.selectOption(${javascript.formatObject(params.values)});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await locator.selectOption(params.values);
|
||||
});
|
||||
}
|
||||
});
|
||||
const pickLocator = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_generate_locator",
|
||||
title: "Create locator for element",
|
||||
description: "Generate locator for the given element to use in tests",
|
||||
inputSchema: elementSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addResult(await (0, import_utils.generateLocator)(locator));
|
||||
}
|
||||
});
|
||||
var snapshot_default = [
|
||||
snapshot,
|
||||
click,
|
||||
drag,
|
||||
hover,
|
||||
selectOption,
|
||||
pickLocator
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
elementSchema
|
||||
});
|
||||
67
node_modules/playwright/lib/mcp/browser/tools/tabs.js
generated
vendored
Normal file
67
node_modules/playwright/lib/mcp/browser/tools/tabs.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 tabs_exports = {};
|
||||
__export(tabs_exports, {
|
||||
default: () => tabs_default
|
||||
});
|
||||
module.exports = __toCommonJS(tabs_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const browserTabs = (0, import_tool.defineTool)({
|
||||
capability: "core-tabs",
|
||||
schema: {
|
||||
name: "browser_tabs",
|
||||
title: "Manage tabs",
|
||||
description: "List, create, close, or select a browser tab.",
|
||||
inputSchema: import_bundle.z.object({
|
||||
action: import_bundle.z.enum(["list", "new", "close", "select"]).describe("Operation to perform"),
|
||||
index: import_bundle.z.number().optional().describe("Tab index, used for close/select. If omitted for close, current tab is closed.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
switch (params.action) {
|
||||
case "list": {
|
||||
await context.ensureTab();
|
||||
response.setIncludeTabs();
|
||||
return;
|
||||
}
|
||||
case "new": {
|
||||
await context.newTab();
|
||||
response.setIncludeTabs();
|
||||
return;
|
||||
}
|
||||
case "close": {
|
||||
await context.closeTab(params.index);
|
||||
response.setIncludeSnapshot();
|
||||
return;
|
||||
}
|
||||
case "select": {
|
||||
if (params.index === void 0)
|
||||
throw new Error("Tab index is required");
|
||||
await context.selectTab(params.index);
|
||||
response.setIncludeSnapshot();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var tabs_default = [
|
||||
browserTabs
|
||||
];
|
||||
49
node_modules/playwright/lib/mcp/browser/tools/tool.js
generated
vendored
Normal file
49
node_modules/playwright/lib/mcp/browser/tools/tool.js
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"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 tool_exports = {};
|
||||
__export(tool_exports, {
|
||||
defineTabTool: () => defineTabTool,
|
||||
defineTool: () => defineTool
|
||||
});
|
||||
module.exports = __toCommonJS(tool_exports);
|
||||
function defineTool(tool) {
|
||||
return tool;
|
||||
}
|
||||
function defineTabTool(tool) {
|
||||
return {
|
||||
...tool,
|
||||
handle: async (context, params, response) => {
|
||||
const tab = await context.ensureTab();
|
||||
const modalStates = tab.modalStates().map((state) => state.type);
|
||||
if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState))
|
||||
response.addError(`Error: The tool "${tool.schema.name}" can only be used when there is related modal state present.
|
||||
` + tab.modalStatesMarkdown().join("\n"));
|
||||
else if (!tool.clearsModalState && modalStates.length)
|
||||
response.addError(`Error: Tool "${tool.schema.name}" does not handle the modal state.
|
||||
` + tab.modalStatesMarkdown().join("\n"));
|
||||
else
|
||||
return tool.handle(tab, params, response);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
defineTabTool,
|
||||
defineTool
|
||||
});
|
||||
74
node_modules/playwright/lib/mcp/browser/tools/tracing.js
generated
vendored
Normal file
74
node_modules/playwright/lib/mcp/browser/tools/tracing.js
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"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 tracing_exports = {};
|
||||
__export(tracing_exports, {
|
||||
default: () => tracing_default
|
||||
});
|
||||
module.exports = __toCommonJS(tracing_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const tracingStart = (0, import_tool.defineTool)({
|
||||
capability: "tracing",
|
||||
schema: {
|
||||
name: "browser_start_tracing",
|
||||
title: "Start tracing",
|
||||
description: "Start trace recording",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const browserContext = await context.ensureBrowserContext();
|
||||
const tracesDir = await context.outputFile(`traces`, { origin: "code", reason: "Collecting trace" });
|
||||
const name = "trace-" + Date.now();
|
||||
await browserContext.tracing.start({
|
||||
name,
|
||||
screenshots: true,
|
||||
snapshots: true,
|
||||
_live: true
|
||||
});
|
||||
const traceLegend = `- Action log: ${tracesDir}/${name}.trace
|
||||
- Network log: ${tracesDir}/${name}.network
|
||||
- Resources with content by sha1: ${tracesDir}/resources`;
|
||||
response.addResult(`Tracing started, saving to ${tracesDir}.
|
||||
${traceLegend}`);
|
||||
browserContext.tracing[traceLegendSymbol] = traceLegend;
|
||||
}
|
||||
});
|
||||
const tracingStop = (0, import_tool.defineTool)({
|
||||
capability: "tracing",
|
||||
schema: {
|
||||
name: "browser_stop_tracing",
|
||||
title: "Stop tracing",
|
||||
description: "Stop trace recording",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const browserContext = await context.ensureBrowserContext();
|
||||
await browserContext.tracing.stop();
|
||||
const traceLegend = browserContext.tracing[traceLegendSymbol];
|
||||
response.addResult(`Tracing stopped.
|
||||
${traceLegend}`);
|
||||
}
|
||||
});
|
||||
var tracing_default = [
|
||||
tracingStart,
|
||||
tracingStop
|
||||
];
|
||||
const traceLegendSymbol = Symbol("tracesDir");
|
||||
100
node_modules/playwright/lib/mcp/browser/tools/utils.js
generated
vendored
Normal file
100
node_modules/playwright/lib/mcp/browser/tools/utils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"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 utils_exports = {};
|
||||
__export(utils_exports, {
|
||||
callOnPageNoTrace: () => callOnPageNoTrace,
|
||||
dateAsFileName: () => dateAsFileName,
|
||||
generateLocator: () => generateLocator,
|
||||
waitForCompletion: () => waitForCompletion
|
||||
});
|
||||
module.exports = __toCommonJS(utils_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
async function waitForCompletion(tab, callback) {
|
||||
const requests = /* @__PURE__ */ new Set();
|
||||
let frameNavigated = false;
|
||||
let waitCallback = () => {
|
||||
};
|
||||
const waitBarrier = new Promise((f) => {
|
||||
waitCallback = f;
|
||||
});
|
||||
const responseListener = (request) => {
|
||||
requests.delete(request);
|
||||
if (!requests.size)
|
||||
waitCallback();
|
||||
};
|
||||
const requestListener = (request) => {
|
||||
requests.add(request);
|
||||
void request.response().then(() => responseListener(request)).catch(() => {
|
||||
});
|
||||
};
|
||||
const frameNavigateListener = (frame) => {
|
||||
if (frame.parentFrame())
|
||||
return;
|
||||
frameNavigated = true;
|
||||
dispose();
|
||||
clearTimeout(timeout);
|
||||
void tab.waitForLoadState("load").then(waitCallback);
|
||||
};
|
||||
const onTimeout = () => {
|
||||
dispose();
|
||||
waitCallback();
|
||||
};
|
||||
tab.page.on("request", requestListener);
|
||||
tab.page.on("requestfailed", responseListener);
|
||||
tab.page.on("framenavigated", frameNavigateListener);
|
||||
const timeout = setTimeout(onTimeout, 1e4);
|
||||
const dispose = () => {
|
||||
tab.page.off("request", requestListener);
|
||||
tab.page.off("requestfailed", responseListener);
|
||||
tab.page.off("framenavigated", frameNavigateListener);
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
try {
|
||||
const result = await callback();
|
||||
if (!requests.size && !frameNavigated)
|
||||
waitCallback();
|
||||
await waitBarrier;
|
||||
await tab.waitForTimeout(1e3);
|
||||
return result;
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
async function generateLocator(locator) {
|
||||
try {
|
||||
const { resolvedSelector } = await locator._resolveSelector();
|
||||
return (0, import_utils.asLocator)("javascript", resolvedSelector);
|
||||
} catch (e) {
|
||||
throw new Error("Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.");
|
||||
}
|
||||
}
|
||||
async function callOnPageNoTrace(page, callback) {
|
||||
return await page._wrapApiCall(() => callback(page), { internal: true });
|
||||
}
|
||||
function dateAsFileName(extension) {
|
||||
const date = /* @__PURE__ */ new Date();
|
||||
return `page-${date.toISOString().replace(/[:.]/g, "-")}.${extension}`;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
callOnPageNoTrace,
|
||||
dateAsFileName,
|
||||
generateLocator,
|
||||
waitForCompletion
|
||||
});
|
||||
154
node_modules/playwright/lib/mcp/browser/tools/verify.js
generated
vendored
Normal file
154
node_modules/playwright/lib/mcp/browser/tools/verify.js
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
"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 verify_exports = {};
|
||||
__export(verify_exports, {
|
||||
default: () => verify_default
|
||||
});
|
||||
module.exports = __toCommonJS(verify_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const verifyElement = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_element_visible",
|
||||
title: "Verify element visible",
|
||||
description: "Verify element is visible on the page",
|
||||
inputSchema: import_bundle.z.object({
|
||||
role: import_bundle.z.string().describe('ROLE of the element. Can be found in the snapshot like this: `- {ROLE} "Accessible Name":`'),
|
||||
accessibleName: import_bundle.z.string().describe('ACCESSIBLE_NAME of the element. Can be found in the snapshot like this: `- role "{ACCESSIBLE_NAME}"`')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = tab.page.getByRole(params.role, { name: params.accessibleName });
|
||||
if (await locator.count() === 0) {
|
||||
response.addError(`Element with role "${params.role}" and accessible name "${params.accessibleName}" not found`);
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(page.getByRole(${javascript.escapeWithQuotes(params.role)}, { name: ${javascript.escapeWithQuotes(params.accessibleName)} })).toBeVisible();`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyText = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_text_visible",
|
||||
title: "Verify text visible",
|
||||
description: `Verify text is visible on the page. Prefer ${verifyElement.schema.name} if possible.`,
|
||||
inputSchema: import_bundle.z.object({
|
||||
text: import_bundle.z.string().describe('TEXT to verify. Can be found in the snapshot like this: `- role "Accessible Name": {TEXT}` or like this: `- text: {TEXT}`')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = tab.page.getByText(params.text).filter({ visible: true });
|
||||
if (await locator.count() === 0) {
|
||||
response.addError("Text not found");
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(page.getByText(${javascript.escapeWithQuotes(params.text)})).toBeVisible();`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyList = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_list_visible",
|
||||
title: "Verify list visible",
|
||||
description: "Verify list is visible on the page",
|
||||
inputSchema: import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable list description"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference that points to the list"),
|
||||
items: import_bundle.z.array(import_bundle.z.string()).describe("Items to verify")
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
const itemTexts = [];
|
||||
for (const item of params.items) {
|
||||
const itemLocator = locator.getByText(item);
|
||||
if (await itemLocator.count() === 0) {
|
||||
response.addError(`Item "${item}" not found`);
|
||||
return;
|
||||
}
|
||||
itemTexts.push(await itemLocator.textContent());
|
||||
}
|
||||
const ariaSnapshot = `\`
|
||||
- list:
|
||||
${itemTexts.map((t) => ` - listitem: ${javascript.escapeWithQuotes(t, '"')}`).join("\n")}
|
||||
\``;
|
||||
response.addCode(`await expect(page.locator('body')).toMatchAriaSnapshot(${ariaSnapshot});`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyValue = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_value",
|
||||
title: "Verify value",
|
||||
description: "Verify element value",
|
||||
inputSchema: import_bundle.z.object({
|
||||
type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the element"),
|
||||
element: import_bundle.z.string().describe("Human-readable element description"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference that points to the element"),
|
||||
value: import_bundle.z.string().describe('Value to verify. For checkbox, use "true" or "false".')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
const locatorSource = `page.${await (0, import_utils.generateLocator)(locator)}`;
|
||||
if (params.type === "textbox" || params.type === "slider" || params.type === "combobox") {
|
||||
const value = await locator.inputValue();
|
||||
if (value !== params.value) {
|
||||
response.addError(`Expected value "${params.value}", but got "${value}"`);
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(${locatorSource}).toHaveValue(${javascript.quote(params.value)});`);
|
||||
} else if (params.type === "checkbox" || params.type === "radio") {
|
||||
const value = await locator.isChecked();
|
||||
if (value !== (params.value === "true")) {
|
||||
response.addError(`Expected value "${params.value}", but got "${value}"`);
|
||||
return;
|
||||
}
|
||||
const matcher = value ? "toBeChecked" : "not.toBeChecked";
|
||||
response.addCode(`await expect(${locatorSource}).${matcher}();`);
|
||||
}
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
var verify_default = [
|
||||
verifyElement,
|
||||
verifyText,
|
||||
verifyList,
|
||||
verifyValue
|
||||
];
|
||||
63
node_modules/playwright/lib/mcp/browser/tools/wait.js
generated
vendored
Normal file
63
node_modules/playwright/lib/mcp/browser/tools/wait.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"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 wait_exports = {};
|
||||
__export(wait_exports, {
|
||||
default: () => wait_default
|
||||
});
|
||||
module.exports = __toCommonJS(wait_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const wait = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_wait_for",
|
||||
title: "Wait for",
|
||||
description: "Wait for text to appear or disappear or a specified time to pass",
|
||||
inputSchema: import_bundle.z.object({
|
||||
time: import_bundle.z.number().optional().describe("The time to wait in seconds"),
|
||||
text: import_bundle.z.string().optional().describe("The text to wait for"),
|
||||
textGone: import_bundle.z.string().optional().describe("The text to wait for to disappear")
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
if (!params.text && !params.textGone && !params.time)
|
||||
throw new Error("Either time, text or textGone must be provided");
|
||||
if (params.time) {
|
||||
response.addCode(`await new Promise(f => setTimeout(f, ${params.time} * 1000));`);
|
||||
await new Promise((f) => setTimeout(f, Math.min(3e4, params.time * 1e3)));
|
||||
}
|
||||
const tab = context.currentTabOrDie();
|
||||
const locator = params.text ? tab.page.getByText(params.text).first() : void 0;
|
||||
const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : void 0;
|
||||
if (goneLocator) {
|
||||
response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);
|
||||
await goneLocator.waitFor({ state: "hidden" });
|
||||
}
|
||||
if (locator) {
|
||||
response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);
|
||||
await locator.waitFor({ state: "visible" });
|
||||
}
|
||||
response.addResult(`Waited for ${params.text || params.textGone || params.time}`);
|
||||
response.setIncludeSnapshot();
|
||||
}
|
||||
});
|
||||
var wait_default = [
|
||||
wait
|
||||
];
|
||||
44
node_modules/playwright/lib/mcp/browser/watchdog.js
generated
vendored
Normal file
44
node_modules/playwright/lib/mcp/browser/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_browserContextFactory = require("./browserContextFactory");
|
||||
var import_context = require("./context");
|
||||
function setupExitWatchdog() {
|
||||
let isExiting = false;
|
||||
const handleExit = async () => {
|
||||
if (isExiting)
|
||||
return;
|
||||
isExiting = true;
|
||||
setTimeout(() => process.exit(0), 15e3);
|
||||
await import_context.Context.disposeAll();
|
||||
await import_browserContextFactory.SharedContextFactory.dispose();
|
||||
process.exit(0);
|
||||
};
|
||||
process.stdin.on("close", handleExit);
|
||||
process.on("SIGINT", handleExit);
|
||||
process.on("SIGTERM", handleExit);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
setupExitWatchdog
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue