@cotestdev/mcp_playwright 0.0.14 → 0.0.16

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.
Files changed (49) hide show
  1. package/lib/mcp/browser/browserContextFactory.js +49 -13
  2. package/lib/mcp/browser/browserServerBackend.js +5 -2
  3. package/lib/mcp/browser/config.js +95 -23
  4. package/lib/mcp/browser/context.js +28 -3
  5. package/lib/mcp/browser/response.js +240 -57
  6. package/lib/mcp/browser/sessionLog.js +1 -1
  7. package/lib/mcp/browser/tab.js +96 -69
  8. package/lib/mcp/browser/tools/common.js +8 -8
  9. package/lib/mcp/browser/tools/console.js +6 -3
  10. package/lib/mcp/browser/tools/dialogs.js +13 -13
  11. package/lib/mcp/browser/tools/evaluate.js +9 -20
  12. package/lib/mcp/browser/tools/files.js +10 -5
  13. package/lib/mcp/browser/tools/form.js +11 -22
  14. package/lib/mcp/browser/tools/install.js +3 -3
  15. package/lib/mcp/browser/tools/keyboard.js +12 -12
  16. package/lib/mcp/browser/tools/mouse.js +14 -14
  17. package/lib/mcp/browser/tools/navigate.js +5 -5
  18. package/lib/mcp/browser/tools/network.js +16 -5
  19. package/lib/mcp/browser/tools/pdf.js +7 -18
  20. package/lib/mcp/browser/tools/runCode.js +77 -0
  21. package/lib/mcp/browser/tools/screenshot.js +44 -33
  22. package/lib/mcp/browser/tools/snapshot.js +42 -33
  23. package/lib/mcp/browser/tools/tabs.js +7 -10
  24. package/lib/mcp/browser/tools/tool.js +8 -7
  25. package/lib/mcp/browser/tools/tracing.js +4 -4
  26. package/lib/mcp/browser/tools/utils.js +50 -52
  27. package/lib/mcp/browser/tools/verify.js +23 -34
  28. package/lib/mcp/browser/tools/wait.js +6 -6
  29. package/lib/mcp/browser/tools.js +4 -3
  30. package/lib/mcp/extension/cdpRelay.js +1 -1
  31. package/lib/mcp/extension/extensionContextFactory.js +4 -3
  32. package/lib/mcp/log.js +2 -2
  33. package/lib/mcp/program.js +21 -29
  34. package/lib/mcp/sdk/exports.js +1 -5
  35. package/lib/mcp/sdk/http.js +37 -50
  36. package/lib/mcp/sdk/server.js +61 -9
  37. package/lib/mcp/sdk/tool.js +5 -4
  38. package/lib/mcp/test/browserBackend.js +67 -61
  39. package/lib/mcp/test/generatorTools.js +122 -0
  40. package/lib/mcp/test/plannerTools.js +144 -0
  41. package/lib/mcp/test/seed.js +82 -0
  42. package/lib/mcp/test/streams.js +10 -7
  43. package/lib/mcp/test/testBackend.js +44 -24
  44. package/lib/mcp/test/testContext.js +243 -14
  45. package/lib/mcp/test/testTools.js +23 -109
  46. package/lib/mcpBundle.js +84 -0
  47. package/lib/mcpBundleImpl/index.js +130 -0
  48. package/lib/util.js +12 -6
  49. package/package.json +1 -1
@@ -30,36 +30,25 @@ var testTools_exports = {};
30
30
  __export(testTools_exports, {
31
31
  debugTest: () => debugTest,
32
32
  listTests: () => listTests,
33
- runTests: () => runTests,
34
- setupPage: () => setupPage
33
+ runTests: () => runTests
35
34
  });
36
35
  module.exports = __toCommonJS(testTools_exports);
37
- var import_fs = __toESM(require("fs"));
38
- var import_path = __toESM(require("path"));
39
- var import_utils = require("playwright-core/lib/utils");
40
- var import_bundle = require("../sdk/bundle");
41
- var import_base = require("../../reporters/base");
42
- var import_list = __toESM(require("../../reporters/list"));
36
+ var import_mcpBundle = require("../../mcpBundleImpl");
43
37
  var import_listModeReporter = __toESM(require("../../reporters/listModeReporter"));
44
- var import_projectUtils = require("../../runner/projectUtils");
45
38
  var import_testTool = require("./testTool");
46
- var import_streams = require("./streams");
47
39
  const listTests = (0, import_testTool.defineTestTool)({
48
40
  schema: {
49
41
  name: "test_list",
50
42
  title: "List tests",
51
43
  description: "List tests",
52
- inputSchema: import_bundle.z.object({}),
44
+ inputSchema: import_mcpBundle.z.object({}),
53
45
  type: "readOnly"
54
46
  },
55
47
  handle: async (context) => {
56
- const { screen, stream } = createScreen();
48
+ const { testRunner, screen, output } = await context.createTestRunner();
57
49
  const reporter = new import_listModeReporter.default({ screen, includeTestId: true });
58
- const testRunner = await context.createTestRunner();
59
50
  await testRunner.listTests(reporter, {});
60
- return {
61
- content: [{ type: "text", text: stream.content() }]
62
- };
51
+ return { content: output.map((text) => ({ type: "text", text })) };
63
52
  }
64
53
  });
