@smoothdeploy/playwright 1.58.3 → 1.60.0-beta-1780662356000

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 (182) hide show
  1. package/ThirdPartyNotices.txt +8 -5036
  2. package/lib/agents/agentParser.js +2 -2
  3. package/lib/agents/generateAgents.js +21 -22
  4. package/lib/agents/playwright-test-healer.agent.md +1 -0
  5. package/lib/agents/playwright-test-planner.agent.md +2 -1
  6. package/lib/cli/reportActions.js +78 -0
  7. package/lib/cli/testActions.js +211 -0
  8. package/lib/common/index.js +2898 -0
  9. package/lib/common/index.js.txt +35 -0
  10. package/lib/errorContext.js +130 -0
  11. package/lib/index.js +283 -206
  12. package/lib/{isomorphic/testServerConnection.js → isomorphic.js} +70 -35
  13. package/lib/isomorphic.js.txt +9 -0
  14. package/lib/loader/loaderProcessEntry.js +34 -0
  15. package/lib/loader/loaderProcessEntry.js.txt +9 -0
  16. package/lib/matchers/expect.js +12988 -249
  17. package/lib/matchers/expect.js.LICENSE +693 -0
  18. package/lib/matchers/expect.js.txt +72 -0
  19. package/lib/mcp/test/browserBackend.js +49 -22
  20. package/lib/mcp/test/generatorTools.js +16 -16
  21. package/lib/mcp/test/plannerTools.js +25 -20
  22. package/lib/mcp/test/seed.js +7 -7
  23. package/lib/mcp/test/testBackend.js +30 -30
  24. package/lib/mcp/test/testContext.js +50 -33
  25. package/lib/mcp/test/testTools.js +15 -25
  26. package/lib/{internalsForTest.js → package.js} +13 -8
  27. package/lib/program.js +63 -263
  28. package/lib/runner/index.js +8339 -0
  29. package/lib/runner/index.js.txt +60 -0
  30. package/lib/transform/babelBundle.js +71002 -18
  31. package/lib/transform/babelBundle.js.LICENSE +2359 -0
  32. package/lib/transform/babelBundle.js.txt +325 -0
  33. package/lib/transform/esmLoader.js +5884 -30
  34. package/lib/transform/esmLoader.js.LICENSE +335 -0
  35. package/lib/transform/esmLoader.js.txt +55 -0
  36. package/lib/util.js +37 -34
  37. package/lib/worker/workerProcessEntry.js +3251 -0
  38. package/lib/worker/workerProcessEntry.js.txt +24 -0
  39. package/package.json +5 -16
  40. package/test.mjs +1 -0
  41. package/types/test.d.ts +173 -12
  42. package/types/testReporter.d.ts +7 -5
  43. package/lib/common/config.js +0 -282
  44. package/lib/common/configLoader.js +0 -344
  45. package/lib/common/esmLoaderHost.js +0 -104
  46. package/lib/common/expectBundle.js +0 -28
  47. package/lib/common/expectBundleImpl.js +0 -407
  48. package/lib/common/fixtures.js +0 -302
  49. package/lib/common/ipc.js +0 -60
  50. package/lib/common/poolBuilder.js +0 -85
  51. package/lib/common/process.js +0 -132
  52. package/lib/common/suiteUtils.js +0 -140
  53. package/lib/common/test.js +0 -321
  54. package/lib/common/testLoader.js +0 -101
  55. package/lib/common/testType.js +0 -298
  56. package/lib/common/validators.js +0 -68
  57. package/lib/fsWatcher.js +0 -67
  58. package/lib/isomorphic/events.js +0 -77
  59. package/lib/isomorphic/folders.js +0 -30
  60. package/lib/isomorphic/stringInternPool.js +0 -69
  61. package/lib/isomorphic/teleReceiver.js +0 -521
  62. package/lib/isomorphic/teleSuiteUpdater.js +0 -157
  63. package/lib/isomorphic/testServerInterface.js +0 -16
  64. package/lib/isomorphic/testTree.js +0 -329
  65. package/lib/isomorphic/types.d.js +0 -16
  66. package/lib/loader/loaderMain.js +0 -59
  67. package/lib/matchers/matcherHint.js +0 -44
  68. package/lib/matchers/matchers.js +0 -383
  69. package/lib/matchers/toBeTruthy.js +0 -75
  70. package/lib/matchers/toEqual.js +0 -100
  71. package/lib/matchers/toHaveURL.js +0 -101
  72. package/lib/matchers/toMatchAriaSnapshot.js +0 -159
  73. package/lib/matchers/toMatchSnapshot.js +0 -342
  74. package/lib/matchers/toMatchText.js +0 -99
  75. package/lib/mcp/browser/browserContextFactory.js +0 -329
  76. package/lib/mcp/browser/browserServerBackend.js +0 -84
  77. package/lib/mcp/browser/config.js +0 -421
  78. package/lib/mcp/browser/context.js +0 -244
  79. package/lib/mcp/browser/response.js +0 -278
  80. package/lib/mcp/browser/sessionLog.js +0 -75
  81. package/lib/mcp/browser/tab.js +0 -343
  82. package/lib/mcp/browser/tools/common.js +0 -65
  83. package/lib/mcp/browser/tools/console.js +0 -46
  84. package/lib/mcp/browser/tools/dialogs.js +0 -60
  85. package/lib/mcp/browser/tools/evaluate.js +0 -61
  86. package/lib/mcp/browser/tools/files.js +0 -58
  87. package/lib/mcp/browser/tools/form.js +0 -63
  88. package/lib/mcp/browser/tools/install.js +0 -72
  89. package/lib/mcp/browser/tools/keyboard.js +0 -107
  90. package/lib/mcp/browser/tools/mouse.js +0 -107
  91. package/lib/mcp/browser/tools/navigate.js +0 -71
  92. package/lib/mcp/browser/tools/network.js +0 -63
  93. package/lib/mcp/browser/tools/open.js +0 -57
  94. package/lib/mcp/browser/tools/pdf.js +0 -49
  95. package/lib/mcp/browser/tools/runCode.js +0 -78
  96. package/lib/mcp/browser/tools/screenshot.js +0 -93
  97. package/lib/mcp/browser/tools/snapshot.js +0 -173
  98. package/lib/mcp/browser/tools/tabs.js +0 -67
  99. package/lib/mcp/browser/tools/tool.js +0 -47
  100. package/lib/mcp/browser/tools/tracing.js +0 -74
  101. package/lib/mcp/browser/tools/utils.js +0 -94
  102. package/lib/mcp/browser/tools/verify.js +0 -143
  103. package/lib/mcp/browser/tools/wait.js +0 -63
  104. package/lib/mcp/browser/tools.js +0 -84
  105. package/lib/mcp/browser/watchdog.js +0 -44
  106. package/lib/mcp/config.d.js +0 -16
  107. package/lib/mcp/extension/cdpRelay.js +0 -351
  108. package/lib/mcp/extension/extensionContextFactory.js +0 -76
  109. package/lib/mcp/extension/protocol.js +0 -28
  110. package/lib/mcp/index.js +0 -61
  111. package/lib/mcp/log.js +0 -35
  112. package/lib/mcp/program.js +0 -111
  113. package/lib/mcp/sdk/exports.js +0 -28
  114. package/lib/mcp/sdk/http.js +0 -152
  115. package/lib/mcp/sdk/inProcessTransport.js +0 -71
  116. package/lib/mcp/sdk/server.js +0 -223
  117. package/lib/mcp/sdk/tool.js +0 -47
  118. package/lib/mcp/terminal/cli.js +0 -296
  119. package/lib/mcp/terminal/command.js +0 -56
  120. package/lib/mcp/terminal/commands.js +0 -333
  121. package/lib/mcp/terminal/daemon.js +0 -129
  122. package/lib/mcp/terminal/help.json +0 -32
  123. package/lib/mcp/terminal/helpGenerator.js +0 -88
  124. package/lib/mcp/terminal/socketConnection.js +0 -80
  125. package/lib/plugins/gitCommitInfoPlugin.js +0 -198
  126. package/lib/plugins/index.js +0 -28
  127. package/lib/plugins/webServerPlugin.js +0 -237
  128. package/lib/reporters/base.js +0 -634
  129. package/lib/reporters/blob.js +0 -138
  130. package/lib/reporters/dot.js +0 -99
  131. package/lib/reporters/empty.js +0 -32
  132. package/lib/reporters/github.js +0 -128
  133. package/lib/reporters/html.js +0 -633
  134. package/lib/reporters/internalReporter.js +0 -138
  135. package/lib/reporters/json.js +0 -254
  136. package/lib/reporters/junit.js +0 -232
  137. package/lib/reporters/line.js +0 -131
  138. package/lib/reporters/list.js +0 -253
  139. package/lib/reporters/listModeReporter.js +0 -69
  140. package/lib/reporters/markdown.js +0 -144
  141. package/lib/reporters/merge.js +0 -558
  142. package/lib/reporters/multiplexer.js +0 -112
  143. package/lib/reporters/reporterV2.js +0 -102
  144. package/lib/reporters/smoothdeploy.js +0 -333
  145. package/lib/reporters/teleEmitter.js +0 -317
  146. package/lib/reporters/versions/blobV1.js +0 -16
  147. package/lib/runner/dispatcher.js +0 -531
  148. package/lib/runner/failureTracker.js +0 -72
  149. package/lib/runner/lastRun.js +0 -77
  150. package/lib/runner/loadUtils.js +0 -334
  151. package/lib/runner/loaderHost.js +0 -89
  152. package/lib/runner/processHost.js +0 -180
  153. package/lib/runner/projectUtils.js +0 -241
  154. package/lib/runner/rebase.js +0 -189
  155. package/lib/runner/reporters.js +0 -140
  156. package/lib/runner/sigIntWatcher.js +0 -96
  157. package/lib/runner/storage.js +0 -91
  158. package/lib/runner/taskRunner.js +0 -127
  159. package/lib/runner/tasks.js +0 -410
  160. package/lib/runner/testGroups.js +0 -125
  161. package/lib/runner/testRunner.js +0 -398
  162. package/lib/runner/testServer.js +0 -269
  163. package/lib/runner/uiModeReporter.js +0 -30
  164. package/lib/runner/vcs.js +0 -72
  165. package/lib/runner/watchMode.js +0 -396
  166. package/lib/runner/workerHost.js +0 -104
  167. package/lib/third_party/pirates.js +0 -62
  168. package/lib/third_party/tsconfig-loader.js +0 -103
  169. package/lib/transform/babelBundleImpl.js +0 -461
  170. package/lib/transform/compilationCache.js +0 -274
  171. package/lib/transform/md.js +0 -221
  172. package/lib/transform/portTransport.js +0 -67
  173. package/lib/transform/transform.js +0 -303
  174. package/lib/utilsBundle.js +0 -50
  175. package/lib/utilsBundleImpl.js +0 -103
  176. package/lib/worker/fixtureRunner.js +0 -262
  177. package/lib/worker/testInfo.js +0 -536
  178. package/lib/worker/testTracing.js +0 -345
  179. package/lib/worker/timeoutManager.js +0 -174
  180. package/lib/worker/util.js +0 -31
  181. package/lib/worker/workerMain.js +0 -530
  182. /package/lib/{common/globals.js → globals.js} +0 -0
