@cotestdev/mcp_playwright 0.0.48 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,7 +38,7 @@ const close = (0, import_command.declareCommand)({
38
38
  description: "Close the page",
39
39
  category: "core",
40
40
  args: import_mcpBundle.z.object({}),
41
- toolName: "browser_close",
41
+ toolName: "",
42
42
  toolParams: () => ({})
43
43
  });
44
44
  const goBack = (0, import_command.declareCommand)({
@@ -308,6 +308,16 @@ const resize = (0, import_command.declareCommand)({
308
308
  toolName: "browser_resize",
309
309
  toolParams: ({ w: width, h: height }) => ({ width, height })
310
310
  });
311
+ const runCode = (0, import_command.declareCommand)({
312
+ name: "run-code",
313
+ description: "Run Playwright code snippet",
314
+ category: "devtools",
315
+ args: import_mcpBundle.z.object({
316
+ code: import_mcpBundle.z.string().describe("A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction.")
317
+ }),
318
+ toolName: "browser_run_code",
319
+ toolParams: ({ code }) => ({ code })
320
+ });
311
321
  const tabList = (0, import_command.declareCommand)({
312
322
  name: "tab-list",
313
323
  description: "List all tabs",
@@ -396,16 +406,6 @@ const networkRequests = (0, import_command.declareCommand)({
396
406
  toolName: ({ clear }) => clear ? "browser_network_clear" : "browser_network_requests",
397
407
  toolParams: ({ static: includeStatic, clear }) => clear ? {} : { includeStatic }
398
408
  });
399
- const runCode = (0, import_command.declareCommand)({
400
- name: "run-code",
401
- description: "Run Playwright code snippet",
402
- category: "devtools",
403
- args: import_mcpBundle.z.object({
404
- code: import_mcpBundle.z.string().describe("A JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction.")
405
- }),
406
- toolName: "browser_run_code",
407
- toolParams: ({ code }) => ({ code })
408
- });
409
409
  const tracingStart = (0, import_command.declareCommand)({
410
410
  name: "tracing-start",
411
411
  description: "Start trace recording",
@@ -422,6 +422,24 @@ const tracingStop = (0, import_command.declareCommand)({
422
422
  toolName: "browser_stop_tracing",
423
423
  toolParams: () => ({})
424
424
  });
425
+ const videoStart = (0, import_command.declareCommand)({
426
+ name: "video-start",
427
+ description: "Start video recording",
428
+ category: "devtools",
429
+ args: import_mcpBundle.z.object({}),
430
+ toolName: "browser_start_video",
431
+ toolParams: () => ({})
432
+ });
433
+ const videoStop = (0, import_command.declareCommand)({
434
+ name: "video-stop",
435
+ description: "Stop video recording",
436
+ category: "devtools",
437
+ options: import_mcpBundle.z.object({
438
+ filename: import_mcpBundle.z.string().optional().describe("Filename to save the video.")
439
+ }),
440
+ toolName: "browser_stop_video",
441
+ toolParams: ({ filename }) => ({ filename })
442
+ });
425
443
  const sessionList = (0, import_command.declareCommand)({
426
444
  name: "session-list",
427
445
  description: "List all sessions",
@@ -487,6 +505,7 @@ const commandsArray = [
487
505
  dialogAccept,
488
506
  dialogDismiss,
489
507
  resize,
508
+ runCode,
490
509
  // navigation category
491
510
  goBack,
492
511
  goForward,
@@ -512,9 +531,10 @@ const commandsArray = [
512
531
  config,
513
532
  // devtools category
514
533
  networkRequests,
515
- runCode,
516
534
  tracingStart,
517
535
  tracingStop,
536
+ videoStart,
537
+ videoStop,
518
538
  // session category
519
539
  sessionList,
520
540
  sessionStop,
@@ -51,7 +51,7 @@ async function socketExists(socketPath) {
51
51
  }
52
52
  return false;
53
53
  }
54
- async function startMcpDaemonServer(socketPath, serverBackendFactory) {
54
+ async function startMcpDaemonServer(socketPath, serverBackendFactory, daemonVersion) {
55
55
  if (import_os.default.platform() !== "win32" && await socketExists(socketPath)) {
56
56
  daemonDebug(`Socket already exists, removing: ${socketPath}`);
57
57
  try {
@@ -75,21 +75,38 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory) {
75
75
  await import_promises.default.mkdir(import_path.default.dirname(socketPath), { recursive: true });
76
76
  const server = import_net.default.createServer((socket) => {
77
77
  daemonDebug("new client connection");
78
- const connection = new import_socketConnection.SocketConnection(socket);
78
+ const connection = new import_socketConnection.SocketConnection(socket, daemonVersion);
79
79
  connection.onclose = () => {
80
80
  daemonDebug("client disconnected");
81
81
  };
82
+ connection.onversionerror = (id, e) => {
83
+ if (daemonVersion === "undefined-for-test")
84
+ return false;
85
+ if (semverGreater(daemonVersion, e.received)) {
86
+ connection.send({ id, error: `Client is too old: daemon is ${daemonVersion}, client is ${e.received}.` }).catch((e2) => console.error(e2));
87
+ } else {
88
+ (0, import_utils.gracefullyProcessExitDoNotHang)(0, async () => {
89
+ await connection.send({ id, error: `Daemon is too old: daemon is ${daemonVersion}, client is ${e.received}. Stopping it.` }).catch((e2) => console.error(e2));
90
+ server.close();
91
+ });
92
+ }
93
+ return true;
94
+ };
82
95
  connection.onmessage = async (message) => {
83
96
  const { id, method, params } = message;
84
97
  try {
85
98
  daemonDebug("received command", method);
86
99
  if (method === "stop") {
87
100
  daemonDebug("stop command received, shutting down");
88
- await connection.send({ id, result: "ok" });
89
- server.close();
90
- (0, import_utils.gracefullyProcessExitDoNotHang)(0);
101
+ (0, import_utils.gracefullyProcessExitDoNotHang)(0, async () => {
102
+ await connection.send({ id, result: "ok" }).catch(() => {
103
+ });
104
+ server.close();
105
+ });
91
106
  } else if (method === "run") {
92
107
  const { toolName, toolParams } = parseCliCommand(params.args);
108
+ if (params.cwd)
109
+ toolParams._meta = { cwd: params.cwd };
93
110
  const response = await backend.callTool(toolName, toolParams, () => {
94
111
  });
95
112
  await connection.send({ id, result: formatResult(response) });
@@ -102,6 +119,11 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory) {
102
119
  }
103
120
  };
104
121
  });
122
+ backend.onBrowserContextClosed = () => {
123
+ daemonDebug("browser closed, shutting down daemon");
124
+ server.close();
125
+ (0, import_utils.gracefullyProcessExitDoNotHang)(0);
126
+ };
105
127
  return new Promise((resolve, reject) => {
106
128
  server.on("error", (error) => {
107
129
  daemonDebug(`server error: ${error.message}`);
@@ -116,8 +138,7 @@ async function startMcpDaemonServer(socketPath, serverBackendFactory) {
116
138
  function formatResult(result) {
117
139
  const isError = result.isError;
118
140
  const text = result.content[0].type === "text" ? result.content[0].text : void 0;
119
- const sections = result.content[0]._meta?.sections;
120
- return { isError, text, sections };
141
+ return { isError, text };
121
142
  }
122
143
  function parseCliCommand(args) {
123
144
  const command = import_commands.commands[args._[0]];
@@ -125,6 +146,19 @@ function parseCliCommand(args) {
125
146
  throw new Error("Command is required");
126
147
  return (0, import_command.parseCommand)(command, args);
127
148
  }
149
+ function semverGreater(a, b) {
150
+ a = a.replace(/-next$/, "");
151
+ b = b.replace(/-next$/, "");
152
+ const aParts = a.split(".").map(Number);
153
+ const bParts = b.split(".").map(Number);
154
+ for (let i = 0; i < 4; i++) {
155
+ if (aParts[i] > bParts[i])
156
+ return true;
157
+ if (aParts[i] < bParts[i])
158
+ return false;
159
+ }
160
+ return false;
161
+ }
128
162
  // Annotate the CommonJS export names for ESM import in node:
129
163
  0 && (module.exports = {
130
164
  startMcpDaemonServer
@@ -91,6 +91,7 @@ ${c.title}:`);
91
91
  }
92
92
  lines.push("\nGlobal options:");
93
93
  lines.push(formatWithGap(" --config <path>", "create a session with custom config, defaults to `playwright-cli.json`"));
94
+ lines.push(formatWithGap(" --extension", "connect to a running browser instance using Playwright MCP Bridge extension"));
94
95
  lines.push(formatWithGap(" --headed", "create a headed session"));
95
96
  lines.push(formatWithGap(" --help [command]", "print help"));
96
97
  lines.push(formatWithGap(" --session", "run command in the scope of a specific session"));