65
54
  const runTests = (0, import_testTool.defineTestTool)({
@@ -67,28 +56,19 @@ const runTests = (0, import_testTool.defineTestTool)({
67
56
  name: "test_run",
68
57
  title: "Run tests",
69
58
  description: "Run tests",
70
- inputSchema: import_bundle.z.object({
71
- locations: import_bundle.z.array(import_bundle.z.string()).optional().describe('Folder, file or location to run: "test/e2e" or "test/e2e/file.spec.ts" or "test/e2e/file.spec.ts:20"'),
72
- projects: import_bundle.z.array(import_bundle.z.string()).optional().describe('Projects to run, projects from playwright.config.ts, by default runs all projects. Running with "chromium" is a good start')
59
+ inputSchema: import_mcpBundle.z.object({
60
+ locations: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe('Folder, file or location to run: "test/e2e" or "test/e2e/file.spec.ts" or "test/e2e/file.spec.ts:20"'),
61
+ projects: import_mcpBundle.z.array(import_mcpBundle.z.string()).optional().describe('Projects to run, projects from playwright.config.ts, by default runs all projects. Running with "chromium" is a good start')
73
62
  }),
74
63
  type: "readOnly"
75
64
  },
76
65
  handle: async (context, params) => {
77
- const { screen, stream } = createScreen();
78
- const configDir = context.configLocation.configDir;
79
- const reporter = new import_list.default({ configDir, screen, includeTestId: true });
80
- const testRunner = await context.createTestRunner();
81
- await testRunner.runTests(reporter, {
82
- locations: params.locations,
66
+ const { output } = await context.runTestsWithGlobalSetupAndPossiblePause({
67
+ locations: params.locations ?? [],
83
68
  projects: params.projects,
84
69
  disableConfigReporters: true
85
70
  });
86
- const text = stream.content();
87
- return {
88
- content: [
89
- { type: "text", text }
90
- ]
91
- };
71
+ return { content: [{ type: "text", text: output }] };
92
72
  }
93
73
  });
94
74
  const debugTest = (0, import_testTool.defineTestTool)({
@@ -96,99 +76,33 @@ const debugTest = (0, import_testTool.defineTestTool)({
96
76
  name: "test_debug",
97
77
  title: "Debug single test",
98
78
  description: "Debug single test",
99
- inputSchema: import_bundle.z.object({
100
- test: import_bundle.z.object({
101
- id: import_bundle.z.string().describe("Test ID to debug."),
102
- title: import_bundle.z.string().describe("Human readable test title for granting permission to debug the test.")
79
+ inputSchema: import_mcpBundle.z.object({
80
+ test: import_mcpBundle.z.object({
81
+ id: import_mcpBundle.z.string().describe("Test ID to debug."),
82
+ title: import_mcpBundle.z.string().describe("Human readable test title for granting permission to debug the test.")
103
83
  })
104
84
  }),
105
85
  type: "readOnly"
106
86
  },
107
87
  handle: async (context, params) => {
108
- const { screen, stream } = createScreen();
109
- const configDir = context.configLocation.configDir;
110
- const reporter = new import_list.default({ configDir, screen });
111
- const testRunner = await context.createTestRunner();
112
- const result = await testRunner.runTests(reporter, {
113
- headed: !context.options?.headless,
88
+ const { output, status } = await context.runTestsWithGlobalSetupAndPossiblePause({
89
+ headed: context.computedHeaded,
90
+ locations: [],
91
+ // we can make this faster by passing the test's location, so we don't need to scan all tests to find the ID
114
92
  testIds: [params.test.id],
115
93
  // For automatic recovery
116
94
  timeout: 0,
117
95
  workers: 1,
118
96
  pauseOnError: true,
119
- disableConfigReporters: true
120
- });
121
- const text = stream.content();
122
- return {
123
- content: [
124
- { type: "text", text }
125
- ],
126
- isError: result.status !== "passed"
127
- };
128
- }
129
- });
130
- const setupPage = (0, import_testTool.defineTestTool)({
131
- schema: {
132
- name: "test_setup_page",
133
- title: "Setup page",
134
- description: "Setup the page for test",
135
- inputSchema: import_bundle.z.object({
136
- project: import_bundle.z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
137
- testLocation: import_bundle.z.string().optional().describe('Location of the seed test to use for setup. For example: "test/seed/default.spec.ts:20".')
138
- }),
139
- type: "readOnly"
140
- },
141
- handle: async (context, params) => {
142
- const { screen, stream } = createScreen();
143
- const configDir = context.configLocation.configDir;
144
- const reporter = new import_list.default({ configDir, screen });
145
- const testRunner = await context.createTestRunner();
146
- let testLocation = params.testLocation;
147
- if (!testLocation) {
148
- testLocation = "default.seed.spec.ts";
149
- const config = await testRunner.loadConfig();
150
- const project = params.project ? config.projects.find((p) => p.project.name === params.project) : (0, import_projectUtils.findTopLevelProjects)(config)[0];
151
- const testDir = project?.project.testDir || configDir;
152
- const seedFile = import_path.default.join(testDir, testLocation);
153
- if (!import_fs.default.existsSync(seedFile)) {
154
- await import_fs.default.promises.mkdir(import_path.default.dirname(seedFile), { recursive: true });
155
- await import_fs.default.promises.writeFile(seedFile, `import { test, expect } from '@playwright/test';
156
-
157
- test('seed', async ({ page }) => {});
158
- `);
159
- }
160
- }
161
- const result = await testRunner.runTests(reporter, {
162
- headed: !context.options?.headless,
163
- locations: [testLocation],
164
- projects: params.project ? [params.project] : void 0,
165
- timeout: 0,
166
- workers: 1,
167
- pauseAtEnd: true,
168
- disableConfigReporters: true
97
+ disableConfigReporters: true,
98
+ actionTimeout: 5e3
169
99
  });
170
- const text = stream.content();
171
- return {
172
- content: [{ type: "text", text }],
173
- isError: result.status !== "passed"
174
- };
100
+ return { content: [{ type: "text", text: output }], isError: status !== "paused" && status !== "passed" };
175
101
  }
176
102
  });
177
- function createScreen() {
178
- const stream = new import_streams.StringWriteStream();
179
- const screen = {
180
- ...import_base.terminalScreen,
181
- isTTY: false,
182
- colors: import_utils.noColors,
183
- stdout: stream,
184
- stderr: stream
185
- };
186
- return { screen, stream };
187
- }
188
103
  // Annotate the CommonJS export names for ESM import in node:
189
104
  0 && (module.exports = {
190
105
  debugTest,
191
106
  listTests,
192
- runTests,
193
- setupPage
107
+ runTests
194
108
  });
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var mcpBundle_exports = {};
30
+ __export(mcpBundle_exports, {
31
+ CallToolRequestSchema: () => CallToolRequestSchema,
32
+ Client: () => Client,
33
+ ListRootsRequestSchema: () => ListRootsRequestSchema,
34
+ ListToolsRequestSchema: () => ListToolsRequestSchema,
35
+ Loop: () => Loop,
36
+ PingRequestSchema: () => PingRequestSchema,
37
+ ProgressNotificationSchema: () => ProgressNotificationSchema,
38
+ SSEClientTransport: () => SSEClientTransport,
39
+ SSEServerTransport: () => SSEServerTransport,
40
+ Server: () => Server,
41
+ StdioClientTransport: () => StdioClientTransport,
42
+ StdioServerTransport: () => StdioServerTransport,
43
+ StreamableHTTPClientTransport: () => StreamableHTTPClientTransport,
44
+ StreamableHTTPServerTransport: () => StreamableHTTPServerTransport,
45
+ z: () => z,
46
+ zodToJsonSchema: () => zodToJsonSchema
47
+ });
48
+ module.exports = __toCommonJS(mcpBundle_exports);
49
+ var bundle = __toESM(require("./mcpBundleImpl"));
50
+ const zodToJsonSchema = bundle.zodToJsonSchema;
51
+ const Client = bundle.Client;
52
+ const Server = bundle.Server;
53
+ const SSEClientTransport = bundle.SSEClientTransport;
54
+ const SSEServerTransport = bundle.SSEServerTransport;
55
+ const StdioClientTransport = bundle.StdioClientTransport;
56
+ const StdioServerTransport = bundle.StdioServerTransport;
57
+ const StreamableHTTPServerTransport = bundle.StreamableHTTPServerTransport;
58
+ const StreamableHTTPClientTransport = bundle.StreamableHTTPClientTransport;
59
+ const CallToolRequestSchema = bundle.CallToolRequestSchema;
60
+ const ListRootsRequestSchema = bundle.ListRootsRequestSchema;
61
+ const ProgressNotificationSchema = bundle.ProgressNotificationSchema;
62
+ const ListToolsRequestSchema = bundle.ListToolsRequestSchema;
63
+ const PingRequestSchema = bundle.PingRequestSchema;
64
+ const Loop = bundle.Loop;
65
+ const z = bundle.z;
66
+ // Annotate the CommonJS export names for ESM import in node:
67
+ 0 && (module.exports = {
68
+ CallToolRequestSchema,
69
+ Client,
70
+ ListRootsRequestSchema,
71
+ ListToolsRequestSchema,
72
+ Loop,
73
+ PingRequestSchema,
74
+ ProgressNotificationSchema,
75
+ SSEClientTransport,
76
+ SSEServerTransport,
77
+ Server,
78
+ StdioClientTransport,
79
+ StdioServerTransport,
80
+ StreamableHTTPClientTransport,
81
+ StreamableHTTPServerTransport,
82
+ z,
83
+ zodToJsonSchema
84
+ });