@@ -0,0 +1,72 @@
1
+ # packages/playwright/lib/matchers/expect.js
2
+ # total: 513.7 KB
3
+
4
+ ## Inlined (64)
5
+ 7.9 KB node_modules/@babel/code-frame/lib/index.js
6
+ 12.6 KB node_modules/@babel/helper-validator-identifier/lib/identifier.js
7
+ 1.6 KB node_modules/@babel/helper-validator-identifier/lib/index.js
8
+ 1.7 KB node_modules/@babel/helper-validator-identifier/lib/keyword.js
9
+ 15.9 KB node_modules/@jest/diff-sequences/build/index.js
10
+ 24.9 KB node_modules/@jest/expect-utils/build/index.js
11
+ 0.8 KB node_modules/@jest/expect-utils/build/index.mjs
12
+ 1.8 KB node_modules/@jest/get-type/build/index.js
13
+ 4.8 KB node_modules/ansi-styles/index.js
14
+ 1.9 KB node_modules/braces/index.js
15
+ 1.7 KB node_modules/braces/lib/compile.js
16
+ 2.1 KB node_modules/braces/lib/constants.js
17
+ 3.1 KB node_modules/braces/lib/expand.js
18
+ 7.0 KB node_modules/braces/lib/parse.js
19
+ 0.9 KB node_modules/braces/lib/stringify.js
20
+ 2.4 KB node_modules/braces/lib/utils.js
21
+ 3.1 KB node_modules/chalk/node_modules/supports-color/index.js
22
+ 5.8 KB node_modules/chalk/source/index.js
23
+ 3.9 KB node_modules/chalk/source/templates.js
24
+ 1.3 KB node_modules/chalk/source/util.js
25
+ 18.7 KB node_modules/color-convert/conversions.js
26
+ 1.8 KB node_modules/color-convert/index.js
27
+ 2.1 KB node_modules/color-convert/route.js
28
+ 5.2 KB node_modules/color-name/index.js
29
+ 6.8 KB node_modules/fill-range/index.js
30
+ 0.4 KB node_modules/has-flag/index.js
31
+ 0.4 KB node_modules/is-number/index.js
32
+ 53.2 KB node_modules/jest-diff/build/index.js
33
+ 25.2 KB node_modules/jest-matcher-utils/build/index.js
34
+ 2.7 KB node_modules/jest-matcher-utils/build/index.mjs
35
+ 15.3 KB node_modules/jest-message-util/build/index.js
36
+ 0.5 KB node_modules/jest-message-util/build/index.mjs
37
+ 0.7 KB node_modules/jest-message-util/node_modules/graceful-fs/clone.js
38
+ 12.2 KB node_modules/jest-message-util/node_modules/graceful-fs/graceful-fs.js
39
+ 3.0 KB node_modules/jest-message-util/node_modules/graceful-fs/legacy-streams.js
40
+ 9.3 KB node_modules/jest-message-util/node_modules/graceful-fs/polyfills.js
41
+ 1.4 KB node_modules/js-tokens/index.js
42
+ 5.8 KB node_modules/micromatch/index.js
43
+ 0.2 KB node_modules/micromatch/node_modules/picomatch/index.js
44
+ 5.3 KB node_modules/micromatch/node_modules/picomatch/lib/constants.js
45
+ 33.9 KB node_modules/micromatch/node_modules/picomatch/lib/parse.js
46
+ 5.3 KB node_modules/micromatch/node_modules/picomatch/lib/picomatch.js
47
+ 9.6 KB node_modules/micromatch/node_modules/picomatch/lib/scan.js
48
+ 2.2 KB node_modules/micromatch/node_modules/picomatch/lib/utils.js
49
+ 3.1 KB node_modules/picocolors/picocolors.js
50
+ 42.7 KB node_modules/pretty-format/build/index.js
51
+ 4.4 KB node_modules/pretty-format/node_modules/ansi-styles/index.js
52
+ 7.7 KB node_modules/pretty-format/node_modules/react-is/cjs/react-is.development.js
53
+ 3.3 KB node_modules/pretty-format/node_modules/react-is/cjs/react-is.production.min.js
54
+ 0.3 KB node_modules/pretty-format/node_modules/react-is/index.js
55
+ 0.4 KB node_modules/slash/index.js
56
+ 7.6 KB node_modules/stack-utils/index.js
57
+ 0.4 KB node_modules/stack-utils/node_modules/escape-string-regexp/index.js
58
+ 6.8 KB node_modules/to-regex-range/index.js
59
+ 10.3 KB packages/playwright/src/matchers/expect.ts
60
+ 45.2 KB packages/playwright/src/matchers/expectLibrary.ts
61
+ 3.3 KB packages/playwright/src/matchers/matcherHint.ts
62
+ 16.0 KB packages/playwright/src/matchers/matchers.ts
63
+ 1.3 KB packages/playwright/src/matchers/toBeTruthy.ts
64
+ 2.1 KB packages/playwright/src/matchers/toEqual.ts
65
+ 2.4 KB packages/playwright/src/matchers/toHaveURL.ts
66
+ 5.6 KB packages/playwright/src/matchers/toMatchAriaSnapshot.ts
67
+ 15.1 KB packages/playwright/src/matchers/toMatchSnapshot.ts
68
+ 3.0 KB packages/playwright/src/matchers/toMatchText.ts
69
+
70
+ ## External (2)
71
+ playwright-core/lib/coreBundle
72
+ playwright-core/lib/utilsBundle
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,52 +17,62 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
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
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var browserBackend_exports = {};
20
30
  __export(browserBackend_exports, {
21
- createCustomMessageHandler: () => createCustomMessageHandler
31
+ createCustomMessageHandler: () => createCustomMessageHandler,
32
+ runDaemonForContext: () => runDaemonForContext
22
33
  });
