e2e-ai 1.4.0 → 1.4.2
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/cli.js +13 -0
- package/package.json +1 -1
- package/scripts/codegen-env.mjs +9 -1
- package/templates/workflow.md +255 -0
package/dist/cli.js
CHANGED
|
@@ -9075,6 +9075,7 @@ function registerInit(program2) {
|
|
|
9075
9075
|
success(`Config written: ${configPath}`);
|
|
9076
9076
|
}
|
|
9077
9077
|
await copyAgentsToLocal(projectRoot, !!cmdOpts?.nonInteractive);
|
|
9078
|
+
copyWorkflowGuide(projectRoot);
|
|
9078
9079
|
console.log("");
|
|
9079
9080
|
success(`Initialization complete!
|
|
9080
9081
|
`);
|
|
@@ -9215,6 +9216,18 @@ async function copyAgentsToLocal(projectRoot, nonInteractive) {
|
|
|
9215
9216
|
success(`Agents copied to .e2e-ai/agents/ (${agentFiles.length} files)`);
|
|
9216
9217
|
return agentFiles.length;
|
|
9217
9218
|
}
|
|
9219
|
+
function copyWorkflowGuide(projectRoot) {
|
|
9220
|
+
const packageRoot = getPackageRoot();
|
|
9221
|
+
const source = join13(packageRoot, "templates", "workflow.md");
|
|
9222
|
+
const target = join13(projectRoot, ".e2e-ai", "workflow.md");
|
|
9223
|
+
if (!existsSync2(source))
|
|
9224
|
+
return;
|
|
9225
|
+
if (existsSync2(target))
|
|
9226
|
+
return;
|
|
9227
|
+
const content = readFileSync2(source, "utf-8");
|
|
9228
|
+
writeFile(target, content);
|
|
9229
|
+
success("Workflow guide written to .e2e-ai/workflow.md");
|
|
9230
|
+
}
|
|
9218
9231
|
|
|
9219
9232
|
// src/commands/scan.ts
|
|
9220
9233
|
import { join as join15 } from "node:path";
|
package/package.json
CHANGED
package/scripts/codegen-env.mjs
CHANGED
|
@@ -225,7 +225,11 @@ if (!existsSync(storageStatePath)) {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
// Spawn codegen with --load-storage (skip login) and --save-storage (update cache)
|
|
228
|
+
const harPath = traceEnabled ? resolve(issueDir, `har-${timestamp}.har`) : null;
|
|
228
229
|
const codegenArgs = ['playwright', 'codegen', '--output', outputPath];
|
|
230
|
+
if (traceEnabled && harPath) {
|
|
231
|
+
codegenArgs.push('--save-har', harPath);
|
|
232
|
+
}
|
|
229
233
|
if (existsSync(storageStatePath)) {
|
|
230
234
|
codegenArgs.push('--load-storage', storageStatePath);
|
|
231
235
|
codegenArgs.push('--save-storage', storageStatePath);
|
|
@@ -336,7 +340,7 @@ child.on('exit', async (code) => {
|
|
|
336
340
|
}
|
|
337
341
|
}
|
|
338
342
|
|
|
339
|
-
// --- Trace: inject test.use and replay ---
|
|
343
|
+
// --- Trace: inject test.use({ trace: 'on' }) and run replay to generate trace ---
|
|
340
344
|
if (existsSync(outputPath)) {
|
|
341
345
|
const codegenSrc = readFileSync(outputPath, 'utf-8');
|
|
342
346
|
if (!codegenSrc.includes("test.use({ trace: 'on' })")) {
|
|
@@ -365,5 +369,9 @@ child.on('exit', async (code) => {
|
|
|
365
369
|
}
|
|
366
370
|
}
|
|
367
371
|
|
|
372
|
+
if (harPath && existsSync(harPath)) {
|
|
373
|
+
console.error(`HAR saved: ${relative(root, harPath)}`);
|
|
374
|
+
}
|
|
375
|
+
|
|
368
376
|
process.exit(code ?? 0);
|
|
369
377
|
});
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# e2e-ai Workflow Guide
|
|
2
|
+
|
|
3
|
+
This file explains how e2e-ai works and how to use it. Keep it as a reference in your `.e2e-ai/` folder.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
e2e-ai converts manual browser recordings into stable, documented Playwright tests. An AI pipeline processes your recording through multiple stages, each producing an artifact that feeds the next.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
record → transcribe → scenario → generate → refine → test → heal → qa
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**In short:** You record yourself testing in the browser (optionally narrating what you're doing), and e2e-ai turns that into a production-ready Playwright test with QA documentation.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
After running `e2e-ai init`, you need a **context file** (`.e2e-ai/context.md`) that teaches the AI about your project's test conventions — fixtures, helpers, selectors, login flows, etc.
|
|
22
|
+
|
|
23
|
+
**How to create it:** Use the `init-agent` in your AI tool (Claude Code, Cursor, etc.). If you have the MCP server configured, the AI can scan your codebase automatically with `e2e_ai_scan_codebase`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## The Standard Workflow
|
|
28
|
+
|
|
29
|
+
### 1. Record (`record`)
|
|
30
|
+
|
|
31
|
+
Opens Playwright codegen in your browser. You interact with your app while codegen captures every action.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
e2e-ai record --key PROJ-101
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**With voice** (default): Records your microphone while you narrate what you're testing. Press `R` to pause/resume audio. Your voice comments become test documentation.
|
|
38
|
+
|
|
39
|
+
**Without voice:**
|
|
40
|
+
```bash
|
|
41
|
+
e2e-ai record --key PROJ-101 --no-voice
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Output:** `codegen-<timestamp>.ts` + `voice-<timestamp>.wav` (if voice enabled)
|
|
45
|
+
|
|
46
|
+
### 2. Transcribe (`transcribe`)
|
|
47
|
+
|
|
48
|
+
Sends the voice recording to OpenAI Whisper. Gets back timestamped text segments and injects them as comments into the codegen file:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// [Voice 00:12 - 00:15] "Now I'm checking the item list loads correctly"
|
|
52
|
+
await page.getByRole('button', { name: 'Items' }).click();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Skipped automatically** if no voice recording exists.
|
|
56
|
+
|
|
57
|
+
### 3. Scenario (`scenario`)
|
|
58
|
+
|
|
59
|
+
Two AI agents process the codegen + transcript:
|
|
60
|
+
|
|
61
|
+
1. **transcript-agent** — Maps your voice comments to codegen actions, translates non-English speech, classifies what's test-relevant vs. noise
|
|
62
|
+
2. **scenario-agent** — Converts everything into a structured YAML test scenario with semantic steps and expected results
|
|
63
|
+
|
|
64
|
+
```yaml
|
|
65
|
+
name: "Items list: verify weekly view headers"
|
|
66
|
+
steps:
|
|
67
|
+
- number: 1
|
|
68
|
+
action: "Log in with valid credentials"
|
|
69
|
+
expectedResult: "User is redirected to dashboard"
|
|
70
|
+
- number: 2
|
|
71
|
+
action: "Navigate to Items section"
|
|
72
|
+
selector: "getByRole('button', { name: 'Items' })"
|
|
73
|
+
expectedResult: "Items list is displayed"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Without voice:** The scenario is generated from codegen actions alone (the AI infers intent from selectors and page structure).
|
|
77
|
+
|
|
78
|
+
### 4. Generate (`generate`)
|
|
79
|
+
|
|
80
|
+
The **playwright-generator-agent** takes the YAML scenario + your project context (`.e2e-ai/context.md`) and writes a complete `.test.ts` file using your project's fixtures, helpers, and conventions.
|
|
81
|
+
|
|
82
|
+
### 5. Refine (`refine`)
|
|
83
|
+
|
|
84
|
+
The **refactor-agent** improves the generated test:
|
|
85
|
+
- Replaces raw CSS selectors with semantic alternatives (`getByRole`, `getByText`)
|
|
86
|
+
- Uses your project's helper methods where available
|
|
87
|
+
- Adds proper timeouts to assertions
|
|
88
|
+
- Replaces `waitForTimeout()` with proper waits
|
|
89
|
+
|
|
90
|
+
### 6. Test (`test`)
|
|
91
|
+
|
|
92
|
+
Runs the test with Playwright, capturing traces, video, and screenshots.
|
|
93
|
+
|
|
94
|
+
- **If it passes** → moves to QA documentation
|
|
95
|
+
- **If it fails** → moves to self-healing
|
|
96
|
+
|
|
97
|
+
### 7. Heal (`heal`)
|
|
98
|
+
|
|
99
|
+
The **self-healing-agent** diagnoses the failure and patches the test. Up to 3 attempts, each trying a different fix strategy:
|
|
100
|
+
|
|
101
|
+
| Failure Type | Fix Strategy |
|
|
102
|
+
|---|---|
|
|
103
|
+
| Selector changed | Try semantic selectors, stable attributes |
|
|
104
|
+
| Timing issue | Add waits, increase timeouts |
|
|
105
|
+
| Element not interactable | Wait for enabled state, scroll into view |
|
|
106
|
+
| Assertion mismatch | Update expected values |
|
|
107
|
+
| Navigation failure | Add `waitForURL`, `waitForLoadState` |
|
|
108
|
+
|
|
109
|
+
Never removes assertions. Never changes test structure. Adds `// HEALED: <reason>` comments.
|
|
110
|
+
|
|
111
|
+
**Skipped automatically** if the test passes.
|
|
112
|
+
|
|
113
|
+
### 8. QA (`qa`)
|
|
114
|
+
|
|
115
|
+
The **qa-testcase-agent** generates formal QA documentation:
|
|
116
|
+
- Markdown test case (ID, preconditions, steps table, postconditions)
|
|
117
|
+
- Zephyr XML (optional, if configured)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Running the Full Pipeline
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Everything in one command
|
|
125
|
+
e2e-ai run --key PROJ-101
|
|
126
|
+
|
|
127
|
+
# Without voice recording
|
|
128
|
+
e2e-ai run --key PROJ-101 --no-voice
|
|
129
|
+
|
|
130
|
+
# Start from a specific step (skip prior steps)
|
|
131
|
+
e2e-ai run --key PROJ-101 --from scenario
|
|
132
|
+
|
|
133
|
+
# Skip specific steps
|
|
134
|
+
e2e-ai run --key PROJ-101 --skip heal
|
|
135
|
+
|
|
136
|
+
# Common: generate from existing recording data
|
|
137
|
+
e2e-ai run --key PROJ-101 --from generate
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Workflow Variations
|
|
143
|
+
|
|
144
|
+
### With Issue Tracker (Jira / Linear)
|
|
145
|
+
|
|
146
|
+
Set `inputSource: 'jira'` or `'linear'` in config. The scenario step will fetch issue context (summary, acceptance criteria, labels) and use it to align the test scenario with the ticket.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
e2e-ai run --key PROJ-101 # fetches Jira/Linear issue automatically
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Without Issue Tracker
|
|
153
|
+
|
|
154
|
+
Set `inputSource: 'none'` (default). Use any identifier as the key, or omit it entirely:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
e2e-ai run --key login-flow
|
|
158
|
+
e2e-ai run my-session
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### AI-Only (No Recording)
|
|
162
|
+
|
|
163
|
+
Write the YAML scenario manually or have it generated from an existing codegen file, then run the AI pipeline:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
e2e-ai generate --key PROJ-101
|
|
167
|
+
e2e-ai test --key PROJ-101
|
|
168
|
+
e2e-ai heal --key PROJ-101
|
|
169
|
+
e2e-ai qa --key PROJ-101
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Existing Test Improvement
|
|
173
|
+
|
|
174
|
+
Refactor an existing test to follow project conventions:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
e2e-ai refine --key PROJ-101
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Scanner Pipeline (Separate Workflow)
|
|
183
|
+
|
|
184
|
+
Scans your codebase to build a QA map of features, workflows, and test scenarios:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# 1. Extract AST (routes, components, hooks)
|
|
188
|
+
e2e-ai scan
|
|
189
|
+
|
|
190
|
+
# 2. AI analysis → features, workflows, scenarios
|
|
191
|
+
e2e-ai analyze
|
|
192
|
+
|
|
193
|
+
# 3. Push QA map to remote API (optional)
|
|
194
|
+
e2e-ai push
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
This is independent from the test pipeline — use it to get an overview of your app's testable surface.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## File Structure
|
|
202
|
+
|
|
203
|
+
After running the pipeline for `PROJ-101`:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
.e2e-ai/
|
|
207
|
+
config.ts ← your configuration
|
|
208
|
+
context.md ← project context (teach AI your conventions)
|
|
209
|
+
workflow.md ← this file
|
|
210
|
+
agents/ ← AI agent prompts (customizable)
|
|
211
|
+
PROJ-101/ ← working files (codegen, recordings)
|
|
212
|
+
|
|
213
|
+
e2e/
|
|
214
|
+
tests/PROJ-101/
|
|
215
|
+
PROJ-101.yaml ← generated scenario
|
|
216
|
+
PROJ-101.test.ts ← generated Playwright test
|
|
217
|
+
|
|
218
|
+
qa/
|
|
219
|
+
PROJ-101.md ← QA documentation
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Environment Variables
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Required
|
|
228
|
+
OPENAI_API_KEY=sk-... # For LLM calls + Whisper transcription
|
|
229
|
+
|
|
230
|
+
# Optional
|
|
231
|
+
AI_PROVIDER=openai # openai | anthropic
|
|
232
|
+
AI_MODEL=gpt-4o # Model override
|
|
233
|
+
ANTHROPIC_API_KEY=sk-ant-... # If using Anthropic
|
|
234
|
+
BASE_URL=https://your-app.com # Your application URL
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Quick Reference
|
|
240
|
+
|
|
241
|
+
| Command | What it does |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `e2e-ai init` | Create config + copy agents |
|
|
244
|
+
| `e2e-ai record --key X` | Record browser session |
|
|
245
|
+
| `e2e-ai transcribe --key X` | Transcribe voice recording |
|
|
246
|
+
| `e2e-ai scenario --key X` | Generate YAML test scenario |
|
|
247
|
+
| `e2e-ai generate --key X` | Generate Playwright test |
|
|
248
|
+
| `e2e-ai refine --key X` | Refactor test with AI |
|
|
249
|
+
| `e2e-ai test --key X` | Run Playwright test |
|
|
250
|
+
| `e2e-ai heal --key X` | Auto-fix failing test |
|
|
251
|
+
| `e2e-ai qa --key X` | Generate QA documentation |
|
|
252
|
+
| `e2e-ai run --key X` | Run full pipeline |
|
|
253
|
+
| `e2e-ai scan` | Scan codebase AST |
|
|
254
|
+
| `e2e-ai analyze` | AI feature/scenario analysis |
|
|
255
|
+
| `e2e-ai push` | Push QA map to API |
|