@ai-qa/workflow 2.0.17 → 2.0.18
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/.opencode/qa-workflow-skill.md +232 -0
- package/PROJECT_GUIDE.md +114 -74
- package/install.js +43 -6
- package/opencode.json +6 -0
- package/package.json +9 -3
- package/playwright.config.ts +10 -0
- package/qa-dashboard/app.js +6 -2
- package/qa-dashboard/package.json +4 -1
- package/qa-dashboard/routes/index.js +26 -4
- package/qa-dashboard/routes/projects.js +25 -1
- package/qa-dashboard/routes/runs.js +38 -0
- package/qa-dashboard/routes/stories.js +18 -1
- package/qa-dashboard/routes/terminal.js +51 -0
- package/qa-dashboard/routes/test-data.js +46 -2
- package/qa-dashboard/services/cli-bridge.js +4 -0
- package/qa-dashboard/views/index.ejs +250 -238
- package/qa-dashboard/views/layouts/main.ejs +3 -2
- package/qa-dashboard/views/project.ejs +78 -51
- package/qa-dashboard/views/run.ejs +63 -3
- package/qa-dashboard/views/stories.ejs +36 -12
- package/qa-dashboard/views/story.ejs +125 -86
- package/qa-dashboard/views/terminal.ejs +101 -0
- package/qa-dashboard/views/test-data.ejs +59 -22
- package/router.md +27 -17
- package/test-results/run-2026-05-18T14-51-36/final-test-report.md +10 -2
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-qa-workflow
|
|
3
|
+
description: AI QA Workflow skill — Playwright E2E testing with Allure, Applitools, self-healing, and QA Dashboard integration
|
|
4
|
+
agents: [qa-planner, qa-generator, qa-healer]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AI QA Workflow Skill
|
|
8
|
+
|
|
9
|
+
You are an expert QA automation engineer working on the **AI QA Workflow Template** project.
|
|
10
|
+
|
|
11
|
+
This project has a complete pipeline: user story → test plan → test generation → execution → self-healing → reporting + dashboard.
|
|
12
|
+
|
|
13
|
+
## 1. Project Architecture
|
|
14
|
+
|
|
15
|
+
### Directory Structure
|
|
16
|
+
```
|
|
17
|
+
user-story/ # User stories (input)
|
|
18
|
+
specs/ # Test plans (generated by planner)
|
|
19
|
+
tests/ # Playwright .spec.ts files (generated by generator)
|
|
20
|
+
test-results/ # Run outputs (execution-output.json, execution-result.json, healing-report.json)
|
|
21
|
+
allure-results/ # Allure raw results (generated by allure-playwright reporter)
|
|
22
|
+
qa-dashboard/ # Express dashboard for visualizing results
|
|
23
|
+
scripts/ # Workflow engine (executor.js, reporter.js, healer.js, etc.)
|
|
24
|
+
.opencode/agents/ # Subagent definitions (qa-planner, qa-generator, qa-healer)
|
|
25
|
+
.qa-context/ # Pipeline state, selectors, traceability, heal history
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Pipeline Phases
|
|
29
|
+
1. **Plan** → `specs/<story>.md`
|
|
30
|
+
2. **Generate** → `tests/<story>.spec.ts`
|
|
31
|
+
3. **Execute** → `test-results/run-<timestamp>/`
|
|
32
|
+
4. **Heal** → auto-fix failing tests
|
|
33
|
+
5. **Report** → markdown report + Allure + Dashboard
|
|
34
|
+
|
|
35
|
+
## 2. Playwright Configuration
|
|
36
|
+
|
|
37
|
+
### Required Reporters in `playwright.config.ts`
|
|
38
|
+
```typescript
|
|
39
|
+
reporter: [
|
|
40
|
+
['list'],
|
|
41
|
+
['json', { outputFile: 'test-results/playwright-report.json' }],
|
|
42
|
+
['html', { outputFolder: 'playwright-report' }],
|
|
43
|
+
['allure-playwright'],
|
|
44
|
+
]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The **json** reporter feeds `executor.js` parsing. The **allure-playwright** reporter writes to `allure-results/`. Both are critical.
|
|
48
|
+
|
|
49
|
+
### Output Paths
|
|
50
|
+
- Playwright HTML report: `playwright-report/index.html`
|
|
51
|
+
- JSON results: `test-results/playwright-report.json`
|
|
52
|
+
- Allure results: `allure-results/`
|
|
53
|
+
- Screenshots (on failure): `test-results/screenshots/` or `test-results/run-<id>/`
|
|
54
|
+
|
|
55
|
+
### Running Tests
|
|
56
|
+
| Command | What it does |
|
|
57
|
+
|---------|-------------|
|
|
58
|
+
| `npx playwright test` | Direct run — saves results to JSON, HTML, Allure (via config) |
|
|
59
|
+
| `npm run qa:execute` | Workflow run — saves to `test-results/run-<id>/` with full pipeline tracking |
|
|
60
|
+
| `npm run qa:execute -- <test-name>` | Run a specific test via the workflow |
|
|
61
|
+
|
|
62
|
+
## 3. Executor Compatibility
|
|
63
|
+
|
|
64
|
+
The `scripts/executor.js` parses Playwright's stdout to extract test results.
|
|
65
|
+
|
|
66
|
+
### What the Executor Expects
|
|
67
|
+
- **Passed tests** → lines matching ` √ <test-name>` (checkmark)
|
|
68
|
+
- **Failed tests** → lines matching ` × <test-name>` (cross mark)
|
|
69
|
+
|
|
70
|
+
### Best Practices for Executor-Friendly Tests
|
|
71
|
+
- Use descriptive test names (no special chars that break regex)
|
|
72
|
+
- Keep test names concise
|
|
73
|
+
- Avoid ANSI codes in test names
|
|
74
|
+
- Each `test()` block = 1 scenario in the report
|
|
75
|
+
|
|
76
|
+
## 4. Allure Integration
|
|
77
|
+
|
|
78
|
+
### Reporter Setup
|
|
79
|
+
```typescript
|
|
80
|
+
reporter: [
|
|
81
|
+
['allure-playwright'],
|
|
82
|
+
]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Commands
|
|
86
|
+
```bash
|
|
87
|
+
# Generate HTML report from raw results
|
|
88
|
+
npx allure generate allure-results --clean -o allure-report
|
|
89
|
+
|
|
90
|
+
# Open report in browser
|
|
91
|
+
npx allure open allure-report
|
|
92
|
+
|
|
93
|
+
# Generate and serve on-the-fly
|
|
94
|
+
npx allure serve allure-results
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Allure results are auto-generated by `executor.js` after each workflow run if `allure-commandline` is installed.
|
|
98
|
+
|
|
99
|
+
The QA Dashboard serves Allure reports at `/allure-report?project=<id>`.
|
|
100
|
+
|
|
101
|
+
### Allure Labels (optional enrichment)
|
|
102
|
+
```typescript
|
|
103
|
+
import { allure } from 'allure-playwright';
|
|
104
|
+
|
|
105
|
+
test('login with valid credentials', async ({ page }) => {
|
|
106
|
+
await allure.feature('Authentication');
|
|
107
|
+
await allure.story('User Login');
|
|
108
|
+
await allure.severity('critical');
|
|
109
|
+
// ... test body
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 5. Applitools Eyes — Visual Testing
|
|
114
|
+
|
|
115
|
+
This project integrates `@applitools/eyes-playwright` for visual regression testing.
|
|
116
|
+
|
|
117
|
+
### Setup
|
|
118
|
+
```typescript
|
|
119
|
+
import { BatchInfo, Configuration, EyesRunner, VisualGridRunner } from '@applitools/eyes-playwright';
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Key Practices
|
|
123
|
+
- Use `eyes.open()` with a unique test name
|
|
124
|
+
- Use `eyes.check()` with `Target.window()` or `Target.region()`
|
|
125
|
+
- Use `eyes.close()` to submit results
|
|
126
|
+
- Configure `APPLITOOLS_API_KEY` in `.env`
|
|
127
|
+
|
|
128
|
+
### Applitools MCP Tools Available
|
|
129
|
+
- `eyes_setup_project` — initial setup instructions
|
|
130
|
+
- `eyes_verify_api_key` — validate the API key
|
|
131
|
+
- `eyes_fetch_visual_results` — fetch results after a run
|
|
132
|
+
- `eyes_add_checkpoints_to_test` — add visual checkpoints to existing tests
|
|
133
|
+
- `eyes_analyze_batch` — analyze visual diffs from a batch URL
|
|
134
|
+
|
|
135
|
+
## 6. Self-Healing Patterns
|
|
136
|
+
|
|
137
|
+
Tests must be written to maximize auto-healing success.
|
|
138
|
+
|
|
139
|
+
### DO
|
|
140
|
+
- Use **stable selectors**: `data-testid` > `aria-label` > `role` > `text`
|
|
141
|
+
- Store frequently-used selectors in `.qa-context/selectors.json`
|
|
142
|
+
- Wrap flaky interactions in retry logic (Playwright auto-retries by default)
|
|
143
|
+
- Keep tests **independent** (no shared state)
|
|
144
|
+
- Use `test.beforeEach` for setup, `test.afterEach` for cleanup
|
|
145
|
+
|
|
146
|
+
### AVOID
|
|
147
|
+
- Hardcoded CSS selectors (e.g., `div.container > ul > li:nth-child(3)`)
|
|
148
|
+
- `page.waitForTimeout()` — use auto-waiting instead
|
|
149
|
+
- Fragile text matching (use regex or `toContainText` over `toHaveText`)
|
|
150
|
+
- Tests that depend on execution order (breaks in parallel mode)
|
|
151
|
+
|
|
152
|
+
### Healer Protocol
|
|
153
|
+
1. The healer reads `.qa-context/heal-history.json` to avoid known failures
|
|
154
|
+
2. It uses Playwright MCP to debug and find new selectors
|
|
155
|
+
3. If healing fails after 2 attempts, the test gets `test.fixme()` and is classified as a defect
|
|
156
|
+
4. Updated selectors are saved to `.qa-context/selectors.json`
|
|
157
|
+
|
|
158
|
+
## 7. QA Dashboard
|
|
159
|
+
|
|
160
|
+
The dashboard is an Express + EJS app at `qa-dashboard/`.
|
|
161
|
+
|
|
162
|
+
### Starting the Dashboard
|
|
163
|
+
```bash
|
|
164
|
+
npm run dashboard # Start on port 4000
|
|
165
|
+
npm run dashboard:dev # Dev mode with auto-reload
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Dashboard Pages
|
|
169
|
+
| Route | Content |
|
|
170
|
+
|-------|---------|
|
|
171
|
+
| `/` | Project overview |
|
|
172
|
+
| `/runs` | All test runs with pass/fail/heal stats |
|
|
173
|
+
| `/runs/:runId` | Single run details (output, result, healing report) |
|
|
174
|
+
| `/analytics` | Aggregated analytics (pass rate, heal rate, duration) |
|
|
175
|
+
| `/allure-report` | Allure HTML report viewer |
|
|
176
|
+
| `/stories` | Story traceability |
|
|
177
|
+
|
|
178
|
+
The dashboard auto-shuts down 10s after the browser tab closes.
|
|
179
|
+
|
|
180
|
+
## 8. Agent Routing
|
|
181
|
+
|
|
182
|
+
This project has 3 specialized subagents in `.opencode/agents/`:
|
|
183
|
+
|
|
184
|
+
| Agent | When to use | File |
|
|
185
|
+
|-------|-------------|------|
|
|
186
|
+
| **qa-planner** | Reading user story, exploring website, writing test plan | `.opencode/agents/qa-planner.md` |
|
|
187
|
+
| **qa-generator** | Converting test plan into Playwright `.spec.ts` files | `.opencode/agents/qa-generator.md` |
|
|
188
|
+
| **qa-healer** | Debugging and fixing failing tests | `.opencode/agents/qa-healer.md` |
|
|
189
|
+
|
|
190
|
+
Route user requests to the appropriate agent based on the current pipeline phase.
|
|
191
|
+
|
|
192
|
+
## 9. Test Template (Project-Style)
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { test, expect } from '@playwright/test';
|
|
196
|
+
|
|
197
|
+
test.describe('Feature: <name>', () => {
|
|
198
|
+
test.beforeEach(async ({ page }) => {
|
|
199
|
+
await page.goto('/<path>');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('<description>', async ({ page }) => {
|
|
203
|
+
await page.getByRole('button', { name: '<label>' }).click();
|
|
204
|
+
await expect(page.getByText('<expected>')).toBeVisible();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Tests go directly in `tests/` (flat structure, not nested) and follow the naming convention `<story-name>.spec.ts`.
|
|
210
|
+
|
|
211
|
+
## 10. Quick Reference
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Workflow commands
|
|
215
|
+
npm run qa:plan # Phase 1: Plan
|
|
216
|
+
npm run qa:generate # Phase 2: Generate
|
|
217
|
+
npm run qa:execute # Phase 3: Execute
|
|
218
|
+
npm run qa:heal # Phase 4: Heal
|
|
219
|
+
npm run qa:report # Phase 5: Report
|
|
220
|
+
|
|
221
|
+
# Allure
|
|
222
|
+
npm run qa:report:allure # Generate Allure HTML report
|
|
223
|
+
npx allure serve allure-results # Serve Allure report
|
|
224
|
+
|
|
225
|
+
# Dashboard
|
|
226
|
+
npm run dashboard # Open QA Dashboard at http://localhost:4000
|
|
227
|
+
|
|
228
|
+
# Playwright
|
|
229
|
+
npx playwright test # Run all tests (direct)
|
|
230
|
+
npx playwright test --ui # UI mode
|
|
231
|
+
npx playwright show-report # View Playwright HTML report
|
|
232
|
+
```
|
package/PROJECT_GUIDE.md
CHANGED
|
@@ -1,102 +1,142 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Guide d'utilisation — AI QA Workflow
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Ce document a pour but de vous aider à naviguer dans le projet, comprendre la structure des dossiers et le rôle exact de chaque fichier.
|
|
3
|
+
## 1. Prérequis
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- **IDE avec agent IA** : VS Code (Copilot), Cursor, Codex, OpenCode, Claude Code...
|
|
6
|
+
- **Node.js 18+**
|
|
7
|
+
- Navigateur Chromium
|
|
7
8
|
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
##
|
|
11
|
+
## 2. Créer un dossier de test
|
|
11
12
|
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
```bash
|
|
14
|
+
mkdir mon-projet-qa
|
|
15
|
+
cd mon-projet-qa
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 3. Installer le template
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @ai-qa/workflow init --yes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 4. Installer les dépendances
|
|
29
|
+
|
|
30
|
+
Consultez le fichier `README.md` → section **Dépendances requises** puis installez :
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -D @playwright/test @types/node allure-playwright allure-commandline
|
|
34
|
+
npx playwright install chromium
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 5. Rédiger une User Story
|
|
40
|
+
|
|
41
|
+
Créez un fichier dans le dossier `user-story/` :
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
# US-ALIM-01 : Alimentation de Solde
|
|
45
|
+
|
|
46
|
+
**Rôle** : Agent SB
|
|
47
|
+
**Étapes** :
|
|
48
|
+
- Se connecter
|
|
49
|
+
- Naviguer vers "Demande alimentation et CASH"
|
|
50
|
+
- Saisir Montant=100, Mode=Virement
|
|
51
|
+
- Joindre un fichier, cliquer Suivant
|
|
23
52
|
```
|
|
24
53
|
|
|
25
54
|
---
|
|
26
55
|
|
|
27
|
-
##
|
|
56
|
+
## 6. Lancer le pipeline IA
|
|
57
|
+
|
|
58
|
+
Ouvrez le projet dans votre IDE avec agent IA, puis envoyez ce prompt :
|
|
28
59
|
|
|
29
|
-
|
|
60
|
+
```text
|
|
61
|
+
"Read router.md and follow the QA workflow for user-story/US-ALIM-01.md"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### C'est quoi `router.md` ?
|
|
65
|
+
|
|
66
|
+
Le fichier `router.md` est le **plan de mission** de l'agent IA. Il définit :
|
|
67
|
+
- Les phases du workflow (Environment Check → Plan → Generate → Execute → Heal → Report)
|
|
68
|
+
- Les fichiers agents à utiliser (`playwright-test-planner.agent.md`, etc.)
|
|
69
|
+
- Les règles de validation humaine à chaque étape
|
|
70
|
+
|
|
71
|
+
En bref : **router.md dit à l'IA comment faire son travail.**
|
|
30
72
|
|
|
31
|
-
|
|
32
|
-
* **Rôle :** C'est le chef d'orchestre en ligne de commande. Il intercepte vos commandes (`plan`, `generate`, `execute`, `run`, `heal`) et appelle le bon script dans le dossier `scripts/`.
|
|
73
|
+
---
|
|
33
74
|
|
|
34
|
-
|
|
35
|
-
* **Rôle :** Lit une "User Story" (Markdown) et utilise l'IA pour rédiger un Plan de Test complet (cas nominaux, cas d'erreurs, assertions attendues).
|
|
75
|
+
## 7. Résultat attendu
|
|
36
76
|
|
|
37
|
-
|
|
38
|
-
|
|
77
|
+
L'IA va :
|
|
78
|
+
1. Explorer l'application via le navigateur
|
|
79
|
+
2. Générer un plan de test dans `specs/`
|
|
80
|
+
3. **STOP** → vous validez
|
|
39
81
|
|
|
40
|
-
|
|
41
|
-
* **Rôle :** Lance Playwright sur les tests générés. Il capture les succès, les échecs, la durée, et enregistre un rapport complet (`execution-result.json`) ainsi que les logs bruts (`execution-output.json`).
|
|
82
|
+
---
|
|
42
83
|
|
|
43
|
-
|
|
44
|
-
* **Rôle :** Le module d'auto-guérison (Self-Healing). Si un test échoue, ce script lit la trace d'erreur, l'envoie à l'IA pour comprendre pourquoi (sélecteur cassé, timeout, etc.), corrige le fichier `.spec.ts` et relance le test automatiquement.
|
|
84
|
+
## 8. Superviser chaque étape
|
|
45
85
|
|
|
46
|
-
|
|
47
|
-
|
|
86
|
+
### Phase Plan
|
|
87
|
+
- Vérifiez le fichier `specs/US-ALIM-01-test-plan.md`
|
|
88
|
+
- Approuvez ou demandez des modifications
|
|
48
89
|
|
|
49
|
-
|
|
50
|
-
|
|
90
|
+
### Phase Generate
|
|
91
|
+
- Vérifiez le fichier `tests/US-ALIM-01.spec.ts`
|
|
92
|
+
- Vérifiez les sélecteurs, les assertions
|
|
93
|
+
- Approuvez avant exécution
|
|
51
94
|
|
|
52
95
|
---
|
|
53
96
|
|
|
54
|
-
##
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### Routes (Contrôleurs) (`qa-dashboard/routes/`)
|
|
67
|
-
Chaque fichier gère une page spécifique :
|
|
68
|
-
* **`index.js`** : Page d'accueil, calcule les statistiques globales (taux de succès, nombre de tests).
|
|
69
|
-
* **`stories.js`** : Liste vos User Stories et gère les boutons pour déclencher l'IA (Plan, Generate, Run). C'est lui qui envoie le texte en temps réel à votre navigateur.
|
|
70
|
-
* **`runs.js`** : Gère l'affichage de l'historique des exécutions. Permet de voir un run en cours d'exécution, de lister les succès/échecs et de comparer deux exécutions.
|
|
71
|
-
* **`analytics.js`** : Prépare les données mathématiques pour les graphiques (durée moyenne, taux de healing).
|
|
72
|
-
* **`export.js`** : Transforme vos rapports Markdown en fichiers PDF ou HTML téléchargeables.
|
|
73
|
-
|
|
74
|
-
### Vues (Gabarits HTML/EJS) (`qa-dashboard/views/`)
|
|
75
|
-
Ce sont les interfaces que vous voyez à l'écran, stylisées selon les guidelines "Clay" (esthétique premium, bords arrondis, couleurs vibrantes).
|
|
76
|
-
* **`layouts/main.ejs`** : Le "squelette" de toutes les pages. Contient la barre de navigation, les polices Google (Outfit, Inter) et le script `marked.js` pour rendre le Markdown.
|
|
77
|
-
* **`story.ejs`** : L'écran le plus interactif. Affiche le terminal noir avec le retour de l'IA en direct.
|
|
78
|
-
* **`runs.ejs`** : La liste globale des tests passés.
|
|
79
|
-
* **`run.ejs`** : Le détail d'un seul passage de test (avec les erreurs empilées et le log du healing).
|
|
80
|
-
* **`analytics.ejs`** : Les superbes graphiques Chart.js (rose fluo, vert, etc.).
|
|
81
|
-
|
|
82
|
-
### Styles & Assets (`qa-dashboard/public/`)
|
|
83
|
-
* **`css/style.css`** : Le cœur de l'esthétique du projet (variables CSS, ombres, effets de survol, animations, classes `card-lavender`, `card-peach`, etc.).
|
|
84
|
-
* **`js/main.js`** : Les petits scripts front-end (ex: interactions mineures de l'interface).
|
|
97
|
+
## 9. Exécuter les tests
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npx playwright test tests/US-ALIM-01.spec.ts
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Ou via le pipeline :
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm run qa:execute US-ALIM-01
|
|
107
|
+
```
|
|
85
108
|
|
|
86
109
|
---
|
|
87
110
|
|
|
88
|
-
##
|
|
111
|
+
## 10. Visualiser les résultats
|
|
112
|
+
|
|
113
|
+
### Option A : Rapport Allure
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm run qa:report:allure
|
|
117
|
+
allure open allure-report
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Option B : Dashboard local
|
|
89
121
|
|
|
90
|
-
|
|
122
|
+
```bash
|
|
123
|
+
npm run dashboard
|
|
124
|
+
# → http://localhost:4000
|
|
125
|
+
```
|
|
91
126
|
|
|
92
|
-
|
|
93
|
-
1. Vous ajoutez un fichier `.md` dans le dossier `user-story/` ou vous donnez simplement un lien à votre Agent IA (Copilot, Cursor, OpenCode, Antigravity).
|
|
94
|
-
2. Vous dites à l'Agent dans le chat : *"Teste cette story ou ce lien"*.
|
|
95
|
-
3. L'Agent lit automatiquement son cerveau (`agents/router.md`), allume son navigateur interne via MCP, explore votre site réel, et **génère le plan de test (dans `specs/`) ainsi que le code exact (dans `tests/`)**. Il n'y a plus aucune hallucination de sélecteurs CSS !
|
|
127
|
+
---
|
|
96
128
|
|
|
97
|
-
|
|
98
|
-
4. Une fois que l'Agent a fait le gros du travail de création, vous ouvrez le Dashboard (`http://localhost:4000`).
|
|
99
|
-
5. Vous cliquez sur **Full Pipeline** ou **Execute**. Le script `executor.js` lance Playwright en fond. Si une petite erreur de timing survient, le `healer.js` tente de la corriger.
|
|
100
|
-
6. Les résultats JSON atterrissent dans `test-results/`.
|
|
101
|
-
7. Vous naviguez dans **Runs** ou **Analytics**, pour voir l'historique complet, les rapports PDF/HTML et les graphiques de qualité !
|
|
129
|
+
## Résumé du workflow
|
|
102
130
|
|
|
131
|
+
```text
|
|
132
|
+
1. Prérequis (IDE + Node.js)
|
|
133
|
+
2. Dossier de test
|
|
134
|
+
3. npx init
|
|
135
|
+
4. npm install dépendances
|
|
136
|
+
5. User story → user-story/
|
|
137
|
+
6. Prompt : "Read router.md..."
|
|
138
|
+
7. L'IA explore + plan → specs/ ← vous validez
|
|
139
|
+
8. L'IA génère tests → tests/ ← vous validez
|
|
140
|
+
9. npx playwright test
|
|
141
|
+
10. allure open ou npm run dashboard
|
|
142
|
+
```
|
package/install.js
CHANGED
|
@@ -8,6 +8,7 @@ const TEMPLATE_DIR = __dirname;
|
|
|
8
8
|
const YES = process.argv.includes('--yes') || process.argv.includes('-y');
|
|
9
9
|
const IS_UPDATE = process.argv.includes('--update') || process.argv.includes('-u');
|
|
10
10
|
const IS_SELF = process.argv.includes('--self') || process.argv.includes('-s');
|
|
11
|
+
const IS_FORCE = process.argv.includes('--force') || process.argv.includes('-f');
|
|
11
12
|
|
|
12
13
|
// Files that belong to the user — NEVER overwritten
|
|
13
14
|
const USER_FILES = new Set([
|
|
@@ -53,8 +54,8 @@ const QA_ITEMS = [
|
|
|
53
54
|
|
|
54
55
|
];
|
|
55
56
|
|
|
56
|
-
// Files to copy even during update (excludes user config files)
|
|
57
|
-
const UPDATE_ITEMS = QA_ITEMS.filter(item => {
|
|
57
|
+
// Files to copy even during update (excludes user config files unless --force)
|
|
58
|
+
const UPDATE_ITEMS = IS_FORCE ? QA_ITEMS : QA_ITEMS.filter(item => {
|
|
58
59
|
if (item.dir) return !USER_DIRS.has(item.dest);
|
|
59
60
|
return !USER_FILES.has(item.dest);
|
|
60
61
|
});
|
|
@@ -76,7 +77,7 @@ function copyRecursive(src, dest, skipDirs) {
|
|
|
76
77
|
if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
|
|
77
78
|
fs.readdirSync(src).forEach(item => copyRecursive(path.join(src, item), path.join(dest, item), skipDirs));
|
|
78
79
|
} else {
|
|
79
|
-
if (!fs.existsSync(dest) || fs.readFileSync(src).
|
|
80
|
+
if (!fs.existsSync(dest) || !fs.readFileSync(src).equals(fs.readFileSync(dest))) {
|
|
80
81
|
fs.copyFileSync(src, dest);
|
|
81
82
|
return true;
|
|
82
83
|
}
|
|
@@ -128,6 +129,28 @@ async function install(targetPath, mode) {
|
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
// Warn about protected user files not updated during update
|
|
133
|
+
if (isUpdate && !IS_FORCE) {
|
|
134
|
+
const skipped = QA_ITEMS.filter(item => {
|
|
135
|
+
if (item.dir) return USER_DIRS.has(item.dest);
|
|
136
|
+
return USER_FILES.has(item.dest);
|
|
137
|
+
});
|
|
138
|
+
if (skipped.length) {
|
|
139
|
+
console.log(`\n ── Protected files (use --force to overwrite) ──`);
|
|
140
|
+
for (const item of skipped) {
|
|
141
|
+
const srcStat = fs.existsSync(path.join(TEMPLATE_DIR, item.src));
|
|
142
|
+
const destStat = fs.existsSync(path.join(targetPath, item.dest));
|
|
143
|
+
if (srcStat && destStat) {
|
|
144
|
+
const changed = !fs.readFileSync(path.join(TEMPLATE_DIR, item.src))
|
|
145
|
+
.equals(fs.readFileSync(path.join(targetPath, item.dest)));
|
|
146
|
+
if (changed) {
|
|
147
|
+
console.log(` ⚠ ${item.dest} (modified locally, skipped)`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
131
154
|
// 2. Create directories (fresh install only)
|
|
132
155
|
if (!isUpdate) {
|
|
133
156
|
console.log(`\n ── Step 2: Project Directories ──`);
|
|
@@ -163,11 +186,20 @@ async function install(targetPath, mode) {
|
|
|
163
186
|
try { execSync('npm install', { cwd: dashboardDest, stdio: 'pipe', timeout: 120000 }); console.log(` ✓ Dashboard deps installed`); } catch (e) { console.log(` ⚠ cd qa-dashboard && npm install`); }
|
|
164
187
|
} else {
|
|
165
188
|
const skipDirs = new Set(['node_modules', 'data']);
|
|
189
|
+
|
|
190
|
+
// Detect if dashboard package.json changed
|
|
191
|
+
const dashPkgSrc = path.join(dashboardSrc, 'package.json');
|
|
192
|
+
const dashPkgDest = path.join(dashboardDest, 'package.json');
|
|
193
|
+
const pkgChanged = fs.existsSync(dashPkgSrc) && fs.existsSync(dashPkgDest) &&
|
|
194
|
+
!fs.readFileSync(dashPkgSrc).equals(fs.readFileSync(dashPkgDest));
|
|
195
|
+
|
|
166
196
|
copyRecursive(dashboardSrc, dashboardDest, skipDirs);
|
|
167
197
|
console.log(` ✓ Dashboard updated (preserved data/, node_modules/)`);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
198
|
+
|
|
199
|
+
const needsInstall = !isUpdate || pkgChanged;
|
|
200
|
+
if (needsInstall) {
|
|
201
|
+
console.log(` → ${pkgChanged ? 'package.json changed, updating' : 'Installing'} dashboard dependencies...`);
|
|
202
|
+
try { execSync('npm install', { cwd: dashboardDest, stdio: 'pipe', timeout: 120000 }); console.log(` ✓ Dashboard deps ${pkgChanged ? 'updated' : 'installed'}`); } catch (e) { console.log(` ⚠ cd qa-dashboard && npm install`); }
|
|
171
203
|
}
|
|
172
204
|
}
|
|
173
205
|
}
|
|
@@ -211,6 +243,7 @@ async function install(targetPath, mode) {
|
|
|
211
243
|
|
|
212
244
|
if (isUpdate) {
|
|
213
245
|
console.log(` Pipeline files updated. Your config and data are preserved.`);
|
|
246
|
+
if (!IS_FORCE) console.log(` Use --force to overwrite protected files (package.json, .qa-workflow.json, etc.)`);
|
|
214
247
|
console.log(` Restart the dashboard if it was running.\n`);
|
|
215
248
|
} else {
|
|
216
249
|
console.log(` Files: ~${totalFiles} scripts + ${dashboardCount} dashboard files`);
|
|
@@ -220,6 +253,7 @@ async function install(targetPath, mode) {
|
|
|
220
253
|
console.log(` npm run qa:init Initialize pipeline (config + dirs + auth)`);
|
|
221
254
|
console.log(` npm run qa:execute Run Playwright tests (auto-generates Allure report)`);
|
|
222
255
|
console.log(` npm run qa:status Check pipeline state`);
|
|
256
|
+
console.log(` npm run qa:update Update pipeline files from template`);
|
|
223
257
|
console.log(` npm run dashboard Start dashboard (port 4000)\n`);
|
|
224
258
|
}
|
|
225
259
|
}
|
|
@@ -246,11 +280,14 @@ AI QA Pipeline Installer
|
|
|
246
280
|
FLAGS:
|
|
247
281
|
--yes, -y Skip all prompts
|
|
248
282
|
--update,-u Update mode (preserves config, stories, results)
|
|
283
|
+
--force,-f Overwrite protected user files (package.json, .qa-workflow.json, ...)
|
|
249
284
|
|
|
250
285
|
EXAMPLES:
|
|
251
286
|
npx ai-qa-workflow init --yes
|
|
287
|
+
npx ai-qa-workflow update Update pipeline in current project
|
|
252
288
|
node install.js ../my-project --yes
|
|
253
289
|
node install.js ../my-project --update
|
|
290
|
+
node install.js ../my-project --update --force
|
|
254
291
|
`);
|
|
255
292
|
process.exit(0);
|
|
256
293
|
}
|
package/opencode.json
CHANGED
|
@@ -23,6 +23,12 @@
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
|
+
"skill": {
|
|
27
|
+
"ai-qa-workflow": {
|
|
28
|
+
"description": "AI QA Workflow skill — Playwright E2E testing with Allure, Applitools, self-healing, and QA Dashboard integration. Use when writing, debugging, or reviewing tests in this project.",
|
|
29
|
+
"file": ".opencode/qa-workflow-skill.md"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
26
32
|
"agent": {
|
|
27
33
|
"qa-planner": {
|
|
28
34
|
"description": "Reads user story, explores website via Playwright MCP, creates test plan in specs/",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-qa/workflow",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.18",
|
|
4
4
|
"description": "AI QA Workflow Template — transforms any AI agent into an autonomous QA engineer. AI explores, plans, generates tests, and heals. Scripts execute and report.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"qa",
|
|
@@ -59,9 +59,15 @@
|
|
|
59
59
|
"qa:report:allure": "node ai-qa-workflow.js report:allure",
|
|
60
60
|
"qa:status": "node ai-qa-workflow.js status",
|
|
61
61
|
"qa:list": "node ai-qa-workflow.js list",
|
|
62
|
+
"qa:update": "node install.js . --update --yes",
|
|
62
63
|
"dashboard": "cd qa-dashboard && npm start",
|
|
63
64
|
"dashboard:dev": "cd qa-dashboard && npx nodemon app.js",
|
|
64
|
-
"dashboard:stop": "npx kill-port 4000"
|
|
65
|
+
"dashboard:stop": "npx kill-port 4000",
|
|
66
|
+
"allure:generate": "allure generate allure-results -o allure-report --clean",
|
|
67
|
+
"allure:open": "allure open allure-report",
|
|
68
|
+
"allure:serve": "allure serve allure-results"
|
|
65
69
|
},
|
|
66
|
-
"devDependencies": {
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/node": "^25.9.2"
|
|
72
|
+
}
|
|
67
73
|
}
|
package/playwright.config.ts
CHANGED
|
@@ -6,6 +6,16 @@ export default defineConfig({
|
|
|
6
6
|
forbidOnly: !!process.env.CI,
|
|
7
7
|
retries: process.env.CI ? 2 : 0,
|
|
8
8
|
workers: process.env.CI ? 1 : undefined,
|
|
9
|
+
reporter: [
|
|
10
|
+
['list'],
|
|
11
|
+
['json', { outputFile: 'test-results/playwright-report.json' }],
|
|
12
|
+
['html', { outputFolder: 'playwright-report' }],
|
|
13
|
+
['allure-playwright', {
|
|
14
|
+
outputFolder: 'allure-results',
|
|
15
|
+
detail: true,
|
|
16
|
+
}],
|
|
17
|
+
],
|
|
18
|
+
|
|
9
19
|
use: {
|
|
10
20
|
baseURL: process.env.APP_URL || 'http://localhost:3000',
|
|
11
21
|
trace: 'on-first-retry',
|
package/qa-dashboard/app.js
CHANGED
|
@@ -89,11 +89,15 @@ app.use('/runs', require('./routes/runs'));
|
|
|
89
89
|
app.use('/review', require('./routes/review'));
|
|
90
90
|
app.use('/analytics', require('./routes/analytics'));
|
|
91
91
|
app.use('/export', require('./routes/export'));
|
|
92
|
+
app.use('/terminal', require('./routes/terminal'));
|
|
92
93
|
app.use('/data', require('./routes/test-data'));
|
|
93
94
|
|
|
94
95
|
app.use((req, res) => { res.status(404).render('error', { message: 'Page not found' }); });
|
|
95
96
|
|
|
96
97
|
app.listen(PORT, () => {
|
|
97
|
-
console.log(
|
|
98
|
-
console.log(`
|
|
98
|
+
console.log(`\n ┌─────────────────────────────────────┐`);
|
|
99
|
+
console.log(` │ Orchestrator QA Dashboard │`);
|
|
100
|
+
console.log(` │ http://localhost:${PORT}${' '.repeat(9 - String(PORT).length)}│`);
|
|
101
|
+
console.log(` └─────────────────────────────────────┘`);
|
|
102
|
+
console.log(` Close the browser tab to stop the server.\n`);
|
|
99
103
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "node app.js",
|
|
8
|
-
"dev": "
|
|
8
|
+
"dev": "nodemon app.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"chart.js": "^4.4.0",
|
|
@@ -14,5 +14,8 @@
|
|
|
14
14
|
"express": "^4.18.2",
|
|
15
15
|
"express-ejs-layouts": "^2.5.1",
|
|
16
16
|
"morgan": "^1.10.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"nodemon": "^3.1.0"
|
|
17
20
|
}
|
|
18
21
|
}
|