23
34
  module.exports = __toCommonJS(browserBackend_exports);
24
- var import_config = require("../browser/config");
25
- var import_browserServerBackend = require("../browser/browserServerBackend");
26
- var import_tab = require("../browser/tab");
27
- var import_util = require("../../util");
28
- var import_browserContextFactory = require("../browser/browserContextFactory");
35
+ var import_crypto = __toESM(require("crypto"));
36
+ const { stripAnsiEscapes } = require("playwright-core/lib/coreBundle").iso;
29
37
  function createCustomMessageHandler(testInfo, context) {
30
38
  let backend;
39
+ const config = { capabilities: ["testing"] };
40
+ let tools;
41
+ context.once("close", () => {
42
+ void backend?.dispose();
43
+ backend = void 0;
44
+ });
31
45
  return async (data) => {
46
+ if (!tools)
47
+ ({ tools } = require("playwright-core/lib/coreBundle"));
48
+ const toolList = tools.filteredTools(config);
32
49
  if (data.initialize) {
33
50
  if (backend)
34
51
  throw new Error("MCP backend is already initialized");
35
- backend = new import_browserServerBackend.BrowserServerBackend({ ...import_config.defaultConfig, capabilities: ["testing"] }, (0, import_browserContextFactory.identityBrowserContextFactory)(context));
52
+ backend = new tools.BrowserBackend(config, context, toolList);
36
53
  await backend.initialize(data.initialize.clientInfo);
37
- const pausedMessage = await generatePausedMessage(testInfo, context);
54
+ const pausedMessage = await generatePausedMessage(tools, testInfo, context);
38
55
  return { initialize: { pausedMessage } };
39
56
  }
40
- if (data.listTools) {
41
- if (!backend)
42
- throw new Error("MCP backend is not initialized");
43
- return { listTools: await backend.listTools() };
44
- }
45
57
  if (data.callTool) {
46
58
  if (!backend)
47
59
  throw new Error("MCP backend is not initialized");
48
60
  return { callTool: await backend.callTool(data.callTool.name, data.callTool.arguments) };
49
61
  }
50
62
  if (data.close) {
51
- backend?.serverClosed();
63
+ await backend?.dispose();
52
64
  backend = void 0;
53
65
  return { close: {} };
54
66
  }
55
67
  throw new Error("Unknown MCP request");
56
68
  };
57
69
  }
