Skip to content

Commit 515e453

Browse files
bryanchen-dCopilot
andcommitted
Move the scenario runner out of the MCP server
The validate-ui-scenario skill runs `runScenario`, which drives VS Code through `test/automation` and writes an evidence bundle. None of that is MCP: the runner loads no MCP module at runtime, and the SDK import it inherited was type-only, so TypeScript already elided it. It only lived under `test/mcp` because that is where the evidence pipeline was first written. That matters now: deleting the MCP server would take the skill with it. Move the six files that have nothing to do with MCP into a new `test/scenario` package, and leave `test/mcp` as one of its consumers alongside the skill. The MCP evidence tools move to `test/mcp/src/evidenceTools.ts`, where the server-specific schemas belong. Deleting `test/mcp` now removes only MCP code. Drop the step banner along with it. `showOverlay` appended a banner to the DOM of the product under test, which can shift layout and influence focus, so the runner always opted out via VSCODE_EVIDENCE_CLEAN_CAPTURE. With the runner as the only caller that opinion is unanimous, so the overlay and its opt-out both go and the capture is unconditionally faithful. Step titles are still rendered onto the finished recording by renderEvidenceChapters. The new package emits declarations, matching `test/automation`, so the MCP server keeps real types rather than silently degrading to `any`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: adb443eb-11e5-40a1-8608-7f593fa79485
1 parent d06ea12 commit 515e453

38 files changed

Lines changed: 197 additions & 147 deletions

.github/skills/validate-ui-scenario/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ Use this to reproduce a reported bug, to show that a fix works, or to attach a r
1111
test-plan item. For deterministic regression coverage that runs on every build, write a smoke test
1212
instead (see the `smoke-tests` skill) — this skill is for one-off, issue-derived validation.
1313

14-
A scenario is a small JavaScript file run by `test/mcp/out/runScenario.js`. Nothing else has to be
14+
A scenario is a small JavaScript file run by `test/scenario/out/runScenario.js`. Nothing else has to be
1515
configured: the runner launches VS Code, records video and a trace, captures a screenshot at every
1616
step boundary, writes the report, and captions the recording with each step and its result.
1717

1818
## Prepare
1919

2020
```bash
2121
npm install # once
22-
npm --prefix test/mcp run compile # after any change under test/mcp
22+
npm --prefix test/scenario run compile # after any change under test/scenario
2323
```
2424

2525
Add `ffmpeg` and `ffprobe` to `PATH` to get the caption band on the video. Without them the run still
@@ -130,7 +130,7 @@ Each step receives a `context` with `app`, `workbench`, `code`, `page`, and `ski
130130
## Run it
131131

132132
```bash
133-
node test/mcp/out/runScenario.js <scenario.cjs> --build "<app-root>"
133+
node test/scenario/out/runScenario.js <scenario.cjs> --build "<app-root>"
134134
```
135135

136136
Exit code `0` means every step passed, `1` means the run failed or was aborted, `2` a usage error.
@@ -149,7 +149,7 @@ Evidence is written to `.build/vscode-playwright-mcp/evidence/<run-id>/`:
149149
The caption band is added **above** the recorded frame rather than drawn over it, so no recorded
150150
pixel is hidden and the recording keeps its original length. Each caption carries the step number
151151
and id, its status, the step title, and the validation detail the step reported. Re-render after
152-
editing a manifest with `node test/mcp/out/renderEvidenceChapters.js <run-dir>`.
152+
editing a manifest with `node test/scenario/out/renderEvidenceChapters.js <run-dir>`.
153153

154154
## What makes evidence trustworthy
155155

build/npm/dirs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const dirs = [
5959
'test/integration/browser',
6060
'test/monaco',
6161
'test/smoke',
62+
'test/scenario',
6263
'test/mcp',
6364
'.vscode/extensions/vscode-selfhost-import-aid',
6465
'.vscode/extensions/vscode-selfhost-test-provider',

eslint.config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,10 +2329,22 @@ export default defineConfig(
23292329
'*' // node modules
23302330
]
23312331
},
2332+
{
2333+
'target': 'test/scenario/**',
2334+
'restrictions': [
2335+
'test/automation',
2336+
'test/scenario/**',
2337+
'@vscode/*',
2338+
'@parcel/*',
2339+
'@playwright/*',
2340+
'*' // node modules
2341+
]
2342+
},
23322343
{
23332344
'target': 'test/mcp/**',
23342345
'restrictions': [
23352346
'test/automation',
2347+
'test/scenario',
23362348
'test/mcp/**',
23372349
'@vscode/*',
23382350
'@parcel/*',

test/mcp/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
"main": "./out/main.js",
66
"private": true,
77
"scripts": {
8-
"compile": "cd ../automation && npm run compile && cd ../mcp && node ../../node_modules/typescript/bin/tsc6",
9-
"watch-automation": "cd ../automation && npm run watch",
8+
"compile": "cd ../scenario && npm run compile && cd ../mcp && node ../../node_modules/typescript/bin/tsc6",
9+
"watch-scenario": "cd ../scenario && npm run watch",
1010
"watch-mcp": "node ../../node_modules/typescript/bin/tsc6 --watch --preserveWatchOutput",
11-
"watch": "npm-run-all2 -lp watch-automation watch-mcp",
11+
"watch": "npm-run-all2 -lp watch-scenario watch-mcp",
1212
"start-stdio": "echo 'Starting vscode-automation-mcp... For customization and troubleshooting, see ./test/mcp/README.md' && npm ci && npm run -s compile && node ./out/stdio.js"
1313
},
1414
"dependencies": {

test/mcp/src/automation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7-
import { ApplicationService } from './application';
7+
import { ApplicationService, EvidenceService } from '../../scenario';
88
import { applyAllTools } from './automationTools/index.js';
99
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
1010
import { z } from 'zod';
11-
import { applyEvidenceStartTool, applyEvidenceTools, EvidenceService } from './evidence.js';
11+
import { applyEvidenceStartTool, applyEvidenceTools } from './evidenceTools.js';
1212

1313
export async function getServer(appService: ApplicationService): Promise<Server> {
1414
const server = new McpServer({

test/mcp/src/automationTools/activityBar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
7-
import { ApplicationService } from '../application';
7+
import { ApplicationService } from '../../../scenario';
88

99
/**
1010
* Activity Bar Tools

test/mcp/src/automationTools/chat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
7-
import { ApplicationService } from '../application';
7+
import { ApplicationService } from '../../../scenario';
88
import { z } from 'zod';
99

1010
/**

test/mcp/src/automationTools/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
77
import { z } from 'zod';
8-
import { ApplicationService, assertNoProfileOverrides } from '../application';
8+
import { ApplicationService, assertNoProfileOverrides } from '../../../scenario';
99

1010
/**
1111
* Core Application Management Tools

test/mcp/src/automationTools/debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
7-
import { ApplicationService } from '../application';
7+
import { ApplicationService } from '../../../scenario';
88
import { z } from 'zod';
99

1010
/**

test/mcp/src/automationTools/editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
7-
import { ApplicationService } from '../application';
7+
import { ApplicationService } from '../../../scenario';
88
import { z } from 'zod';
99

1010
/**

0 commit comments

Comments
 (0)