@letsrunit/mcp-server 0.10.0 → 0.11.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/dist/index.js +12 -17
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/tools/diff.ts +12 -12
- package/src/tools/run.ts +1 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letsrunit/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "MCP server for letsrunit — AI-agent browser test generation and execution",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"testing",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"packageManager": "yarn@4.10.3",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@cucumber/cucumber": "^12.7.0",
|
|
50
|
-
"@letsrunit/controller": "0.
|
|
51
|
-
"@letsrunit/gherkin": "0.
|
|
52
|
-
"@letsrunit/journal": "0.
|
|
53
|
-
"@letsrunit/playwright": "0.
|
|
54
|
-
"@letsrunit/store": "0.
|
|
55
|
-
"@letsrunit/utils": "0.
|
|
50
|
+
"@letsrunit/controller": "0.11.0",
|
|
51
|
+
"@letsrunit/gherkin": "0.11.0",
|
|
52
|
+
"@letsrunit/journal": "0.11.0",
|
|
53
|
+
"@letsrunit/playwright": "0.11.0",
|
|
54
|
+
"@letsrunit/store": "0.11.0",
|
|
55
|
+
"@letsrunit/utils": "0.11.0",
|
|
56
56
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
57
57
|
"@playwright/test": "^1.57.0",
|
|
58
58
|
"zod": "^4.3.5"
|
package/src/tools/diff.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { unifiedHtmlDiff } from '@letsrunit/playwright';
|
|
3
|
-
import { openStore,
|
|
3
|
+
import { openStore, findLastTest, findArtifacts } from '@letsrunit/store';
|
|
4
4
|
import { execSync } from 'node:child_process';
|
|
5
5
|
import { readFileSync } from 'node:fs';
|
|
6
6
|
import { dirname, join } from 'node:path';
|
|
@@ -28,17 +28,17 @@ export function registerDiff(server: McpServer, sessions: SessionManager): void
|
|
|
28
28
|
'letsrunit_diff',
|
|
29
29
|
{
|
|
30
30
|
description:
|
|
31
|
-
'Diff the current live page against the HTML snapshot from the last passing
|
|
31
|
+
'Diff the current live page against the HTML snapshot from the last passing test of a scenario. ' +
|
|
32
32
|
'Pass the scenarioId returned by letsrunit_run. ' +
|
|
33
33
|
'Returns a unified HTML diff and paths to baseline screenshots. ' +
|
|
34
|
-
'By default only considers baseline
|
|
34
|
+
'By default only considers baseline tests from the current git ancestry (gitTreeOnly: true).',
|
|
35
35
|
inputSchema: {
|
|
36
36
|
sessionId: z.string().describe('Session ID returned by letsrunit_session_start'),
|
|
37
37
|
scenarioId: z.string().describe('Scenario UUID returned by letsrunit_run'),
|
|
38
38
|
gitTreeOnly: z
|
|
39
39
|
.boolean()
|
|
40
40
|
.optional()
|
|
41
|
-
.describe('Restrict baseline to
|
|
41
|
+
.describe('Restrict baseline to tests from the current git ancestry (default: true)'),
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
44
|
async (input) => {
|
|
@@ -55,20 +55,20 @@ export function registerDiff(server: McpServer, sessions: SessionManager): void
|
|
|
55
55
|
|
|
56
56
|
const allowedCommits = (input.gitTreeOnly ?? true) ? resolveAllowedCommits() : undefined;
|
|
57
57
|
|
|
58
|
-
const
|
|
59
|
-
if (!
|
|
58
|
+
const test = findLastTest(db, input.scenarioId, 'passed', allowedCommits ?? undefined);
|
|
59
|
+
if (!test) {
|
|
60
60
|
return err(
|
|
61
61
|
allowedCommits
|
|
62
|
-
? 'No passing
|
|
63
|
-
: 'No passing
|
|
62
|
+
? 'No passing test found for this scenario in the current git ancestry. Try gitTreeOnly: false or run cucumber first.'
|
|
63
|
+
: 'No passing test found for this scenario.',
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const artifacts = findArtifacts(db,
|
|
67
|
+
const artifacts = findArtifacts(db, test.id);
|
|
68
68
|
|
|
69
69
|
const htmlArtifact = [...artifacts].reverse().find((a) => a.filename.endsWith('.html'));
|
|
70
70
|
if (!htmlArtifact) {
|
|
71
|
-
return err('No HTML snapshot found in the baseline
|
|
71
|
+
return err('No HTML snapshot found in the baseline test. Ensure the store formatter is configured.');
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const storedHtml = readFileSync(join(artifactDir, htmlArtifact.filename), 'utf-8');
|
|
@@ -86,8 +86,8 @@ export function registerDiff(server: McpServer, sessions: SessionManager): void
|
|
|
86
86
|
JSON.stringify({
|
|
87
87
|
diff,
|
|
88
88
|
baseline: {
|
|
89
|
-
|
|
90
|
-
commit:
|
|
89
|
+
testId: test.id,
|
|
90
|
+
commit: test.gitCommit,
|
|
91
91
|
screenshots,
|
|
92
92
|
},
|
|
93
93
|
}),
|
package/src/tools/run.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
4
|
-
import { computeStepId, computeScenarioId } from '@letsrunit/store';
|
|
3
|
+
import { scenarioIdFromGherkin } from '@letsrunit/gherkin';
|
|
5
4
|
import type { SessionManager } from '../sessions';
|
|
6
5
|
import { normalizeGherkin } from '../utility/gherkin';
|
|
7
6
|
import { err, text } from '../utility/response';
|
|
8
7
|
|
|
9
|
-
function scenarioIdFromGherkin(gherkin: string): string {
|
|
10
|
-
const { steps } = parseFeature(gherkin);
|
|
11
|
-
const stepIds = steps.map((s) => computeStepId(s));
|
|
12
|
-
return computeScenarioId(stepIds);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
8
|
export function registerRun(server: McpServer, sessions: SessionManager): void {
|
|
16
9
|
server.registerTool(
|
|
17
10
|
'letsrunit_run',
|