playwright-test-agent 0.1.4 → 0.1.6
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.
|
@@ -7,7 +7,7 @@ import { initializeProject } from '../playwright-test-agent/scripts/init-playwri
|
|
|
7
7
|
const usage = `Usage: playwright-test-agent init [target-directory]
|
|
8
8
|
|
|
9
9
|
Initialize Playwright Test agents, install the playwright-test-agent skill,
|
|
10
|
-
and update AGENTS.md and CLAUDE.md
|
|
10
|
+
configure the project MCP servers, and update AGENTS.md and CLAUDE.md.`;
|
|
11
11
|
|
|
12
12
|
const [command, targetDirectory, ...extraArguments] = process.argv.slice(2);
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwright-test-agent",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Initialize Playwright Test agents and
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "Initialize Playwright Test, its agents, MCP configuration, and the playwright-test-agent skill.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"playwright-test-agent": "bin/playwright-test-agent.mjs"
|
|
@@ -1,113 +1,64 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: playwright-test-agent
|
|
3
|
-
description: Use first when a user asks to test a website, browser workflow, HTTP API, or application feature, including planning,
|
|
3
|
+
description: Use first when a user asks to investigate or test a website, browser workflow, HTTP API, or application feature with Playwright, including test planning, generation, execution, debugging, healing, and evidence collection.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Playwright Test Agent
|
|
7
7
|
|
|
8
|
-
Use Playwright
|
|
8
|
+
Use Playwright's Planner -> Generator -> Healer workflow for durable, auditable tests. `AGENTS.md` or `CLAUDE.md` defines how the active platform assumes or launches those roles; this Skill contains only their shared workflow.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Prepare the objective
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
The main agent may inspect the local project for relevant requirements, routes, fixtures, and constraints. Do not require a setup audit or check for a seed, Playwright config, or generated files before beginning Planner.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|---|---|---|
|
|
16
|
-
| Planner | `playwright_test_planner` | `playwright-test-planner` |
|
|
17
|
-
| Generator | `playwright_test_generator` | `playwright-test-generator` |
|
|
18
|
-
| Healer | `playwright_test_healer` | `playwright-test-healer` |
|
|
14
|
+
Before planning, ask the user for information that could materially change the test purpose, scope, safety, or expected behavior, such as the deployed URL, intended role, success criteria, allowed data mutations, and required environment. Do not ask for UI details Planner can safely discover.
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
If the request is sufficient, begin Planner immediately. If investigation reveals that a URL, credential, role, prerequisite, expected result, or authorization boundary is missing, incorrect, or contradictory, pause Planner and ask for the specific correction. Resume Planner with the corrected information and blocking observation. Do not guess credentials, probe nearby environments, bypass access controls, or wander through unrelated pages.
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
Keep credentials and tokens in environment variables or ignored secret files. Never copy them into plans, tests, screenshots, evidence, or chat.
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
- **Planner:** Run the generated seed to establish page context, global setup, dependencies, fixtures, and hooks. Explore the deployed application for the requested scenarios and user flows, compare observations with the request and optional PRD, and save a precise human-readable Markdown plan under `specs/`. It does not generate the formal test files and must not spawn another agent. It must call its own injected `planner_setup_page` and `planner_save_plan` tools directly.
|
|
26
|
-
- **Generator:** Read the complete user-confirmed Markdown plan and the same generated seed, execute each scenario to validate locators and assertions against the live application, and generate executable Playwright tests under the configured test directory. It must not invent unconfirmed scenarios or expected behavior, must not spawn another agent, and must call its own injected `generator_setup_page`, `generator_read_log`, and `generator_write_test` tools directly.
|
|
27
|
-
- **Healer:** Run the failing test, replay its steps, inspect the current UI, propose and apply test-side patches, and rerun until the test passes or a guardrail stops the loop. It must not spawn another agent and must call its own injected `test_list`, `test_run`, `test_debug`, and relevant `browser_*` tools directly. It must report a likely broken product, environment/data problem, or plan conflict instead of weakening assertions merely to obtain a pass.
|
|
20
|
+
## Planner
|
|
28
21
|
|
|
29
|
-
|
|
22
|
+
Planner owns live application investigation and saves a human-readable Markdown plan under `specs/`. Start page setup immediately. Supply a seed only when the user or request explicitly identifies one; otherwise allow Playwright to use its initialized default. Do not perform a separate seed/config discovery pass.
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
request + deployed URL -> locate generated seed -> planner -> user confirms plan
|
|
33
|
-
-> generator -> healer for failures -> final report
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Planner, Generator, and Healer are terminal/leaf agents in this flow. The main agent starts the platform-specific agent for each role directly and passes all required inputs in that invocation. Never delegate their work to `live_planner`, `live_generator`, `live_healer`, a same-role nested agent, or another intermediary. If a directly started agent lacks any required MCP tool, stop with an MCP-injection diagnosis; do not create another subagent level and do not replace that agent's work in the main agent.
|
|
37
|
-
|
|
38
|
-
## Initialize once per project
|
|
39
|
-
|
|
40
|
-
Inspect the target project first. If Playwright Test, its config, or either Codex/Claude agent set is missing, tell the user initialization will modify the project, then run from the target project:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npx playwright-test-agent init
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
The command installs this skill for Codex and Claude, selects the ready-to-use Playwright defaults (TypeScript, `playwright-tests/`, no GitHub Actions, Chromium with browser installation), and runs both:
|
|
47
|
-
|
|
48
|
-
```text
|
|
49
|
-
npx playwright init-agents --loop=codex
|
|
50
|
-
npx playwright init-agents --loop=claude
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
It uses the project-local Playwright command. Never install a global/additional Playwright CLI or run `playwright init-skills`.
|
|
54
|
-
|
|
55
|
-
`playwright init-agents` also creates the project's default `seed.spec.ts`. Its directory follows the selected Playwright project's `testDir`, so it may be under `playwright-tests/`, `e2e/`, `tests/`, or another configured directory. Do not hardcode the path. Locate it from `playwright.config.*`, the generated agent definitions, or the filesystem before invoking planner or generator.
|
|
56
|
-
|
|
57
|
-
## Understand the request
|
|
24
|
+
The plan contains prerequisites, test data requirements, independent scenarios, steps, observable expected results, exclusions, and intended test outputs. Reconnaissance must not create durable/shared data or perform purchases, submissions, messages, deletion, or other consequential actions unless the user authorized them.
|
|
58
25
|
|
|
59
|
-
|
|
26
|
+
Show the completed scenario list and exclusions to the user. Generator may start only after the user confirms the plan.
|
|
60
27
|
|
|
61
|
-
|
|
28
|
+
## Generator
|
|
62
29
|
|
|
63
|
-
|
|
30
|
+
Generator converts the complete confirmed Markdown plan into executable Playwright tests and validates locators and assertions against the application. Generate only confirmed scenarios. Prefer independent tests, semantic locators, assertions for every expected result, and environment-based secrets.
|
|
64
31
|
|
|
65
|
-
|
|
32
|
+
For API-only scenarios, Playwright `APIRequestContext` tests may be written directly. Assert status, headers, schema, stable business invariants, and safe mutation cleanup.
|
|
66
33
|
|
|
67
|
-
|
|
34
|
+
## Healer
|
|
68
35
|
|
|
69
|
-
|
|
36
|
+
Use Healer only for failing generated tests. Diagnose one failing test at a time, replay the failure, inspect the current application state, apply a test-side correction when justified, and rerun within the role's guardrails.
|
|
70
37
|
|
|
71
|
-
|
|
38
|
+
Do not weaken assertions, add arbitrary sleeps, retry blindly, or skip a test merely to obtain a pass. If behavior conflicts with the confirmed plan, preserve the evidence and ask whether it is a regression or intended product change. Classify unresolved failures as an application defect, test defect, environment/data problem, or product decision.
|
|
72
39
|
|
|
73
|
-
|
|
40
|
+
## Evidence
|
|
74
41
|
|
|
75
|
-
|
|
42
|
+
Keep generated evidence under `.playwright-evidence/`:
|
|
76
43
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
Show the complete scenario list and exclusions to the user. Ask whether it is complete. Revise until confirmed. Do not invoke the generator or formally execute tests before confirmation.
|
|
86
|
-
|
|
87
|
-
## Generate and run
|
|
88
|
-
|
|
89
|
-
For confirmed UI scenarios, invoke the Generator directly once for the complete confirmed plan (or complete selected scenario set), explicitly naming the Markdown plan and the same generated seed; use the configured Playwright test directory for generated tests. The Generator executes scenarios against the live application to validate locators and assertions while generating. Its internal per-scenario setup does not mean starting a new Generator agent for every scenario, and it must not delegate execution to a nested Generator. If the direct Generator lacks `generator_setup_page`, `generator_read_log`, or `generator_write_test`, report an MCP-injection failure and stop. Require one independent test per file, semantic locators, an assertion for every expected result, and environment-based secrets.
|
|
90
|
-
|
|
91
|
-
For confirmed API-only scenarios, write `APIRequestContext` tests directly under `playwright-tests/`. Assert status, headers, schema, and stable business invariants; define safe setup/cleanup for mutations.
|
|
44
|
+
```text
|
|
45
|
+
.playwright-evidence/
|
|
46
|
+
|-- mcp/
|
|
47
|
+
|-- snapshots/
|
|
48
|
+
|-- test-results/
|
|
49
|
+
`-- report/
|
|
50
|
+
```
|
|
92
51
|
|
|
93
|
-
|
|
52
|
+
Keep trace DOM snapshots, sources, network data, and attachments, but set trace `screenshots: false`. Trace screenshots are screencast frames and can create hundreds of JPEG resources. Explicit screenshots and failure evidence remain available when needed; avoid secrets and sensitive personal data.
|
|
94
53
|
|
|
95
|
-
|
|
54
|
+
Report the plan path, generated test paths, pass/fail/flaky/skipped counts when tests ran, evidence paths, and failure classification. Never report a skipped or unresolved test as success.
|
|
96
55
|
|
|
97
|
-
##
|
|
56
|
+
## Initialization
|
|
98
57
|
|
|
99
|
-
|
|
58
|
+
When this Skill or the Playwright Test tools are unavailable, run from the target project:
|
|
100
59
|
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
├── mcp/ # page YAML snapshots, screenshots, and agent logs
|
|
104
|
-
├── snapshots/ # reusable visual/ARIA baselines
|
|
105
|
-
├── test-results/ # failure screenshots, traces, videos, attachments
|
|
106
|
-
└── report/ # HTML report
|
|
60
|
+
```bash
|
|
61
|
+
npx playwright-test-agent init
|
|
107
62
|
```
|
|
108
63
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Keep trace DOM snapshots, sources, network data, and attachments, but disable trace screenshots (`use.trace.screenshots: false`). Trace screenshots are screencast frames and can create hundreds of JPEG files under trace `resources/`; they are separate from explicit test screenshots and are not needed for ordinary DOM-based diagnosis.
|
|
112
|
-
|
|
113
|
-
Finish by reporting the plan path, generated test paths, environment without secrets, pass/fail/flaky/skipped counts, and evidence paths. Classify failures as application defect, test defect, environment/data problem, or unresolved product decision.
|
|
64
|
+
The initializer installs the Skill, generates the official role definitions, and configures each platform. Restart the active agent session after initialization so newly configured tools are registered.
|
|
@@ -10,25 +10,24 @@ const BLOCK_END = '<!-- playwright-test-agent:end -->';
|
|
|
10
10
|
const CODEX_INSTRUCTIONS = `${BLOCK_START}
|
|
11
11
|
## Playwright Test Agent
|
|
12
12
|
|
|
13
|
-
For
|
|
13
|
+
For website, browser workflow, HTTP API, or application-feature testing, first load and follow \`.agents/skills/playwright-test-agent/SKILL.md\`.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Codex must not start \`playwright_test_planner\`, \`playwright_test_generator\`, \`playwright_test_healer\`, or another Playwright subagent. The main agent performs Planner -> Generator -> Healer in the same session with the project-level \`playwright-test\` MCP tools.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
For each phase, read the matching generated role definition and follow its \`developer_instructions\` directly:
|
|
18
|
+
- Planner: \`.codex/agents/playwright_test_planner.toml\`; call \`planner_setup_page\`, \`browser_*\`, then \`planner_save_plan\`.
|
|
19
|
+
- Generator: \`.codex/agents/playwright_test_generator.toml\`; call \`generator_setup_page\`, \`browser_*\`, \`generator_read_log\`, then \`generator_write_test\`.
|
|
20
|
+
- Healer: \`.codex/agents/playwright_test_healer.toml\`; call \`test_list\`, \`test_run\`, \`test_debug\`, and relevant \`browser_*\` tools.
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
These TOML files are role instructions to read, not agents to launch. If the project-level \`playwright-test\` tools are absent, ask the user to rerun \`npx playwright-test-agent init\` and restart Codex; do not create a subagent fallback. Ask for missing or contradictory test-purpose, access, role, data, or safety information before or during Planner, then resume the same phase after clarification. The Skill contains the shared testing rules.
|
|
20
23
|
${BLOCK_END}`;
|
|
21
24
|
|
|
22
25
|
const CLAUDE_INSTRUCTIONS = `${BLOCK_START}
|
|
23
26
|
## Playwright Test Agent
|
|
24
27
|
|
|
25
|
-
For
|
|
28
|
+
For website, browser workflow, HTTP API, or application-feature testing, first load and follow \`.claude/skills/playwright-test-agent/SKILL.md\`.
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
The main agent must start each Playwright Test agent directly. Planner, Generator, and Healer are leaf agents: do not ask them to spawn \`live_planner\`, \`live_generator\`, \`live_healer\`, or any other nested subagent. Each must use its own injected Playwright Test MCP tools directly. If a directly started agent does not expose its required tools, stop and report the MCP-injection problem; do not retry by creating a second- or third-level agent.
|
|
30
|
-
|
|
31
|
-
If Planner reports that required test information is missing, invalid, or inconsistent, stop that planning attempt and ask the user for the specific missing information. After the user responds, start \`playwright-test-planner\` again with the corrected information and the previous blocking observation. Do not continue guessing or exploring around the blocker.
|
|
30
|
+
Claude Code uses the official \`playwright-test-planner\`, \`playwright-test-generator\`, and \`playwright-test-healer\` subagents. Start each required role directly and never insert a nested or same-role intermediary. Use Planner for all live website investigation, Generator only after the user confirms the saved plan, and Healer for failing generated tests. Ask for missing or contradictory test-purpose, access, role, data, or safety information before or during Planner, then resume the same phase after clarification. The Skill contains the shared testing rules.
|
|
32
31
|
${BLOCK_END}`;
|
|
33
32
|
|
|
34
33
|
const exists = async (file) => {
|
|
@@ -147,17 +146,128 @@ async function configureClaudeMcp(projectDir) {
|
|
|
147
146
|
await writeFile(file, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
148
147
|
}
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
149
|
+
function normalizeTomlTableName(name) {
|
|
150
|
+
return name
|
|
151
|
+
.split('.')
|
|
152
|
+
.map((part) => part.trim().replace(/^(?:"([^"]+)"|'([^']+)')$/, '$1$2'))
|
|
153
|
+
.join('.');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function findTomlTables(lines, tableName) {
|
|
157
|
+
const matches = [];
|
|
158
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
159
|
+
const match = lines[index].match(/^\s*\[([^\]]+)\]\s*(?:#.*)?$/);
|
|
160
|
+
if (match && normalizeTomlTableName(match[1]) === tableName) matches.push(index);
|
|
161
|
+
}
|
|
162
|
+
return matches;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function listTomlTableNames(lines) {
|
|
166
|
+
return lines
|
|
167
|
+
.map((line) => line.match(/^\s*\[([^\]]+)\]\s*(?:#.*)?$/))
|
|
168
|
+
.filter(Boolean)
|
|
169
|
+
.map((match) => normalizeTomlTableName(match[1]));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function assignmentEnd(lines, start, limit) {
|
|
173
|
+
let square = 0;
|
|
174
|
+
let curly = 0;
|
|
175
|
+
let quote = null;
|
|
176
|
+
let escaped = false;
|
|
177
|
+
|
|
178
|
+
for (let index = start; index < limit; index += 1) {
|
|
179
|
+
for (const character of lines[index]) {
|
|
180
|
+
if (escaped) {
|
|
181
|
+
escaped = false;
|
|
182
|
+
} else if (quote === '"' && character === '\\') {
|
|
183
|
+
escaped = true;
|
|
184
|
+
} else if (quote) {
|
|
185
|
+
if (character === quote) quote = null;
|
|
186
|
+
} else if (character === '"' || character === "'") {
|
|
187
|
+
quote = character;
|
|
188
|
+
} else if (character === '#') {
|
|
189
|
+
break;
|
|
190
|
+
} else if (character === '[') {
|
|
191
|
+
square += 1;
|
|
192
|
+
} else if (character === ']') {
|
|
193
|
+
square -= 1;
|
|
194
|
+
} else if (character === '{') {
|
|
195
|
+
curly += 1;
|
|
196
|
+
} else if (character === '}') {
|
|
197
|
+
curly -= 1;
|
|
198
|
+
}
|
|
159
199
|
}
|
|
200
|
+
if (square <= 0 && curly <= 0 && !quote) return index + 1;
|
|
201
|
+
}
|
|
202
|
+
return limit;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function replaceTomlTable(lines, tableName, assignments, removedKeys = []) {
|
|
206
|
+
const matches = findTomlTables(lines, tableName);
|
|
207
|
+
if (matches.length > 1) {
|
|
208
|
+
throw new Error(`duplicate [${tableName}] tables in .codex/config.toml`);
|
|
160
209
|
}
|
|
210
|
+
|
|
211
|
+
const body = [`[${tableName}]`, ...Object.entries(assignments).map(([key, value]) => `${key} = ${value}`)];
|
|
212
|
+
if (matches.length === 0) {
|
|
213
|
+
while (lines.at(-1) === '') lines.pop();
|
|
214
|
+
if (lines.length > 0) lines.push('');
|
|
215
|
+
lines.push(...body, '');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const start = matches[0];
|
|
220
|
+
let end = start + 1;
|
|
221
|
+
while (end < lines.length && !/^\s*\[\[?[^\]]+\]\]?\s*(?:#.*)?$/.test(lines[end])) {
|
|
222
|
+
end += 1;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const replacedKeys = new Set([...Object.keys(assignments), ...removedKeys]);
|
|
226
|
+
const preserved = [];
|
|
227
|
+
for (let index = start + 1; index < end;) {
|
|
228
|
+
const match = lines[index].match(/^\s*([A-Za-z0-9_-]+)\s*=/);
|
|
229
|
+
if (match && replacedKeys.has(match[1])) {
|
|
230
|
+
index = assignmentEnd(lines, index, end);
|
|
231
|
+
} else {
|
|
232
|
+
preserved.push(lines[index]);
|
|
233
|
+
index += 1;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
while (preserved[0] === '') preserved.shift();
|
|
237
|
+
while (preserved.at(-1) === '') preserved.pop();
|
|
238
|
+
lines.splice(start, end - start, ...body, ...(preserved.length ? ['', ...preserved] : []), '');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async function configureCodexMainMcp(projectDir) {
|
|
242
|
+
const codexDir = path.join(projectDir, '.codex');
|
|
243
|
+
const file = path.join(codexDir, 'config.toml');
|
|
244
|
+
await mkdir(codexDir, { recursive: true });
|
|
245
|
+
|
|
246
|
+
const source = await exists(file) ? await readFile(file, 'utf8') : '';
|
|
247
|
+
const lines = source.replace(/\r\n?/g, '\n').split('\n');
|
|
248
|
+
const command = process.platform === 'win32' ? 'cmd' : 'npx';
|
|
249
|
+
const args = process.platform === 'win32'
|
|
250
|
+
? '["/d", "/s", "/c", "npx", "--no-install", "playwright", "run-test-mcp-server"]'
|
|
251
|
+
: '["--no-install", "playwright", "run-test-mcp-server"]';
|
|
252
|
+
|
|
253
|
+
replaceTomlTable(lines, 'mcp_servers.playwright-test', {
|
|
254
|
+
command: `"${command}"`,
|
|
255
|
+
args,
|
|
256
|
+
cwd: '"."',
|
|
257
|
+
enabled: 'true',
|
|
258
|
+
default_tools_approval_mode: '"approve"',
|
|
259
|
+
}, ['enabled_tools', 'disabled_tools']);
|
|
260
|
+
replaceTomlTable(lines, 'mcp_servers.playwright-test.env', {
|
|
261
|
+
PLAYWRIGHT_MCP_OUTPUT_DIR: '".playwright-evidence/mcp"',
|
|
262
|
+
});
|
|
263
|
+
for (const tableName of new Set(listTomlTableNames(lines))) {
|
|
264
|
+
if (tableName.startsWith('mcp_servers.playwright-test.tools.')) {
|
|
265
|
+
replaceTomlTable(lines, tableName, { approval_mode: '"approve"' });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
while (lines.at(-1) === '') lines.pop();
|
|
270
|
+
await writeFile(file, `${lines.join('\n')}\n`, 'utf8');
|
|
161
271
|
}
|
|
162
272
|
|
|
163
273
|
async function initializePlaywright(projectDir, run) {
|
|
@@ -187,7 +297,7 @@ async function initializePlaywright(projectDir, run) {
|
|
|
187
297
|
await run(projectDir, 'npx', ['--no-install', 'playwright', 'init-agents', '--loop=claude']);
|
|
188
298
|
await mkdir(path.join(projectDir, '.playwright-evidence', 'mcp'), { recursive: true });
|
|
189
299
|
await configureClaudeMcp(projectDir);
|
|
190
|
-
await
|
|
300
|
+
await configureCodexMainMcp(projectDir);
|
|
191
301
|
}
|
|
192
302
|
|
|
193
303
|
async function runStage(name, action) {
|
|
@@ -213,7 +323,8 @@ export async function initializeProject({
|
|
|
213
323
|
|
|
214
324
|
process.stdout.write(
|
|
215
325
|
'Playwright Test Agent ready: skills installed for Codex and Claude, ' +
|
|
216
|
-
'tests in playwright-tests/, evidence in .playwright-evidence
|
|
326
|
+
'tests in playwright-tests/, evidence in .playwright-evidence/. ' +
|
|
327
|
+
'Restart Codex so it loads the project-level playwright-test MCP server.\n',
|
|
217
328
|
);
|
|
218
329
|
}
|
|
219
330
|
|