@playwright-repl/mcp 0.18.0 → 0.18.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/README.md +48 -1
- package/dist/index.js +50 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ npm install -g @playwright-repl/mcp
|
|
|
53
53
|
|
|
54
54
|
Load `packages/extension/dist/` as an unpacked extension in Chrome (`chrome://extensions` → Enable Developer mode → Load unpacked).
|
|
55
55
|
|
|
56
|
-
Or install from the Chrome Web Store
|
|
56
|
+
Or install from the [Chrome Web Store](https://chromewebstore.google.com/detail/dramaturg/ppbkmncnmjkfppilnmplpokdfagobipa).
|
|
57
57
|
|
|
58
58
|
### 3. Configure your MCP client
|
|
59
59
|
|
|
@@ -182,6 +182,53 @@ A prompt template that guides the AI to generate a passing Playwright test from
|
|
|
182
182
|
|
|
183
183
|
The AI navigates the page, takes snapshots, writes Playwright assertions, runs them via `run_script(language="javascript")`, and iterates until all pass.
|
|
184
184
|
|
|
185
|
+
## AI Agents
|
|
186
|
+
|
|
187
|
+
The MCP package includes four ready-to-use AI agents in `packages/mcp/agents/`:
|
|
188
|
+
|
|
189
|
+
| Agent | Purpose |
|
|
190
|
+
|-------|---------|
|
|
191
|
+
| **playwright-repl-planner** | Explore a web page and create a comprehensive workflow plan |
|
|
192
|
+
| **playwright-repl-generator** | Turn a plan or description into a working `.pw` or JS script |
|
|
193
|
+
| **playwright-repl-healer** | Debug and fix a failing script |
|
|
194
|
+
| **playwright-repl-converter** | Convert scripts between `.pw` keyword syntax and JavaScript |
|
|
195
|
+
|
|
196
|
+
### playwright-repl-planner
|
|
197
|
+
|
|
198
|
+
Systematically explores a web page — takes snapshots, screenshots, maps out navigation, forms, and interactive elements — and produces a structured workflow plan. Use it as the first step before generating a script: give it a URL and a goal, and it returns a step-by-step plan with the exact text/labels discovered on the page.
|
|
199
|
+
|
|
200
|
+
### playwright-repl-generator
|
|
201
|
+
|
|
202
|
+
Takes a workflow plan (from the planner or your own description) and turns it into a working `.pw` keyword script or JavaScript Playwright script. It executes each step in the real browser, assembles the commands, runs the full script via `run_script`, and iterates until it passes. Output is a tested, ready-to-use script.
|
|
203
|
+
|
|
204
|
+
### playwright-repl-healer
|
|
205
|
+
|
|
206
|
+
Debugs and fixes a failing `.pw` or JS script. Give it a script that's broken — wrong selectors, timing issues, changed page structure — and it will run it, diagnose failures using snapshots and screenshots, fix the commands, and re-run until all lines pass.
|
|
207
|
+
|
|
208
|
+
### playwright-repl-converter
|
|
209
|
+
|
|
210
|
+
Converts scripts between `.pw` keyword syntax and JavaScript Playwright API. Includes a comprehensive conversion reference table and produces idiomatic output — chaining `.press()` to locators instead of `page.keyboard`, extracting repeated locators into variables, and choosing the right locator strategy (`getByRole`, `getByLabel`, `getByText`, etc.) based on the actual page structure.
|
|
211
|
+
|
|
212
|
+
### Setup
|
|
213
|
+
|
|
214
|
+
Copy the agent files into your project's `.claude/agents/` folder:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
mkdir -p .claude/agents
|
|
218
|
+
cp node_modules/@playwright-repl/mcp/agents/*.agent.md .claude/agents/
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Then invoke them with `@agent-name`:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
@playwright-repl-planner explore https://demo.playwright.dev/todomvc and plan a test for adding/completing todos
|
|
225
|
+
@playwright-repl-generator create a .pw script from this plan: [paste plan]
|
|
226
|
+
@playwright-repl-healer fix this script: [paste failing script]
|
|
227
|
+
@playwright-repl-converter convert this .pw script to JavaScript: [paste script]
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Each agent has access to `run_command` and `run_script` via the MCP server and runs autonomously — exploring the page, executing commands, and iterating until the output is verified.
|
|
231
|
+
|
|
185
232
|
## Tips for AI agents
|
|
186
233
|
|
|
187
234
|
- **Call `snapshot` to understand the page** — it returns the accessibility tree with element refs (`e1`, `e5`, …) that you can use with `click`, `fill`, etc. Useful before interacting with an unfamiliar page.
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { BridgeServer } from '@playwright-repl/core';
|
|
5
|
+
import { BridgeServer, COMMANDS, CATEGORIES, refToLocator } from '@playwright-repl/core';
|
|
6
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
6
7
|
const argv = process.argv.slice(2);
|
|
7
8
|
const portIdx = argv.indexOf('--port');
|
|
8
9
|
const port = portIdx !== -1
|
|
9
10
|
? parseInt(argv[portIdx + 1])
|
|
10
11
|
: (process.env.BRIDGE_PORT ? parseInt(process.env.BRIDGE_PORT) : 9876);
|
|
11
12
|
const srv = new BridgeServer();
|
|
13
|
+
let lastSnapshot = null;
|
|
12
14
|
try {
|
|
13
15
|
await srv.start(port);
|
|
14
16
|
}
|
|
@@ -42,14 +44,50 @@ Run a command in the connected Chrome browser. Supports three input modes:
|
|
|
42
44
|
document.title, window.location.href,
|
|
43
45
|
document.querySelectorAll('a').length
|
|
44
46
|
|
|
45
|
-
Use snapshot to understand the page structure before interacting. Use screenshot to visually verify the current state
|
|
46
|
-
|
|
47
|
+
Use snapshot to understand the page structure before interacting. Use screenshot to visually verify the current state.
|
|
48
|
+
|
|
49
|
+
IMPORTANT: Before writing .pw commands, run 'help' to get the full list of available commands. Only use commands that appear in the help output. Do not invent commands.`;
|
|
50
|
+
const server = new McpServer({ name: 'playwright-repl', version: pkg.version });
|
|
47
51
|
server.registerTool('run_command', {
|
|
48
52
|
description: RUN_COMMAND_DESCRIPTION,
|
|
49
53
|
inputSchema: {
|
|
50
54
|
command: z.string().describe(RUN_COMMAND_INPUT_DESCRIPTION),
|
|
51
55
|
},
|
|
52
56
|
}, async ({ command }) => {
|
|
57
|
+
const trimmed = command.trim().toLowerCase();
|
|
58
|
+
if (trimmed === 'help') {
|
|
59
|
+
const lines = Object.entries(CATEGORIES)
|
|
60
|
+
.map(([cat, cmds]) => ` ${cat}: ${cmds.join(', ')}`)
|
|
61
|
+
.join('\n');
|
|
62
|
+
return { content: [{ type: 'text', text: `Available commands:\n${lines}\n\nType "help <command>" for details.` }] };
|
|
63
|
+
}
|
|
64
|
+
if (trimmed.startsWith('locator ')) {
|
|
65
|
+
const ref = command.trim().slice(8).trim();
|
|
66
|
+
if (!lastSnapshot) {
|
|
67
|
+
return { content: [{ type: 'text', text: 'No snapshot cached. Run "snapshot" first.' }], isError: true };
|
|
68
|
+
}
|
|
69
|
+
const locator = refToLocator(lastSnapshot.snapshotString, ref);
|
|
70
|
+
if (!locator) {
|
|
71
|
+
return { content: [{ type: 'text', text: `Ref "${ref}" not found in last snapshot. Run "snapshot" to refresh.` }], isError: true };
|
|
72
|
+
}
|
|
73
|
+
return { content: [{ type: 'text', text: `js: ${locator.js}\npw: ${locator.pw}` }] };
|
|
74
|
+
}
|
|
75
|
+
if (trimmed.startsWith('help ')) {
|
|
76
|
+
const cmd = trimmed.slice(5).trim();
|
|
77
|
+
const info = COMMANDS[cmd];
|
|
78
|
+
if (!info) {
|
|
79
|
+
return { content: [{ type: 'text', text: `Unknown command: "${cmd}". Type "help" for available commands.` }], isError: true };
|
|
80
|
+
}
|
|
81
|
+
const parts = [`${cmd} — ${info.desc}`];
|
|
82
|
+
if (info.usage)
|
|
83
|
+
parts.push(`Usage: ${info.usage}`);
|
|
84
|
+
if (info.examples?.length) {
|
|
85
|
+
parts.push('Examples:');
|
|
86
|
+
for (const ex of info.examples)
|
|
87
|
+
parts.push(` ${ex}`);
|
|
88
|
+
}
|
|
89
|
+
return { content: [{ type: 'text', text: parts.join('\n') }] };
|
|
90
|
+
}
|
|
53
91
|
if (!srv.connected) {
|
|
54
92
|
return {
|
|
55
93
|
content: [{ type: 'text', text: 'Browser not connected. Open Chrome with the playwright-repl extension — it connects automatically.' }],
|
|
@@ -57,6 +95,11 @@ server.registerTool('run_command', {
|
|
|
57
95
|
};
|
|
58
96
|
}
|
|
59
97
|
const result = await srv.run(command);
|
|
98
|
+
// Cache snapshot for locator command
|
|
99
|
+
// Bridge mode: snapshot returns raw YAML (no ### headers)
|
|
100
|
+
if (trimmed.startsWith('snapshot') && result.text && !result.isError) {
|
|
101
|
+
lastSnapshot = { url: '', snapshotString: result.text.trim() };
|
|
102
|
+
}
|
|
60
103
|
if (result.image) {
|
|
61
104
|
const [header, data] = result.image.split(',');
|
|
62
105
|
const mimeType = (header.match(/data:(.*);base64/) ?? [])[1] ?? 'image/png';
|
|
@@ -73,7 +116,9 @@ Useful for replaying a known script without per-step round trips.
|
|
|
73
116
|
Prefer run_command for AI-driven exploration where you need to observe and adapt after each step.
|
|
74
117
|
|
|
75
118
|
language='pw': each line is a .pw keyword command, run sequentially. Lines starting with # are skipped. Stops on first error.
|
|
76
|
-
language='javascript': the entire script is run as a single JavaScript/Playwright block
|
|
119
|
+
language='javascript': the entire script is run as a single JavaScript/Playwright block.
|
|
120
|
+
|
|
121
|
+
IMPORTANT: Only use commands listed by 'help'. Run run_command('help') first if unsure which commands are available.`;
|
|
77
122
|
server.registerTool('run_script', {
|
|
78
123
|
description: RUN_SCRIPT_DESCRIPTION,
|
|
79
124
|
inputSchema: {
|
|
@@ -98,6 +143,7 @@ Generate a passing Playwright test for the following scenario:
|
|
|
98
143
|
${steps}
|
|
99
144
|
|
|
100
145
|
Workflow:
|
|
146
|
+
0. Run run_command('help') to see all available keyword commands. Only use commands from this list — do not invent commands.
|
|
101
147
|
1. ${url ? `Navigate to ${url} using run_command('goto ${url}').` : 'Navigate to the target URL using run_command.'}
|
|
102
148
|
2. Take a snapshot using run_command('snapshot') to understand the page structure.
|
|
103
149
|
3. Interact with the page as needed (click, fill, press) using run_command.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|