callman-mcp 0.3.0 → 0.5.0
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/CHANGELOG.md +38 -0
- package/README.md +29 -7
- package/dist/client/api.d.ts +83 -1
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +105 -0
- package/dist/client/api.js.map +1 -1
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +46 -11
- package/dist/client/errors.js.map +1 -1
- package/dist/client/types.d.ts +231 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/domain/diagram/patch.d.ts +2 -2
- package/dist/domain/uiTest/compose.d.ts +55 -0
- package/dist/domain/uiTest/compose.d.ts.map +1 -0
- package/dist/domain/uiTest/compose.js +228 -0
- package/dist/domain/uiTest/compose.js.map +1 -0
- package/dist/domain/uiTest/summarize.d.ts +273 -0
- package/dist/domain/uiTest/summarize.d.ts.map +1 -0
- package/dist/domain/uiTest/summarize.js +145 -0
- package/dist/domain/uiTest/summarize.js.map +1 -0
- package/dist/lib/truncate.d.ts +1 -1
- package/dist/lib/truncate.d.ts.map +1 -1
- package/dist/lib/truncate.js.map +1 -1
- package/dist/resources/docs/overview.d.ts +1 -1
- package/dist/resources/docs/overview.d.ts.map +1 -1
- package/dist/resources/docs/overview.js +12 -3
- package/dist/resources/docs/overview.js.map +1 -1
- package/dist/resources/docs/uiTests.d.ts +2 -0
- package/dist/resources/docs/uiTests.d.ts.map +1 -0
- package/dist/resources/docs/uiTests.js +101 -0
- package/dist/resources/docs/uiTests.js.map +1 -0
- package/dist/resources/generated/aiPacks.d.ts +1 -1
- package/dist/resources/generated/aiPacks.js +2 -2
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +13 -2
- package/dist/resources/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/catalog.d.ts +1 -1
- package/dist/tools/catalog.d.ts.map +1 -1
- package/dist/tools/catalog.js +31 -0
- package/dist/tools/catalog.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lookups.d.ts +19 -1
- package/dist/tools/lookups.d.ts.map +1 -1
- package/dist/tools/lookups.js +77 -0
- package/dist/tools/lookups.js.map +1 -1
- package/dist/tools/shared.d.ts +5 -0
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +10 -0
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/uiTestAdmin.d.ts +4 -0
- package/dist/tools/uiTestAdmin.d.ts.map +1 -0
- package/dist/tools/uiTestAdmin.js +509 -0
- package/dist/tools/uiTestAdmin.js.map +1 -0
- package/dist/tools/uiTestRuns.d.ts +24 -0
- package/dist/tools/uiTestRuns.d.ts.map +1 -0
- package/dist/tools/uiTestRuns.js +367 -0
- package/dist/tools/uiTestRuns.js.map +1 -0
- package/dist/tools/uiTestShared.d.ts +236 -0
- package/dist/tools/uiTestShared.d.ts.map +1 -0
- package/dist/tools/uiTestShared.js +187 -0
- package/dist/tools/uiTestShared.js.map +1 -0
- package/dist/tools/uiTests.d.ts +4 -0
- package/dist/tools/uiTests.d.ts.map +1 -0
- package/dist/tools/uiTests.js +572 -0
- package/dist/tools/uiTests.js.map +1 -0
- package/dist-cjs/client/api.js +105 -0
- package/dist-cjs/client/errors.js +46 -11
- package/dist-cjs/domain/uiTest/compose.js +242 -0
- package/dist-cjs/domain/uiTest/summarize.js +155 -0
- package/dist-cjs/resources/docs/overview.js +12 -3
- package/dist-cjs/resources/docs/uiTests.js +103 -0
- package/dist-cjs/resources/generated/aiPacks.js +2 -2
- package/dist-cjs/resources/index.js +11 -0
- package/dist-cjs/server.js +2 -2
- package/dist-cjs/tools/catalog.js +31 -0
- package/dist-cjs/tools/index.js +6 -0
- package/dist-cjs/tools/lookups.js +83 -1
- package/dist-cjs/tools/shared.js +12 -1
- package/dist-cjs/tools/uiTestAdmin.js +512 -0
- package/dist-cjs/tools/uiTestRuns.js +372 -0
- package/dist-cjs/tools/uiTestShared.js +202 -0
- package/dist-cjs/tools/uiTests.js +575 -0
- package/package.json +3 -3
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallmanApiError, ToolInputError } from "../client/errors.js";
|
|
3
|
+
import { resolvedSummary } from "../domain/resolve.js";
|
|
4
|
+
import { historyRow, imageFromDataUrl, runListRow, runReportView } from "../domain/uiTest/summarize.js";
|
|
5
|
+
import { findInWorkspaces, loadUiTestFolders, loadUiTests, resolveUiTest, resolveUiTestFolder, uiTestFolderSubtree } from "./lookups.js";
|
|
6
|
+
import { failureOf, guarded, ok, okWithImages, READ, RUN, workspaceArg } from "./shared.js";
|
|
7
|
+
import { flowArg, refuseMaskedDataset, workspaceIdOf } from "./uiTestShared.js";
|
|
8
|
+
// Running UI tests. Two executors:
|
|
9
|
+
// * server — the backend's ui-runner (Playwright, web flows only), when the
|
|
10
|
+
// installation has one (GET /ui-test-runner/status);
|
|
11
|
+
// * desktop — the user's own Callman desktop app, when "Let AI tools run UI
|
|
12
|
+
// tests on this computer" is on: it claims the queued job, runs it on a
|
|
13
|
+
// connected device / emulator / simulator (Android, iOS) or a local
|
|
14
|
+
// browser (web) and streams the steps back into the same report.
|
|
15
|
+
// Either way the tool gets a reportId and polls GET /ui-test-runs/:id.
|
|
16
|
+
const TERMINAL = new Set(["passed", "failed", "stopped"]);
|
|
17
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
+
export const DESKTOP_HINT = "Open the Callman desktop app on your computer, sign in, and turn on Settings → AI tools → \"Let AI tools run UI tests on this computer\". For Android/iOS also connect a device or start an emulator/simulator. list_ui_test_devices shows what is available.";
|
|
19
|
+
const targetArg = z
|
|
20
|
+
.enum(["auto", "server", "desktop"])
|
|
21
|
+
.default("auto")
|
|
22
|
+
.describe("auto = the server runner for web flows when the installation has one, otherwise your desktop app; server = web only; desktop = your Callman desktop app");
|
|
23
|
+
const desktopOptions = {
|
|
24
|
+
device: z.string().max(200).optional().describe("Desktop runs: device id or name (list_ui_test_devices); default = the app's current / first online device"),
|
|
25
|
+
browserKind: z.enum(["chrome", "firefox", "webkit"]).optional().describe("Desktop web runs: browser (default: the flow's setting)"),
|
|
26
|
+
headless: z.boolean().optional().describe("Desktop web runs: headless browser"),
|
|
27
|
+
dataset: z.record(z.string().max(10_000)).optional().describe("Desktop runs: dataset values overriding the flow's for this run"),
|
|
28
|
+
};
|
|
29
|
+
const hasDesktopOptions = (options) => Object.values(options).some((value) => value !== undefined);
|
|
30
|
+
const serverRunnerAvailable = async (ctx) => {
|
|
31
|
+
try {
|
|
32
|
+
return (await ctx.api.uiTestRunnerStatus()).serverRunner === true;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
// Pick the executor and start the run. auto → server for a web flow when a
|
|
39
|
+
// runner is up (and no desktop-only option was given), else desktop; a
|
|
40
|
+
// server answer of "no runner" falls back to the desktop.
|
|
41
|
+
export const startRun = async (ctx, flow, target, options, serverRunner) => {
|
|
42
|
+
const ws = workspaceIdOf(flow);
|
|
43
|
+
const notes = [];
|
|
44
|
+
if (target === "server") {
|
|
45
|
+
if (flow.platform !== "web")
|
|
46
|
+
throw new ToolInputError("UI_TEST_PLATFORM_UNSUPPORTED", `The server runner runs web flows only — "${flow.name}" is ${flow.platform}. Use target: "desktop" (your Callman desktop app with a device/emulator).`);
|
|
47
|
+
if (hasDesktopOptions(options))
|
|
48
|
+
throw new ToolInputError("ARG_TARGET_MISMATCH", "device / browserKind / headless / dataset apply to desktop runs only — drop them or use target: \"desktop\".");
|
|
49
|
+
}
|
|
50
|
+
const useServer = target === "server" || (target === "auto" && flow.platform === "web" && !hasDesktopOptions(options) && (serverRunner ?? (await serverRunnerAvailable(ctx))));
|
|
51
|
+
if (useServer) {
|
|
52
|
+
try {
|
|
53
|
+
return { flow, trigger: await ctx.api.runUiTestOnServer(ws, flow.clientId), executor: "server", notes };
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (!(target === "auto" && error instanceof CallmanApiError && error.code === "UI_RUNNER_UNAVAILABLE"))
|
|
57
|
+
throw error;
|
|
58
|
+
notes.push("The server runner is not available — the run went to your desktop app instead.");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
refuseMaskedDataset(options.dataset);
|
|
62
|
+
const body = {
|
|
63
|
+
...(options.device ? { device: options.device } : {}),
|
|
64
|
+
...(options.browserKind ? { browserKind: options.browserKind } : {}),
|
|
65
|
+
...(options.headless !== undefined ? { headless: options.headless } : {}),
|
|
66
|
+
...(options.dataset ? { dataset: options.dataset } : {}),
|
|
67
|
+
};
|
|
68
|
+
const trigger = await ctx.api.runUiTestOnDesktop(ws, flow.clientId, body);
|
|
69
|
+
// A desktop busy with a run the user started by hand still accepts the job
|
|
70
|
+
// (it waits in the queue) — say so, or a long "queued" looks like a hang.
|
|
71
|
+
const agents = await ctx.api.listUiTestDesktopAgents(ws).then((result) => result.agents ?? [], () => []);
|
|
72
|
+
const capable = agents.filter((agent) => agent.platforms.includes(flow.platform));
|
|
73
|
+
if (capable.length > 0 && capable.every((agent) => agent.busy)) {
|
|
74
|
+
notes.push(`Your desktop app${capable.length > 1 ? "s are" : " is"} busy with another UI-test run (e.g. one started by hand) — this run is queued behind it and starts when it finishes.`);
|
|
75
|
+
}
|
|
76
|
+
return { flow, trigger, executor: "desktop", notes };
|
|
77
|
+
};
|
|
78
|
+
const fetchReport = async (ctx, ws, reportId) => {
|
|
79
|
+
try {
|
|
80
|
+
return await ctx.api.getUiTestRun(ws, reportId);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof CallmanApiError && error.status === 404)
|
|
84
|
+
return null; // not visible yet
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export const pollRun = async (ctx, ws, reportId, timeoutSec) => {
|
|
89
|
+
const deadline = Date.now() + timeoutSec * 1000;
|
|
90
|
+
let polls = 0;
|
|
91
|
+
let last = null;
|
|
92
|
+
while (Date.now() < deadline) {
|
|
93
|
+
await sleep(polls < 5 ? ctx.pollDelaysMs.fast : ctx.pollDelaysMs.slow);
|
|
94
|
+
polls += 1;
|
|
95
|
+
last = (await fetchReport(ctx, ws, reportId)) ?? last;
|
|
96
|
+
if (last && TERMINAL.has(last.status))
|
|
97
|
+
return { report: last, timedOut: false };
|
|
98
|
+
}
|
|
99
|
+
return { report: last, timedOut: true };
|
|
100
|
+
};
|
|
101
|
+
const screenshotImages = (report) => [
|
|
102
|
+
{ caption: `Failure screenshot — ${report.flowName}`, image: imageFromDataUrl(report.failureScreenshot) },
|
|
103
|
+
{ caption: `Final screenshot — ${report.flowName}`, image: imageFromDataUrl(report.finalScreenshot) },
|
|
104
|
+
].flatMap((entry) => (entry.image ? [{ caption: entry.caption, ...entry.image }] : []));
|
|
105
|
+
const timedOutNote = (status, executor, timeoutSec) => status === "queued" && executor === "desktop"
|
|
106
|
+
? `No desktop app picked the run up within ${timeoutSec}s. ${DESKTOP_HINT} The run stays queued for 10 minutes; check it later with get_ui_test_run, or cancel_ui_test_run.`
|
|
107
|
+
: `Still ${status ?? "running"} after ${timeoutSec}s — call get_ui_test_run with this reportId later.`;
|
|
108
|
+
// The report's workspace is needed for the per-report routes: the flow's, or
|
|
109
|
+
// found by trying each workspace.
|
|
110
|
+
const findReport = async (ctx, workspace, reportId) => findInWorkspaces(ctx, workspace, "UI-test run", reportId, (ws) => ctx.api.getUiTestRun(ws.id, reportId), { matchOf: () => "id" });
|
|
111
|
+
export const registerUiTestRunTools = (server, ctx) => {
|
|
112
|
+
server.registerTool("list_ui_test_devices", {
|
|
113
|
+
title: "Where UI tests can run",
|
|
114
|
+
description: "Where UI tests can run right now: whether the server runner is up (web flows), and your desktop apps that let AI tools run UI tests — with their connected Android/iOS devices, emulators and simulators, the browsers they have, and whether they are busy. Call it before run_ui_test for mobile flows, or when a run says the desktop is offline.",
|
|
115
|
+
inputSchema: { workspace: workspaceArg },
|
|
116
|
+
annotations: READ,
|
|
117
|
+
}, guarded(async ({ workspace }) => {
|
|
118
|
+
const ws = await ctx.resolveWorkspaceOrNull(workspace);
|
|
119
|
+
let agents = [];
|
|
120
|
+
let serverRunner;
|
|
121
|
+
let note;
|
|
122
|
+
try {
|
|
123
|
+
const result = await ctx.api.listUiTestDesktopAgents(ws?.id ?? null);
|
|
124
|
+
agents = result.agents ?? [];
|
|
125
|
+
serverRunner = result.serverRunner === true;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (!(error instanceof CallmanApiError && (error.code === "ROUTE_NOT_FOUND" || error.status === 404)))
|
|
129
|
+
throw error;
|
|
130
|
+
serverRunner = await serverRunnerAvailable(ctx);
|
|
131
|
+
note = "This server does not support desktop runs yet (no desktop relay) — only the server runner is available.";
|
|
132
|
+
}
|
|
133
|
+
const online = (platform) => agents.flatMap((agent) => agent.devices.filter((device) => device.platform === platform && device.state === "online"));
|
|
134
|
+
const webDesktop = agents.some((agent) => agent.platforms.includes("web"));
|
|
135
|
+
return ok({
|
|
136
|
+
serverRunner,
|
|
137
|
+
desktopAgents: agents.map((agent) => ({
|
|
138
|
+
agentId: agent.agentId,
|
|
139
|
+
hostName: agent.hostName,
|
|
140
|
+
appVersion: agent.appVersion,
|
|
141
|
+
lastSeenAt: agent.lastSeenAt,
|
|
142
|
+
busy: agent.busy,
|
|
143
|
+
platforms: agent.platforms,
|
|
144
|
+
browsers: agent.browsers,
|
|
145
|
+
devices: agent.devices,
|
|
146
|
+
})),
|
|
147
|
+
canRun: {
|
|
148
|
+
web: serverRunner ? (webDesktop ? "server or desktop" : "server") : webDesktop ? "desktop" : "nowhere",
|
|
149
|
+
android: online("android").length > 0 ? "desktop" : agents.some((agent) => agent.platforms.includes("android")) ? "desktop (no online device — connect one or start an emulator)" : "nowhere",
|
|
150
|
+
ios: online("ios").length > 0 ? "desktop" : agents.some((agent) => agent.platforms.includes("ios")) ? "desktop (no online simulator/device)" : "nowhere",
|
|
151
|
+
},
|
|
152
|
+
...(agents.length === 0 ? { hint: DESKTOP_HINT } : {}),
|
|
153
|
+
...(note ? { note } : {}),
|
|
154
|
+
});
|
|
155
|
+
}));
|
|
156
|
+
server.registerTool("run_ui_test", {
|
|
157
|
+
title: "Run a UI test",
|
|
158
|
+
description: "Run one UI test and wait for the result (default up to 10 minutes). target auto (default): web flows on the server runner when the installation has one, everything else (Android, iOS, or no server runner) on your Callman desktop app — which must be open with \"Let AI tools run UI tests on this computer\" on (list_ui_test_devices). device / browserKind / headless / dataset apply to desktop runs. Returns per-step results, failing steps expanded with the data they saw, dataset issues and warnings; includeScreenshots: true adds the failure/final screenshots as images. wait: false returns the reportId at once.",
|
|
159
|
+
inputSchema: {
|
|
160
|
+
workspace: workspaceArg,
|
|
161
|
+
flow: flowArg,
|
|
162
|
+
target: targetArg,
|
|
163
|
+
...desktopOptions,
|
|
164
|
+
wait: z.boolean().default(true),
|
|
165
|
+
timeoutSec: z.number().int().min(5).max(1800).default(600),
|
|
166
|
+
includeScreenshots: z.boolean().default(false),
|
|
167
|
+
},
|
|
168
|
+
annotations: RUN,
|
|
169
|
+
}, guarded(async ({ workspace, flow, target, device, browserKind, headless, dataset, wait, timeoutSec, includeScreenshots }) => {
|
|
170
|
+
const resolved = await resolveUiTest(ctx, workspace, flow);
|
|
171
|
+
const started = await startRun(ctx, resolved.item, target, { device, browserKind, headless, dataset });
|
|
172
|
+
const annotation = resolved.annotation ? { resolved: [resolvedSummary(flow, resolved)] } : {};
|
|
173
|
+
const header = { uiTest: { id: resolved.item.clientId, name: resolved.item.name, platform: resolved.item.platform }, reportId: started.trigger.reportId, executor: started.executor };
|
|
174
|
+
if (!wait) {
|
|
175
|
+
return ok({ ...header, status: started.trigger.status, ...(started.notes.length ? { warnings: started.notes } : {}), note: "Check it with get_ui_test_run.", ...annotation });
|
|
176
|
+
}
|
|
177
|
+
const { report, timedOut } = await pollRun(ctx, workspaceIdOf(resolved.item), started.trigger.reportId, timeoutSec);
|
|
178
|
+
if (timedOut || !report) {
|
|
179
|
+
return ok({ ...header, status: report?.status ?? started.trigger.status, timedOut: true, note: timedOutNote(report?.status ?? started.trigger.status, started.executor, timeoutSec), ...(started.notes.length ? { warnings: started.notes } : {}), ...annotation });
|
|
180
|
+
}
|
|
181
|
+
const structured = { run: runReportView({ ...report, executor: report.executor ?? started.executor }), ...(started.notes.length ? { warnings: started.notes } : {}), ...annotation };
|
|
182
|
+
return includeScreenshots ? okWithImages(structured, screenshotImages(report)) : ok(structured);
|
|
183
|
+
}));
|
|
184
|
+
server.registerTool("run_ui_tests", {
|
|
185
|
+
title: "Run several UI tests",
|
|
186
|
+
description: "Run a batch of UI tests — a list of flows, or every flow in a folder (subfolders included unless includeSubfolders: false) — and wait for all of them. Each flow goes to the same executor run_ui_test would pick (server runs may run in parallel; desktop runs queue one after another on your app). Returns totals and one row per flow (status, executor, duration, first failing step); read details with get_ui_test_run.",
|
|
187
|
+
inputSchema: {
|
|
188
|
+
workspace: workspaceArg,
|
|
189
|
+
flows: z.array(flowArg).min(1).max(100).optional(),
|
|
190
|
+
folder: z.string().max(300).optional().describe("Run every flow in this folder (id, name or path)"),
|
|
191
|
+
includeSubfolders: z.boolean().default(true),
|
|
192
|
+
target: targetArg,
|
|
193
|
+
wait: z.boolean().default(true),
|
|
194
|
+
timeoutSec: z.number().int().min(5).max(7200).default(1800).describe("For the whole batch"),
|
|
195
|
+
},
|
|
196
|
+
annotations: RUN,
|
|
197
|
+
}, guarded(async ({ workspace, flows, folder, includeSubfolders, target, wait, timeoutSec }) => {
|
|
198
|
+
if ((flows === undefined) === (folder === undefined))
|
|
199
|
+
throw new ToolInputError("RUN_BATCH_SCOPE", "Pass `flows` or `folder` (one of them).");
|
|
200
|
+
let selected = [];
|
|
201
|
+
const notStarted = [];
|
|
202
|
+
let unresolved = 0;
|
|
203
|
+
if (folder) {
|
|
204
|
+
const target = await resolveUiTestFolder(ctx, workspace, folder);
|
|
205
|
+
const scope = includeSubfolders ? uiTestFolderSubtree(await loadUiTestFolders(ctx), target.item.id) : new Set([target.item.id]);
|
|
206
|
+
selected = (await loadUiTests(ctx)).filter((flow) => flow.folderId && scope.has(flow.folderId));
|
|
207
|
+
if (selected.length === 0)
|
|
208
|
+
throw new ToolInputError("UI_TEST_FOLDER_EMPTY", `Folder "${target.item.path}" has no UI tests${includeSubfolders ? "" : " directly (try includeSubfolders: true)"}.`);
|
|
209
|
+
if (selected.length > 100)
|
|
210
|
+
throw new ToolInputError("RUN_BATCH_TOO_LARGE", `Folder "${target.item.path}" has ${selected.length} UI tests (limit 100 per batch) — run a subfolder.`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
for (const ref of flows ?? []) {
|
|
214
|
+
try {
|
|
215
|
+
selected.push((await resolveUiTest(ctx, workspace, ref)).item);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
notStarted.push({ flow: ref, error: failureOf(error) });
|
|
219
|
+
unresolved += 1;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const serverRunner = await serverRunnerAvailable(ctx);
|
|
224
|
+
const started = [];
|
|
225
|
+
for (const flow of selected) {
|
|
226
|
+
try {
|
|
227
|
+
started.push(await startRun(ctx, flow, target, {}, serverRunner));
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
notStarted.push({ flow: flow.name, error: failureOf(error) });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const reports = new Map(started.map((run) => [run.trigger.reportId, null]));
|
|
234
|
+
let timedOut = false;
|
|
235
|
+
if (wait && started.length > 0) {
|
|
236
|
+
const deadline = Date.now() + timeoutSec * 1000;
|
|
237
|
+
let polls = 0;
|
|
238
|
+
for (;;) {
|
|
239
|
+
const pending = started.filter((run) => !TERMINAL.has(reports.get(run.trigger.reportId)?.status ?? ""));
|
|
240
|
+
if (pending.length === 0)
|
|
241
|
+
break;
|
|
242
|
+
if (Date.now() >= deadline) {
|
|
243
|
+
timedOut = true;
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
await sleep(polls < 5 ? ctx.pollDelaysMs.fast : ctx.pollDelaysMs.slow);
|
|
247
|
+
polls += 1;
|
|
248
|
+
for (const run of pending) {
|
|
249
|
+
const report = await fetchReport(ctx, workspaceIdOf(run.flow), run.trigger.reportId);
|
|
250
|
+
if (report)
|
|
251
|
+
reports.set(run.trigger.reportId, report);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const rows = started.map((run) => {
|
|
256
|
+
const report = reports.get(run.trigger.reportId);
|
|
257
|
+
return report
|
|
258
|
+
? { ...runListRow(report), executor: report.executor ?? run.executor }
|
|
259
|
+
: { reportId: run.trigger.reportId, flow: { id: run.flow.clientId, name: run.flow.name }, status: run.trigger.status, executor: run.executor };
|
|
260
|
+
});
|
|
261
|
+
const count = (status) => rows.filter((row) => row.status === status).length;
|
|
262
|
+
const unfinished = rows.filter((row) => !TERMINAL.has(row.status));
|
|
263
|
+
const desktopQueued = unfinished.some((row) => row.status === "queued" && row.executor === "desktop");
|
|
264
|
+
return ok({
|
|
265
|
+
total: selected.length + unresolved,
|
|
266
|
+
passed: count("passed"),
|
|
267
|
+
failed: count("failed"),
|
|
268
|
+
stopped: count("stopped"),
|
|
269
|
+
...(unfinished.length > 0 ? { unfinished: unfinished.length } : {}),
|
|
270
|
+
runs: rows,
|
|
271
|
+
...(notStarted.length > 0 ? { notStarted } : {}),
|
|
272
|
+
...(timedOut ? { timedOut: true, note: `Some runs were still going after ${timeoutSec}s — check them with get_ui_test_run.${desktopQueued ? ` ${DESKTOP_HINT}` : ""}` } : !wait ? { note: "Started — check each with get_ui_test_run." } : {}),
|
|
273
|
+
...([...new Set(started.flatMap((run) => run.notes))].length > 0 ? { warnings: [...new Set(started.flatMap((run) => run.notes))] } : {}),
|
|
274
|
+
});
|
|
275
|
+
}));
|
|
276
|
+
server.registerTool("get_ui_test_run", {
|
|
277
|
+
title: "Get a UI-test run",
|
|
278
|
+
description: "One UI-test run report: status, executor and device, per-step results (command, status, duration, error, the sub-flow it came from), failing steps expanded with the data they returned (DB rows, API responses, extracted {{vars}}), dataset issues and warnings. By `reportId`, or `flow` for its latest run. includeScreenshots: true returns the failure/final screenshots as images; includeNetwork: true adds the captured API calls; stepData: true expands every data step, not only failing ones.",
|
|
279
|
+
inputSchema: {
|
|
280
|
+
workspace: workspaceArg,
|
|
281
|
+
reportId: z.string().max(64).optional(),
|
|
282
|
+
flow: flowArg.optional(),
|
|
283
|
+
includeScreenshots: z.boolean().default(false),
|
|
284
|
+
includeNetwork: z.boolean().default(false),
|
|
285
|
+
stepData: z.boolean().default(false),
|
|
286
|
+
},
|
|
287
|
+
annotations: READ,
|
|
288
|
+
}, guarded(async ({ workspace, reportId, flow, includeScreenshots, includeNetwork, stepData }) => {
|
|
289
|
+
if (!reportId && !flow)
|
|
290
|
+
throw new ToolInputError("RUN_REF_REQUIRED", "Pass `reportId`, or `flow` for its latest run.");
|
|
291
|
+
let report;
|
|
292
|
+
if (reportId) {
|
|
293
|
+
report = (await findReport(ctx, workspace, reportId)).value;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
const resolved = await resolveUiTest(ctx, workspace, flow);
|
|
297
|
+
const [latest] = await ctx.api.listUiTestRuns({ flowClientId: resolved.item.clientId, limit: 1 });
|
|
298
|
+
if (!latest) {
|
|
299
|
+
const [history] = await ctx.api.listUiTestResults({ flowClientId: resolved.item.clientId, limit: 1 }).catch(() => []);
|
|
300
|
+
return ok({
|
|
301
|
+
uiTest: { id: resolved.item.clientId, name: resolved.item.name },
|
|
302
|
+
run: null,
|
|
303
|
+
...(history ? { lastRecordedRun: historyRow(history), note: "The latest run was recorded by the desktop app without a full report (step list only)." } : { note: "This UI test has no runs yet. Use run_ui_test." }),
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
report = await ctx.api.getUiTestRun(workspaceIdOf(resolved.item), latest.id);
|
|
307
|
+
}
|
|
308
|
+
const structured = { run: runReportView(report, { includeNetwork, allStepData: stepData }) };
|
|
309
|
+
return includeScreenshots ? okWithImages(structured, screenshotImages(report)) : ok(structured);
|
|
310
|
+
}));
|
|
311
|
+
server.registerTool("list_ui_test_runs", {
|
|
312
|
+
title: "List UI-test runs",
|
|
313
|
+
description: "Recent UI-test runs, newest first — server, schedule and AI-started desktop runs (with reportIds), merged with the run history the desktop app recorded itself. Filter by flow and status.",
|
|
314
|
+
inputSchema: {
|
|
315
|
+
workspace: workspaceArg,
|
|
316
|
+
flow: flowArg.optional(),
|
|
317
|
+
status: z.enum(["queued", "running", "passed", "failed", "stopped"]).optional(),
|
|
318
|
+
limit: z.number().int().min(1).max(100).default(20),
|
|
319
|
+
includeHistory: z.boolean().default(true).describe("Also list desktop-recorded runs that have no report"),
|
|
320
|
+
},
|
|
321
|
+
annotations: READ,
|
|
322
|
+
}, guarded(async ({ workspace, flow, status, limit, includeHistory }) => {
|
|
323
|
+
const resolved = flow ? await resolveUiTest(ctx, workspace, flow) : null;
|
|
324
|
+
const flowClientId = resolved?.item.clientId;
|
|
325
|
+
const [reports, history] = await Promise.all([
|
|
326
|
+
ctx.api.listUiTestRuns({ ...(flowClientId ? { flowClientId } : {}), ...(status ? { status } : {}), limit }),
|
|
327
|
+
includeHistory && (!status || ["passed", "failed", "stopped"].includes(status)) ? ctx.api.listUiTestResults({ ...(flowClientId ? { flowClientId } : {}), limit }).catch(() => []) : Promise.resolve([]),
|
|
328
|
+
]);
|
|
329
|
+
const reportIds = new Set(reports.map((report) => report.id));
|
|
330
|
+
const extra = history.filter((row) => !row.reportId || !reportIds.has(row.reportId)).filter((row) => !status || row.status === status);
|
|
331
|
+
const rows = [
|
|
332
|
+
...reports.map((report) => ({ at: Number(new Date(report.startedAt ?? 0)) || 0, row: runListRow(report) })),
|
|
333
|
+
...extra.map((row) => ({ at: Number(row.startedAt) || 0, row: historyRow(row) })),
|
|
334
|
+
]
|
|
335
|
+
.sort((a, b) => b.at - a.at)
|
|
336
|
+
.slice(0, limit)
|
|
337
|
+
.map((entry) => entry.row);
|
|
338
|
+
return ok({ ...(resolved ? { uiTest: { id: resolved.item.clientId, name: resolved.item.name } } : {}), runs: rows, total: rows.length });
|
|
339
|
+
}));
|
|
340
|
+
server.registerTool("cancel_ui_test_run", {
|
|
341
|
+
title: "Cancel a UI-test run",
|
|
342
|
+
description: "Stop a queued or running UI-test run (server or desktop). A queued desktop run is dropped at once; a running one stops at the next step.",
|
|
343
|
+
inputSchema: { workspace: workspaceArg, reportId: z.string().min(1).max(64) },
|
|
344
|
+
annotations: RUN,
|
|
345
|
+
}, guarded(async ({ workspace, reportId }) => {
|
|
346
|
+
const found = await findReport(ctx, workspace, reportId);
|
|
347
|
+
if (TERMINAL.has(found.value.status)) {
|
|
348
|
+
return ok({ reportId, status: found.value.status, note: "The run had already finished — nothing to cancel." });
|
|
349
|
+
}
|
|
350
|
+
const result = (await ctx.api.cancelUiTestRun(found.ws.id, reportId));
|
|
351
|
+
// Dropped from the queue = already stopped; a running one stops at its
|
|
352
|
+
// next step — re-read once so the answer is the report's real status.
|
|
353
|
+
let status = result?.status ?? (result?.cancelledFromQueue ? "stopped" : "stopping");
|
|
354
|
+
if (!TERMINAL.has(status)) {
|
|
355
|
+
const after = await ctx.api.getUiTestRun(found.ws.id, reportId).catch(() => null);
|
|
356
|
+
if (after && TERMINAL.has(after.status))
|
|
357
|
+
status = after.status;
|
|
358
|
+
}
|
|
359
|
+
return ok({
|
|
360
|
+
reportId,
|
|
361
|
+
flow: { id: found.value.flowClientId, name: found.value.flowName },
|
|
362
|
+
status,
|
|
363
|
+
note: status === "stopped" ? "The run was still queued — it will not run." : "Cancel requested — get_ui_test_run shows the final status.",
|
|
364
|
+
});
|
|
365
|
+
}));
|
|
366
|
+
};
|
|
367
|
+
//# sourceMappingURL=uiTestRuns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uiTestRuns.js","sourceRoot":"","sources":["../../src/tools/uiTestRuns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { type UiTestLintResult } from "callman-core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ConnectionRecord, UiTestDatasetSource, UiTestFlow, UiTestPlatform, Workspace } from "../client/types.js";
|
|
4
|
+
import type { ToolContext } from "../context.js";
|
|
5
|
+
export declare const PLATFORMS: readonly ["web", "android", "ios"];
|
|
6
|
+
export declare const TEST_TYPES: readonly ["regression", "smoke", "sanity", "integration", "e2e", "functional", "acceptance"];
|
|
7
|
+
export declare const SEVERITIES: readonly ["critical", "high-risk", "major", "minor"];
|
|
8
|
+
export declare const platformArg: z.ZodEnum<["web", "android", "ios"]>;
|
|
9
|
+
export declare const flowArg: z.ZodString;
|
|
10
|
+
export declare const stepInputSchema: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
|
|
11
|
+
export declare const stepsArg: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>, "many">]>;
|
|
12
|
+
export declare const datasetSourceSchema: z.ZodObject<{
|
|
13
|
+
kind: z.ZodOptional<z.ZodLiteral<"db">>;
|
|
14
|
+
connection: z.ZodString;
|
|
15
|
+
query: z.ZodString;
|
|
16
|
+
column: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, "strict", z.ZodTypeAny, {
|
|
18
|
+
query: string;
|
|
19
|
+
connection: string;
|
|
20
|
+
kind?: "db" | undefined;
|
|
21
|
+
column?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
query: string;
|
|
24
|
+
connection: string;
|
|
25
|
+
kind?: "db" | undefined;
|
|
26
|
+
column?: string | undefined;
|
|
27
|
+
}>;
|
|
28
|
+
export declare const runSettingsSchema: z.ZodObject<{
|
|
29
|
+
screenshotOnSuccess: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
30
|
+
screenshotOnFailure: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
31
|
+
autoRetryTransient: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
32
|
+
captureNetwork: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
33
|
+
}, "strict", z.ZodTypeAny, {
|
|
34
|
+
screenshotOnSuccess?: boolean | null | undefined;
|
|
35
|
+
screenshotOnFailure?: boolean | null | undefined;
|
|
36
|
+
autoRetryTransient?: boolean | null | undefined;
|
|
37
|
+
captureNetwork?: boolean | null | undefined;
|
|
38
|
+
}, {
|
|
39
|
+
screenshotOnSuccess?: boolean | null | undefined;
|
|
40
|
+
screenshotOnFailure?: boolean | null | undefined;
|
|
41
|
+
autoRetryTransient?: boolean | null | undefined;
|
|
42
|
+
captureNetwork?: boolean | null | undefined;
|
|
43
|
+
}>;
|
|
44
|
+
export declare const headerArg: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
45
|
+
export declare const groupArg: z.ZodOptional<z.ZodString>;
|
|
46
|
+
export declare const resolveGroupId: (ctx: ToolContext, ws: string, ref: string | undefined) => Promise<{
|
|
47
|
+
id?: string;
|
|
48
|
+
note?: string;
|
|
49
|
+
}>;
|
|
50
|
+
export interface LintContext {
|
|
51
|
+
flowNames: string[];
|
|
52
|
+
connections: ConnectionRecord[] | null;
|
|
53
|
+
}
|
|
54
|
+
export declare const lintContext: (ctx: ToolContext, workspaceId: string) => Promise<LintContext>;
|
|
55
|
+
export declare const lintFlow: (content: string, platform: UiTestPlatform, context: LintContext, datasetKeys: string[]) => UiTestLintResult;
|
|
56
|
+
export declare const lintView: (lint: UiTestLintResult, context?: LintContext) => {
|
|
57
|
+
note?: string | undefined;
|
|
58
|
+
ok: boolean;
|
|
59
|
+
errors: import("callman-core").UiTestLintIssue[];
|
|
60
|
+
warnings: import("callman-core").UiTestLintIssue[];
|
|
61
|
+
};
|
|
62
|
+
export declare const refuseLintErrors: (lint: UiTestLintResult, force: boolean | undefined, content: string) => void;
|
|
63
|
+
export type DatasetSourceInput = z.infer<typeof datasetSourceSchema>;
|
|
64
|
+
export declare const resolveDatasetSources: (ctx: ToolContext, ws: string, sources: Record<string, DatasetSourceInput | null>, current?: Record<string, UiTestDatasetSource>) => Promise<Record<string, UiTestDatasetSource>>;
|
|
65
|
+
export declare const upsertBodyOf: (flow: UiTestFlow) => Record<string, unknown>;
|
|
66
|
+
/** Refuses masked values the CALLER supplied. Masks read back from the flow
|
|
67
|
+
* itself may be sent unchanged: the backend keeps the stored secret when a
|
|
68
|
+
* value equals the mask of what is stored under that key. */
|
|
69
|
+
export declare const refuseMaskedDataset: (dataset: Record<string, string> | undefined) => void;
|
|
70
|
+
export declare const saveFlow: (ctx: ToolContext, ws: string, body: Record<string, unknown>, options?: {
|
|
71
|
+
expectedVersion?: number;
|
|
72
|
+
force?: boolean;
|
|
73
|
+
}) => Promise<{
|
|
74
|
+
flow: UiTestFlow;
|
|
75
|
+
} | {
|
|
76
|
+
conflict: Record<string, unknown>;
|
|
77
|
+
}>;
|
|
78
|
+
export declare const conflictResult: (conflict: Record<string, unknown>) => {
|
|
79
|
+
[x: string]: unknown;
|
|
80
|
+
content: ({
|
|
81
|
+
type: "text";
|
|
82
|
+
text: string;
|
|
83
|
+
annotations?: {
|
|
84
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
85
|
+
priority?: number | undefined;
|
|
86
|
+
lastModified?: string | undefined;
|
|
87
|
+
} | undefined;
|
|
88
|
+
_meta?: {
|
|
89
|
+
[x: string]: unknown;
|
|
90
|
+
} | undefined;
|
|
91
|
+
} | {
|
|
92
|
+
type: "image";
|
|
93
|
+
data: string;
|
|
94
|
+
mimeType: string;
|
|
95
|
+
annotations?: {
|
|
96
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
97
|
+
priority?: number | undefined;
|
|
98
|
+
lastModified?: string | undefined;
|
|
99
|
+
} | undefined;
|
|
100
|
+
_meta?: {
|
|
101
|
+
[x: string]: unknown;
|
|
102
|
+
} | undefined;
|
|
103
|
+
} | {
|
|
104
|
+
type: "audio";
|
|
105
|
+
data: string;
|
|
106
|
+
mimeType: string;
|
|
107
|
+
annotations?: {
|
|
108
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
109
|
+
priority?: number | undefined;
|
|
110
|
+
lastModified?: string | undefined;
|
|
111
|
+
} | undefined;
|
|
112
|
+
_meta?: {
|
|
113
|
+
[x: string]: unknown;
|
|
114
|
+
} | undefined;
|
|
115
|
+
} | {
|
|
116
|
+
uri: string;
|
|
117
|
+
name: string;
|
|
118
|
+
type: "resource_link";
|
|
119
|
+
description?: string | undefined;
|
|
120
|
+
mimeType?: string | undefined;
|
|
121
|
+
size?: number | undefined;
|
|
122
|
+
annotations?: {
|
|
123
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
124
|
+
priority?: number | undefined;
|
|
125
|
+
lastModified?: string | undefined;
|
|
126
|
+
} | undefined;
|
|
127
|
+
_meta?: {
|
|
128
|
+
[x: string]: unknown;
|
|
129
|
+
} | undefined;
|
|
130
|
+
icons?: {
|
|
131
|
+
src: string;
|
|
132
|
+
mimeType?: string | undefined;
|
|
133
|
+
sizes?: string[] | undefined;
|
|
134
|
+
theme?: "light" | "dark" | undefined;
|
|
135
|
+
}[] | undefined;
|
|
136
|
+
title?: string | undefined;
|
|
137
|
+
} | {
|
|
138
|
+
type: "resource";
|
|
139
|
+
resource: {
|
|
140
|
+
uri: string;
|
|
141
|
+
text: string;
|
|
142
|
+
mimeType?: string | undefined;
|
|
143
|
+
_meta?: {
|
|
144
|
+
[x: string]: unknown;
|
|
145
|
+
} | undefined;
|
|
146
|
+
} | {
|
|
147
|
+
uri: string;
|
|
148
|
+
blob: string;
|
|
149
|
+
mimeType?: string | undefined;
|
|
150
|
+
_meta?: {
|
|
151
|
+
[x: string]: unknown;
|
|
152
|
+
} | undefined;
|
|
153
|
+
};
|
|
154
|
+
annotations?: {
|
|
155
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
156
|
+
priority?: number | undefined;
|
|
157
|
+
lastModified?: string | undefined;
|
|
158
|
+
} | undefined;
|
|
159
|
+
_meta?: {
|
|
160
|
+
[x: string]: unknown;
|
|
161
|
+
} | undefined;
|
|
162
|
+
})[];
|
|
163
|
+
_meta?: {
|
|
164
|
+
[x: string]: unknown;
|
|
165
|
+
progressToken?: string | number | undefined;
|
|
166
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
167
|
+
taskId: string;
|
|
168
|
+
} | undefined;
|
|
169
|
+
} | undefined;
|
|
170
|
+
structuredContent?: {
|
|
171
|
+
[x: string]: unknown;
|
|
172
|
+
} | undefined;
|
|
173
|
+
isError?: boolean | undefined;
|
|
174
|
+
};
|
|
175
|
+
export declare const connectionNames: (connections: ConnectionRecord[] | null) => Map<string, string>;
|
|
176
|
+
export declare const flowDetailView: (ctx: ToolContext, flow: UiTestFlow, lint: UiTestLintResult, context: LintContext, options: {
|
|
177
|
+
workspaces: Workspace[];
|
|
178
|
+
reveal?: boolean;
|
|
179
|
+
includeContent?: boolean;
|
|
180
|
+
}) => Promise<{
|
|
181
|
+
note?: string | undefined;
|
|
182
|
+
contentTruncated?: boolean | undefined;
|
|
183
|
+
contentBytes?: number | undefined;
|
|
184
|
+
content?: string | undefined;
|
|
185
|
+
datasetSources: {
|
|
186
|
+
[k: string]: {
|
|
187
|
+
connectionName?: string | undefined;
|
|
188
|
+
kind: "db";
|
|
189
|
+
connection: string;
|
|
190
|
+
query: string;
|
|
191
|
+
column?: string;
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
preconditions: string[];
|
|
195
|
+
steps: import("callman-core").UiTestLintStep[];
|
|
196
|
+
lint: {
|
|
197
|
+
note?: string | undefined;
|
|
198
|
+
ok: boolean;
|
|
199
|
+
errors: import("callman-core").UiTestLintIssue[];
|
|
200
|
+
warnings: import("callman-core").UiTestLintIssue[];
|
|
201
|
+
};
|
|
202
|
+
datasetMasked?: string[] | undefined;
|
|
203
|
+
header: Record<string, unknown>;
|
|
204
|
+
settings: {
|
|
205
|
+
runSettings: import("callman-core").UiTestRunSettings;
|
|
206
|
+
browserKind: import("../client/types.js").UiTestBrowserKind | null;
|
|
207
|
+
headless: boolean | null;
|
|
208
|
+
} | {
|
|
209
|
+
runSettings: import("callman-core").UiTestRunSettings;
|
|
210
|
+
dismissPopups: string[];
|
|
211
|
+
};
|
|
212
|
+
dataset: Record<string, string>;
|
|
213
|
+
reviewNote?: string | undefined;
|
|
214
|
+
reviewStatus?: import("../client/types.js").ScenarioReviewStatus | undefined;
|
|
215
|
+
approvedVersion?: number | null | undefined;
|
|
216
|
+
activeVersionNumber?: number | null | undefined;
|
|
217
|
+
description: string | null;
|
|
218
|
+
testType: string | null;
|
|
219
|
+
severity: string | null;
|
|
220
|
+
tags: string[];
|
|
221
|
+
version: number | null;
|
|
222
|
+
group?: string | undefined;
|
|
223
|
+
id: string;
|
|
224
|
+
name: string;
|
|
225
|
+
platform: UiTestPlatform;
|
|
226
|
+
workspace: {
|
|
227
|
+
id: string;
|
|
228
|
+
name: string | null;
|
|
229
|
+
};
|
|
230
|
+
folder: {
|
|
231
|
+
id: string;
|
|
232
|
+
path: string;
|
|
233
|
+
} | null;
|
|
234
|
+
}>;
|
|
235
|
+
export declare const workspaceIdOf: (flow: UiTestFlow) => string;
|
|
236
|
+
//# sourceMappingURL=uiTestShared.d.ts.map
|