@smoothdeploy/playwright 1.58.4 → 1.60.1
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.
- package/ThirdPartyNotices.txt +8 -5036
- package/lib/agents/agentParser.js +2 -2
- package/lib/agents/generateAgents.js +21 -22
- package/lib/agents/playwright-test-healer.agent.md +1 -0
- package/lib/agents/playwright-test-planner.agent.md +2 -1
- package/lib/cli/reportActions.js +78 -0
- package/lib/cli/testActions.js +211 -0
- package/lib/common/index.js +2898 -0
- package/lib/common/index.js.txt +35 -0
- package/lib/errorContext.js +130 -0
- package/lib/index.js +258 -206
- package/lib/{isomorphic/testServerConnection.js → isomorphic.js} +70 -35
- package/lib/isomorphic.js.txt +9 -0
- package/lib/loader/loaderProcessEntry.js +34 -0
- package/lib/loader/loaderProcessEntry.js.txt +9 -0
- package/lib/matchers/expect.js +12988 -249
- package/lib/matchers/expect.js.LICENSE +693 -0
- package/lib/matchers/expect.js.txt +72 -0
- package/lib/mcp/test/browserBackend.js +49 -22
- package/lib/mcp/test/generatorTools.js +16 -16
- package/lib/mcp/test/plannerTools.js +25 -20
- package/lib/mcp/test/seed.js +7 -7
- package/lib/mcp/test/testBackend.js +30 -30
- package/lib/mcp/test/testContext.js +50 -33
- package/lib/mcp/test/testTools.js +15 -25
- package/lib/{internalsForTest.js → package.js} +13 -8
- package/lib/program.js +63 -263
- package/lib/runner/index.js +8339 -0
- package/lib/runner/index.js.txt +60 -0
- package/lib/transform/babelBundle.js +71002 -18
- package/lib/transform/babelBundle.js.LICENSE +2359 -0
- package/lib/transform/babelBundle.js.txt +325 -0
- package/lib/transform/esmLoader.js +5884 -30
- package/lib/transform/esmLoader.js.LICENSE +335 -0
- package/lib/transform/esmLoader.js.txt +55 -0
- package/lib/util.js +37 -34
- package/lib/worker/workerProcessEntry.js +3251 -0
- package/lib/worker/workerProcessEntry.js.txt +24 -0
- package/package.json +5 -16
- package/test.mjs +1 -0
- package/types/test.d.ts +172 -12
- package/types/testReporter.d.ts +7 -5
- package/lib/common/config.js +0 -282
- package/lib/common/configLoader.js +0 -344
- package/lib/common/esmLoaderHost.js +0 -104
- package/lib/common/expectBundle.js +0 -28
- package/lib/common/expectBundleImpl.js +0 -407
- package/lib/common/fixtures.js +0 -302
- package/lib/common/ipc.js +0 -60
- package/lib/common/poolBuilder.js +0 -85
- package/lib/common/process.js +0 -132
- package/lib/common/suiteUtils.js +0 -140
- package/lib/common/test.js +0 -321
- package/lib/common/testLoader.js +0 -101
- package/lib/common/testType.js +0 -298
- package/lib/common/validators.js +0 -68
- package/lib/fsWatcher.js +0 -67
- package/lib/isomorphic/events.js +0 -77
- package/lib/isomorphic/folders.js +0 -30
- package/lib/isomorphic/stringInternPool.js +0 -69
- package/lib/isomorphic/teleReceiver.js +0 -521
- package/lib/isomorphic/teleSuiteUpdater.js +0 -157
- package/lib/isomorphic/testServerInterface.js +0 -16
- package/lib/isomorphic/testTree.js +0 -329
- package/lib/isomorphic/types.d.js +0 -16
- package/lib/loader/loaderMain.js +0 -59
- package/lib/matchers/matcherHint.js +0 -44
- package/lib/matchers/matchers.js +0 -383
- package/lib/matchers/toBeTruthy.js +0 -75
- package/lib/matchers/toEqual.js +0 -100
- package/lib/matchers/toHaveURL.js +0 -101
- package/lib/matchers/toMatchAriaSnapshot.js +0 -159
- package/lib/matchers/toMatchSnapshot.js +0 -342
- package/lib/matchers/toMatchText.js +0 -99
- package/lib/mcp/browser/browserContextFactory.js +0 -329
- package/lib/mcp/browser/browserServerBackend.js +0 -84
- package/lib/mcp/browser/config.js +0 -421
- package/lib/mcp/browser/context.js +0 -244
- package/lib/mcp/browser/response.js +0 -278
- package/lib/mcp/browser/sessionLog.js +0 -75
- package/lib/mcp/browser/tab.js +0 -343
- package/lib/mcp/browser/tools/common.js +0 -65
- package/lib/mcp/browser/tools/console.js +0 -46
- package/lib/mcp/browser/tools/dialogs.js +0 -60
- package/lib/mcp/browser/tools/evaluate.js +0 -61
- package/lib/mcp/browser/tools/files.js +0 -58
- package/lib/mcp/browser/tools/form.js +0 -63
- package/lib/mcp/browser/tools/install.js +0 -72
- package/lib/mcp/browser/tools/keyboard.js +0 -107
- package/lib/mcp/browser/tools/mouse.js +0 -107
- package/lib/mcp/browser/tools/navigate.js +0 -71
- package/lib/mcp/browser/tools/network.js +0 -63
- package/lib/mcp/browser/tools/open.js +0 -57
- package/lib/mcp/browser/tools/pdf.js +0 -49
- package/lib/mcp/browser/tools/runCode.js +0 -78
- package/lib/mcp/browser/tools/screenshot.js +0 -93
- package/lib/mcp/browser/tools/snapshot.js +0 -173
- package/lib/mcp/browser/tools/tabs.js +0 -67
- package/lib/mcp/browser/tools/tool.js +0 -47
- package/lib/mcp/browser/tools/tracing.js +0 -74
- package/lib/mcp/browser/tools/utils.js +0 -94
- package/lib/mcp/browser/tools/verify.js +0 -143
- package/lib/mcp/browser/tools/wait.js +0 -63
- package/lib/mcp/browser/tools.js +0 -84
- package/lib/mcp/browser/watchdog.js +0 -44
- package/lib/mcp/config.d.js +0 -16
- package/lib/mcp/extension/cdpRelay.js +0 -351
- package/lib/mcp/extension/extensionContextFactory.js +0 -76
- package/lib/mcp/extension/protocol.js +0 -28
- package/lib/mcp/index.js +0 -61
- package/lib/mcp/log.js +0 -35
- package/lib/mcp/program.js +0 -111
- package/lib/mcp/sdk/exports.js +0 -28
- package/lib/mcp/sdk/http.js +0 -152
- package/lib/mcp/sdk/inProcessTransport.js +0 -71
- package/lib/mcp/sdk/server.js +0 -223
- package/lib/mcp/sdk/tool.js +0 -47
- package/lib/mcp/terminal/cli.js +0 -296
- package/lib/mcp/terminal/command.js +0 -56
- package/lib/mcp/terminal/commands.js +0 -333
- package/lib/mcp/terminal/daemon.js +0 -129
- package/lib/mcp/terminal/help.json +0 -32
- package/lib/mcp/terminal/helpGenerator.js +0 -88
- package/lib/mcp/terminal/socketConnection.js +0 -80
- package/lib/plugins/gitCommitInfoPlugin.js +0 -198
- package/lib/plugins/index.js +0 -28
- package/lib/plugins/webServerPlugin.js +0 -237
- package/lib/reporters/base.js +0 -634
- package/lib/reporters/blob.js +0 -138
- package/lib/reporters/dot.js +0 -99
- package/lib/reporters/empty.js +0 -32
- package/lib/reporters/github.js +0 -128
- package/lib/reporters/html.js +0 -633
- package/lib/reporters/internalReporter.js +0 -138
- package/lib/reporters/json.js +0 -254
- package/lib/reporters/junit.js +0 -232
- package/lib/reporters/line.js +0 -131
- package/lib/reporters/list.js +0 -253
- package/lib/reporters/listModeReporter.js +0 -69
- package/lib/reporters/markdown.js +0 -144
- package/lib/reporters/merge.js +0 -558
- package/lib/reporters/multiplexer.js +0 -112
- package/lib/reporters/reporterV2.js +0 -102
- package/lib/reporters/smoothdeploy.js +0 -333
- package/lib/reporters/teleEmitter.js +0 -317
- package/lib/reporters/versions/blobV1.js +0 -16
- package/lib/runner/dispatcher.js +0 -531
- package/lib/runner/failureTracker.js +0 -72
- package/lib/runner/lastRun.js +0 -77
- package/lib/runner/loadUtils.js +0 -334
- package/lib/runner/loaderHost.js +0 -89
- package/lib/runner/processHost.js +0 -180
- package/lib/runner/projectUtils.js +0 -241
- package/lib/runner/rebase.js +0 -189
- package/lib/runner/reporters.js +0 -140
- package/lib/runner/sigIntWatcher.js +0 -96
- package/lib/runner/storage.js +0 -91
- package/lib/runner/taskRunner.js +0 -127
- package/lib/runner/tasks.js +0 -410
- package/lib/runner/testGroups.js +0 -125
- package/lib/runner/testRunner.js +0 -398
- package/lib/runner/testServer.js +0 -269
- package/lib/runner/uiModeReporter.js +0 -30
- package/lib/runner/vcs.js +0 -72
- package/lib/runner/watchMode.js +0 -396
- package/lib/runner/workerHost.js +0 -104
- package/lib/third_party/pirates.js +0 -62
- package/lib/third_party/tsconfig-loader.js +0 -103
- package/lib/transform/babelBundleImpl.js +0 -461
- package/lib/transform/compilationCache.js +0 -274
- package/lib/transform/md.js +0 -221
- package/lib/transform/portTransport.js +0 -67
- package/lib/transform/transform.js +0 -303
- package/lib/utilsBundle.js +0 -50
- package/lib/utilsBundleImpl.js +0 -103
- package/lib/worker/fixtureRunner.js +0 -262
- package/lib/worker/testInfo.js +0 -536
- package/lib/worker/testTracing.js +0 -345
- package/lib/worker/timeoutManager.js +0 -174
- package/lib/worker/util.js +0 -31
- package/lib/worker/workerMain.js +0 -530
- /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
|
|
25
|
-
|
|
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
|
|
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?.
|
|
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(
|
|
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
|
|
77
|
-
|
|
78
|
-
if (
|
|
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
|
|
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
|
-
|
|
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:
|
|
47
|
-
plan:
|
|
48
|
-
project:
|
|
49
|
-
seedFile:
|
|
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:
|
|
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:
|
|
84
|
-
fileName:
|
|
85
|
-
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
|
|
99
|
-
|
|
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(
|
|
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:
|
|
46
|
-
project:
|
|
47
|
-
seedFile:
|
|
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 =
|
|
58
|
-
overview:
|
|
59
|
-
suites:
|
|
60
|
-
name:
|
|
61
|
-
seedFile:
|
|
62
|
-
tests:
|
|
63
|
-
name:
|
|
64
|
-
file:
|
|
65
|
-
steps:
|
|
66
|
-
perform:
|
|
67
|
-
expect:
|
|
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:
|
|
96
|
-
fileName:
|
|
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
|
-
|
|
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",
|
package/lib/mcp/test/seed.js
CHANGED
|
@@ -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
|
|
41
|
-
|
|
42
|
-
function seedProject(
|
|
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
|
|
45
|
-
const project =
|
|
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
|
|
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
|
|
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
|
|
35
|
-
var
|
|
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
|
-
|
|
41
|
-
|
|
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
|
|
64
|
-
|
|
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: ${
|
|
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
|
-
|
|
77
|
-
|
|
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:
|
|
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
|
});
|