58
- async function generatePausedMessage(testInfo, context) {
70
+ async function generatePausedMessage(tools, testInfo, context) {
59
71
  const lines = [];
60
72
  if (testInfo.errors.length) {
61
73
  lines.push(`### Paused on error:`);
62
74
  for (const error of testInfo.errors)
63
- lines.push((0, import_util.stripAnsiEscapes)(error.message || ""));
75
+ lines.push(stripAnsiEscapes(error.message || ""));
64
76
  } else {
65
77
  lines.push(`### Paused at end of test. ready for interaction`);
66
78
  }
@@ -73,17 +85,17 @@ async function generatePausedMessage(testInfo, context) {
73
85
  `- Page URL: ${page.url()}`,
74
86
  `- Page Title: ${await page.title()}`.trim()
75
87
  );
76
- let console = testInfo.errors.length ? await import_tab.Tab.collectConsoleMessages(page) : [];
77
- console = console.filter((msg) => msg.type === "error");
78
- if (console.length) {
88
+ let console2 = testInfo.errors.length ? await tools.Tab.collectConsoleMessages(page) : [];
89
+ console2 = console2.filter((msg) => msg.type === "error");
90
+ if (console2.length) {
79
91
  lines.push("- Console Messages:");
80
- for (const message of console)
92
+ for (const message of console2)
81
93
  lines.push(` - ${message.toString()}`);
82
94
  }
83
95
  lines.push(
84
96
  `- Page Snapshot:`,
85
97
  "```yaml",
86
- (await page._snapshotForAI()).full,
98
+ await page.ariaSnapshot({ mode: "ai" }),
87
99
  "```"
88
100
  );
89
101
  }
@@ -92,7 +104,22 @@ async function generatePausedMessage(testInfo, context) {
92
104
  lines.push(`### Task`, `Try recovering from the error prior to continuing`);
93
105
  return lines.join("\n");
94
106
  }
107
+ async function runDaemonForContext(testInfo, context) {
108
+ if (testInfo._configInternal.configCLIOverrides.debug !== "cli")
109
+ return false;
110
+ const sessionName = `tw-${import_crypto.default.randomBytes(3).toString("hex")}`;
111
+ await context.browser().bind(sessionName, { workspaceDir: testInfo.project.testDir });
112
+ console.log([
113
+ `### The test is currently paused at the start`,
114
+ ``,
115
+ `### Debugging Instructions`,
116
+ `- Run "playwright-cli attach ${sessionName}" to attach to this test`
117
+ ].join("\n"));
118
+ await context.debugger.requestPause();
119
+ return true;
120
+ }
95
121
  // Annotate the CommonJS export names for ESM import in node:
96
122
  0 && (module.exports = {
97
- createCustomMessageHandler
123
+ createCustomMessageHandler,
124
+ runDaemonForContext
98
125
  });
@@ -35,25 +35,26 @@ __export(generatorTools_exports, {
35
35
  module.exports = __toCommonJS(generatorTools_exports);
36
36
  var import_fs = __toESM(require("fs"));
37
37
  var import_path = __toESM(require("path"));
38
- var import_mcpBundle = require("playwright-core/lib/mcpBundle");
39
38
  var import_testTool = require("./testTool");
40
39
  var import_testContext = require("./testContext");
40
+ const z = require("playwright-core/lib/utilsBundle").z;
41
+ const { isPathInside, resolveWithinRoot } = require("playwright-core/lib/coreBundle").utils;
41
42
  const setupPage = (0, import_testTool.defineTestTool)({
42
43
  schema: {
43
44
  name: "generator_setup_page",
44
45
  title: "Setup generator page",
45
46
  description: "Setup the page for test.",
46
- inputSchema: import_mcpBundle.z.object({
47
- plan: import_mcpBundle.z.string().describe("The plan for the test. This should be the actual test plan with all the steps."),
48
- project: import_mcpBundle.z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
49
- seedFile: import_mcpBundle.z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
47
+ inputSchema: z.object({
48
+ plan: z.string().describe("The plan for the test. This should be the actual test plan with all the steps."),
49
+ project: z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
50
+ seedFile: z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
50
51
  }),
51
52
  type: "readOnly"
52
53
  },
53
- handle: async (context, params) => {
54
+ handle: async (context, params, signal) => {
54
55
  const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
55
56
  context.generatorJournal = new import_testContext.GeneratorJournal(context.rootPath, params.plan, seed);
56
- const { output, status } = await context.runSeedTest(seed.file, seed.projectName);
57
+ const { output, status } = await context.runSeedTest(seed.file, seed.projectName, signal);
57
58
  return { content: [{ type: "text", text: output }], isError: status !== "paused" };
58
59
  }
59
60
  });
@@ -62,7 +63,7 @@ const generatorReadLog = (0, import_testTool.defineTestTool)({
62
63
  name: "generator_read_log",
63
64
  title: "Retrieve test log",
64
65
  description: "Retrieve the performed test log",
65
- inputSchema: import_mcpBundle.z.object({}),
66
+ inputSchema: z.object({}),
66
67
  type: "readOnly"
67
68
  },
68
69
  handle: async (context) => {
@@ -80,9 +81,9 @@ const generatorWriteTest = (0, import_testTool.defineTestTool)({
80
81
  name: "generator_write_test",
81
82
  title: "Write test",
82
83
  description: "Write the generated test to the test file",
83
- inputSchema: import_mcpBundle.z.object({
84
- fileName: import_mcpBundle.z.string().describe("The file to write the test to"),
85
- code: import_mcpBundle.z.string().describe("The generated test code")
84
+ inputSchema: z.object({
85
+ fileName: z.string().describe("The file to write the test to"),
86
+ code: z.string().describe("The generated test code")
86
87
  }),
87
88
  type: "readOnly"
88
89
  },
@@ -93,12 +94,11 @@ const generatorWriteTest = (0, import_testTool.defineTestTool)({
93
94
  if (!testRunner)
94
95
  throw new Error("No test runner found, please setup page and perform actions first.");
95
96
  const config = await testRunner.loadConfig();
97
+ const resolvedFile = resolveWithinRoot(context.rootPath, params.fileName);
96
98
  const dirs = [];
97
99
  for (const project of config.projects) {
98
- const testDir = import_path.default.relative(context.rootPath, project.project.testDir).replace(/\\/g, "/");
99
- const fileName = params.fileName.replace(/\\/g, "/");
100
- if (fileName.startsWith(testDir)) {
101
- const resolvedFile = import_path.default.resolve(context.rootPath, fileName);
100
+ const projectTestDir = project.project.testDir;
101
+ if (resolvedFile && isPathInside(projectTestDir, resolvedFile)) {
102
102
  await import_fs.default.promises.mkdir(import_path.default.dirname(resolvedFile), { recursive: true });
103
103
  await import_fs.default.promises.writeFile(resolvedFile, params.code);
104
104
  return {
@@ -109,7 +109,7 @@ Test written to ${params.fileName}`
109
109
  }]
110
110
  };
111
111
  }
112
- dirs.push(testDir);
112
+ dirs.push(import_path.default.relative(context.rootPath, projectTestDir).replace(/\\/g, "/"));
113
113
  }
114
114
  throw new Error(`Test file did not match any of the test dirs: ${dirs.join(", ")}`);
115
115
  }
@@ -35,36 +35,37 @@ __export(plannerTools_exports, {
35
35
  module.exports = __toCommonJS(plannerTools_exports);
36
36
  var import_fs = __toESM(require("fs"));
37
37
  var import_path = __toESM(require("path"));
38
- var import_mcpBundle = require("playwright-core/lib/mcpBundle");
39
38
  var import_testTool = require("./testTool");
39
+ const z = require("playwright-core/lib/utilsBundle").z;
40
+ const { resolveWithinRoot } = require("playwright-core/lib/coreBundle").utils;
40
41
  const setupPage = (0, import_testTool.defineTestTool)({
41
42
  schema: {
42
43
  name: "planner_setup_page",
43
44
  title: "Setup planner page",
44
45
  description: "Setup the page for test planning",
45
- inputSchema: import_mcpBundle.z.object({
46
- project: import_mcpBundle.z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
47
- seedFile: import_mcpBundle.z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
46
+ inputSchema: z.object({
47
+ project: z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
48
+ seedFile: z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
48
49
  }),
49
50
  type: "readOnly"
50
51
  },
51
- handle: async (context, params) => {
52
+ handle: async (context, params, signal) => {
52
53
  const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
53
- const { output, status } = await context.runSeedTest(seed.file, seed.projectName);
54
+ const { output, status } = await context.runSeedTest(seed.file, seed.projectName, signal);
54
55
  return { content: [{ type: "text", text: output }], isError: status !== "paused" };
55
56
  }
56
57
  });
57
- const planSchema = import_mcpBundle.z.object({
58
- overview: import_mcpBundle.z.string().describe("A brief overview of the application to be tested"),
59
- suites: import_mcpBundle.z.array(import_mcpBundle.z.object({
60
- name: import_mcpBundle.z.string().describe("The name of the suite"),
61
- seedFile: import_mcpBundle.z.string().describe("A seed file that was used to setup the page for testing."),
62
- tests: import_mcpBundle.z.array(import_mcpBundle.z.object({
63
- name: import_mcpBundle.z.string().describe("The name of the test"),
64
- file: import_mcpBundle.z.string().describe('The file the test should be saved to, for example: "tests/<suite-name>/<test-name>.spec.ts".'),
65
- steps: import_mcpBundle.z.array(import_mcpBundle.z.object({
66
- perform: import_mcpBundle.z.string().optional().describe(`Action to perform. For example: 'Click on the "Submit" button'.`),
67
- expect: import_mcpBundle.z.string().array().describe(`Expected result of the action where appropriate. For example: 'The page should show the "Thank you for your submission" message'`)
58
+ const planSchema = z.object({
59
+ overview: z.string().describe("A brief overview of the application to be tested"),
60
+ suites: z.array(z.object({
61
+ name: z.string().describe("The name of the suite"),
62
+ seedFile: z.string().describe("A seed file that was used to setup the page for testing."),
63
+ tests: z.array(z.object({
64
+ name: z.string().describe("The name of the test"),
65
+ file: z.string().describe('The file the test should be saved to, for example: "tests/<suite-name>/<test-name>.spec.ts".'),
66
+ steps: z.array(z.object({
67
+ perform: z.string().optional().describe(`Action to perform. For example: 'Click on the "Submit" button'.`),
68
+ expect: z.string().array().describe(`Expected result of the action where appropriate. For example: 'The page should show the "Thank you for your submission" message'`)
68
69
  }))
69
70
  }))
70
71
  }))
@@ -92,8 +93,8 @@ const saveTestPlan = (0, import_testTool.defineTestTool)({
92
93
  title: "Save test plan as markdown file",
93
94
  description: "Save the test plan as a markdown file",
94
95
  inputSchema: planSchema.extend({
95
- name: import_mcpBundle.z.string().describe('The name of the test plan, for example: "Test Plan".'),
96
- fileName: import_mcpBundle.z.string().describe('The file to save the test plan to, for example: "spec/test.plan.md". Relative to the workspace root.')
96
+ name: z.string().describe('The name of the test plan, for example: "Test Plan".'),
97
+ fileName: z.string().describe('The file to save the test plan to, for example: "spec/test.plan.md". Relative to the workspace root.')
97
98
  }),
98
99
  type: "readOnly"
99
100
  },
@@ -128,7 +129,11 @@ const saveTestPlan = (0, import_testTool.defineTestTool)({
128
129
  }
129
130
  }
130
131
  lines.push(``);
131
- await import_fs.default.promises.writeFile(import_path.default.resolve(context.rootPath, params.fileName), lines.join("\n"));
132
+ const resolvedFile = resolveWithinRoot(context.rootPath, params.fileName);
133
+ if (!resolvedFile)
134
+ throw new Error(`Plan file name must be a relative path inside the workspace: ${params.fileName}`);
135
+ await import_fs.default.promises.mkdir(import_path.default.dirname(resolvedFile), { recursive: true });
136
+ await import_fs.default.promises.writeFile(resolvedFile, lines.join("\n"));
132
137
  return {
133
138
  content: [{
134
139
  type: "text",
@@ -37,18 +37,18 @@ __export(seed_exports, {
37
37
  module.exports = __toCommonJS(seed_exports);
38
38
  var import_fs = __toESM(require("fs"));
39
39
  var import_path = __toESM(require("path"));
40
- var import_utils = require("playwright-core/lib/utils");
41
- var import_projectUtils = require("../../runner/projectUtils");
42
- function seedProject(config, projectName) {
40
+ var import_runner = require("../../runner");
41
+ const { mkdirIfNeeded } = require("playwright-core/lib/coreBundle").utils;
42
+ function seedProject(fullConfig, projectName) {
43
43
  if (!projectName)
44
- return (0, import_projectUtils.findTopLevelProjects)(config)[0];
45
- const project = config.projects.find((p) => p.project.name === projectName);
44
+ return import_runner.projectUtils.findTopLevelProjects(fullConfig)[0];
45
+ const project = fullConfig.projects.find((p) => p.project.name === projectName);
46
46
  if (!project)
47
47
  throw new Error(`Project ${projectName} not found`);
48
48
  return project;
49
49
  }
50
50
  async function findSeedFile(project) {
51
- const files = await (0, import_projectUtils.collectFilesForProject)(project);
51
+ const files = await import_runner.projectUtils.collectFilesForProject(project);
52
52
  return files.find((file) => import_path.default.basename(file).includes("seed"));
53
53
  }
54
54
  function defaultSeedFile(project) {
@@ -60,7 +60,7 @@ async function ensureSeedFile(project) {
60
60
  if (seedFile)
61
61
  return seedFile;
62
62
  const seedFilePath = defaultSeedFile(project);
63
- await (0, import_utils.mkdirIfNeeded)(seedFilePath);
63
+ await mkdirIfNeeded(seedFilePath);
64
64
  await import_fs.default.promises.writeFile(seedFilePath, seedFileContent);
65
65
  return seedFilePath;
66
66
  }
@@ -28,66 +28,65 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var testBackend_exports = {};
30
30
  __export(testBackend_exports, {
31
- TestServerBackend: () => TestServerBackend
31
+ TestServerBackend: () => TestServerBackend,
32
+ testServerBackendTools: () => testServerBackendTools
32
33
  });
33
34
  module.exports = __toCommonJS(testBackend_exports);
34
- var import_mcpBundle = require("playwright-core/lib/mcpBundle");
35
- var mcp = __toESM(require("../sdk/exports"));
35
+ var import_events = __toESM(require("events"));
36
+ var import_coreBundle = require("playwright-core/lib/coreBundle");
36
37
  var import_testContext = require("./testContext");
37
38
  var testTools = __toESM(require("./testTools.js"));
38
39
  var generatorTools = __toESM(require("./generatorTools.js"));
39
40
  var plannerTools = __toESM(require("./plannerTools.js"));
40
- var import_tools = require("../browser/tools");
41
- class TestServerBackend {
41
+ const zod = require("playwright-core/lib/utilsBundle").z;
42
+ const typesWithIntent = ["action", "assertion", "input"];
43
+ const testServerBackendTools = [
44
+ plannerTools.saveTestPlan,
45
+ plannerTools.setupPage,
46
+ plannerTools.submitTestPlan,
47
+ generatorTools.setupPage,
48
+ generatorTools.generatorReadLog,
49
+ generatorTools.generatorWriteTest,
50
+ testTools.listTests,
51
+ testTools.runTests,
52
+ testTools.debugTest,
53
+ ...import_coreBundle.tools.browserTools.map((tool) => wrapBrowserTool(tool))
54
+ ];
55
+ class TestServerBackend extends import_events.default {
42
56
  constructor(configPath, options) {
57
+ super();
43
58
  this.name = "Playwright";
44
59
  this.version = "0.0.1";
45
- this._tools = [
46
- plannerTools.saveTestPlan,
47
- plannerTools.setupPage,
48
- plannerTools.submitTestPlan,
49
- generatorTools.setupPage,
50
- generatorTools.generatorReadLog,
51
- generatorTools.generatorWriteTest,
52
- testTools.listTests,
53
- testTools.runTests,
54
- testTools.debugTest,
55
- ...import_tools.browserTools.map((tool) => wrapBrowserTool(tool))
56
- ];
57
60
  this._options = options || {};
58
61
  this._configPath = configPath;
59
62
  }
60
63
  async initialize(clientInfo) {
61
64
  this._context = new import_testContext.TestContext(clientInfo, this._configPath, this._options);
62
65
  }
63
- async listTools() {
64
- return this._tools.map((tool) => mcp.toMcpTool(tool.schema));
65
- }
66
- async callTool(name, args) {
67
- const tool = this._tools.find((tool2) => tool2.schema.name === name);
66
+ async callTool(name, args, signal) {
67
+ const tool = testServerBackendTools.find((tool2) => tool2.schema.name === name);
68
68
  if (!tool)
69
- throw new Error(`Tool not found: ${name}. Available tools: ${this._tools.map((tool2) => tool2.schema.name).join(", ")}`);
69
+ throw new Error(`Tool not found: ${name}. Available tools: ${testServerBackendTools.map((tool2) => tool2.schema.name).join(", ")}`);
70
70
  try {
71
- return await tool.handle(this._context, tool.schema.inputSchema.parse(args || {}));
71
+ return await tool.handle(this._context, tool.schema.inputSchema.parse(args || {}), signal);
72
72
  } catch (e) {
73
73
  return { content: [{ type: "text", text: String(e) }], isError: true };
74
74
  }
75
75
  }
76
- serverClosed() {
77
- void this._context?.close();
76
+ async dispose() {
77
+ await this._context?.close();
78
78
  }
79
79
  }
80
- const typesWithIntent = ["action", "assertion", "input"];
81
80
  function wrapBrowserTool(tool) {
82
81
  const inputSchema = typesWithIntent.includes(tool.schema.type) ? tool.schema.inputSchema.extend({
83
- intent: import_mcpBundle.z.string().describe("The intent of the call, for example the test step description plan idea")
82
+ intent: zod.string().describe("The intent of the call, for example the test step description plan idea")
84
83
  }) : tool.schema.inputSchema;
85
84
  return {
86
85
  schema: {
87
86
  ...tool.schema,
88
87
  inputSchema
89
88
  },
90
- handle: async (context, params) => {
89
+ handle: async (context, params, _signal) => {
91
90
  const response = await context.sendMessageToPausedTest({ callTool: { name: tool.schema.name, arguments: params } });
92
91
  return response.callTool;
93
92
  }
@@ -95,5 +94,6 @@ function wrapBrowserTool(tool) {
95
94
  }
96
95
  // Annotate the CommonJS export names for ESM import in node:
97
96
  0 && (module.exports = {
98
- TestServerBackend
97
+ TestServerBackend,
98
+ testServerBackendTools
99
99
  });