@quanticjs/create-app 0.1.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/dist/deps.d.ts +4 -0
- package/dist/deps.js +97 -0
- package/dist/deps.js.map +1 -0
- package/dist/generators/backend.d.ts +2 -0
- package/dist/generators/backend.js +20 -0
- package/dist/generators/backend.js.map +1 -0
- package/dist/generators/bff.d.ts +2 -0
- package/dist/generators/bff.js +9 -0
- package/dist/generators/bff.js.map +1 -0
- package/dist/generators/claude.d.ts +2 -0
- package/dist/generators/claude.js +45 -0
- package/dist/generators/claude.js.map +1 -0
- package/dist/generators/docker.d.ts +2 -0
- package/dist/generators/docker.js +10 -0
- package/dist/generators/docker.js.map +1 -0
- package/dist/generators/e2e.d.ts +2 -0
- package/dist/generators/e2e.js +8 -0
- package/dist/generators/e2e.js.map +1 -0
- package/dist/generators/frontend.d.ts +2 -0
- package/dist/generators/frontend.js +28 -0
- package/dist/generators/frontend.js.map +1 -0
- package/dist/generators/module.d.ts +2 -0
- package/dist/generators/module.js +35 -0
- package/dist/generators/module.js.map +1 -0
- package/dist/generators/root.d.ts +2 -0
- package/dist/generators/root.js +7 -0
- package/dist/generators/root.js.map +1 -0
- package/dist/generators/scripts.d.ts +2 -0
- package/dist/generators/scripts.js +10 -0
- package/dist/generators/scripts.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +8 -0
- package/dist/prompts.js +53 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scaffold.d.ts +2 -0
- package/dist/scaffold.js +79 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/utils/exec.d.ts +2 -0
- package/dist/utils/exec.js +14 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/template.d.ts +10 -0
- package/dist/utils/template.js +20 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/validate.d.ts +4 -0
- package/dist/utils/validate.js +27 -0
- package/dist/utils/validate.js.map +1 -0
- package/package.json +50 -0
- package/templates/backend/app.module.ts.ejs +61 -0
- package/templates/backend/bff.controller.ts.ejs +60 -0
- package/templates/backend/bff.module.ts.ejs +10 -0
- package/templates/backend/bff.service.ts.ejs +6 -0
- package/templates/backend/create-schema.migration.ts.ejs +15 -0
- package/templates/backend/data-source.ts.ejs +13 -0
- package/templates/backend/env.example.ejs +30 -0
- package/templates/backend/main.ts.ejs +43 -0
- package/templates/backend/module.ts.ejs +14 -0
- package/templates/backend/nest-cli.json.ejs +8 -0
- package/templates/backend/package.json.ejs +23 -0
- package/templates/backend/tsconfig.build.json.ejs +4 -0
- package/templates/backend/tsconfig.json.ejs +24 -0
- package/templates/claude/CLAUDE.md.ejs +86 -0
- package/templates/claude/hooks/auto-format.sh +22 -0
- package/templates/claude/hooks/check-secrets.sh +49 -0
- package/templates/claude/hooks/guard-destructive.sh +42 -0
- package/templates/claude/hooks/on-compaction.sh +29 -0
- package/templates/claude/mcp.json +10 -0
- package/templates/claude/rules/api-patterns.md +86 -0
- package/templates/claude/rules/auth-patterns.md +109 -0
- package/templates/claude/rules/backend-patterns.md +421 -0
- package/templates/claude/rules/database-patterns.md +96 -0
- package/templates/claude/rules/docker-patterns.md +86 -0
- package/templates/claude/rules/frontend-patterns.md +262 -0
- package/templates/claude/rules/observability-backend.md +132 -0
- package/templates/claude/rules/observability-frontend.md +49 -0
- package/templates/claude/rules/playwright-mcp.md +80 -0
- package/templates/claude/rules/resilience-ops.md +103 -0
- package/templates/claude/rules/testing-e2e-ui.md +190 -0
- package/templates/claude/rules/testing-patterns.md +94 -0
- package/templates/claude/rules/workflow-backend.md +64 -0
- package/templates/claude/rules/workflow-frontend.md +60 -0
- package/templates/claude/settings.json +68 -0
- package/templates/claude/skills/add-api-endpoint/SKILL.md +59 -0
- package/templates/claude/skills/add-auth-endpoint/SKILL.md +68 -0
- package/templates/claude/skills/add-entity/SKILL.md +56 -0
- package/templates/claude/skills/add-event/SKILL.md +127 -0
- package/templates/claude/skills/add-feature/SKILL.md +20 -0
- package/templates/claude/skills/add-frontend-page/SKILL.md +75 -0
- package/templates/claude/skills/add-handler/SKILL.md +105 -0
- package/templates/claude/skills/add-integration/SKILL.md +176 -0
- package/templates/claude/skills/add-migration/SKILL.md +20 -0
- package/templates/claude/skills/add-module/SKILL.md +89 -0
- package/templates/claude/skills/add-realtime/SKILL.md +119 -0
- package/templates/claude/skills/audit-rules/SKILL.md +120 -0
- package/templates/claude/skills/debugging/SKILL.md +105 -0
- package/templates/claude/skills/docker-dev/SKILL.md +86 -0
- package/templates/claude/skills/e2e-audit/SKILL.md +85 -0
- package/templates/claude/skills/e2e-full/SKILL.md +132 -0
- package/templates/claude/skills/e2e-scan/SKILL.md +171 -0
- package/templates/claude/skills/e2e-verify/SKILL.md +145 -0
- package/templates/claude/skills/fix-bug/SKILL.md +33 -0
- package/templates/claude/skills/implement-spec/SKILL.md +98 -0
- package/templates/claude/skills/review-code/SKILL.md +109 -0
- package/templates/claude/skills/review-spec/SKILL.md +216 -0
- package/templates/claude/skills/run-tests/SKILL.md +37 -0
- package/templates/claude/skills/specify/SKILL.md +87 -0
- package/templates/claude/skills/write-backend-tests/SKILL.md +182 -0
- package/templates/claude/skills/write-ui-tests/SKILL.md +118 -0
- package/templates/docker/Dockerfile.client.ejs +14 -0
- package/templates/docker/Dockerfile.ejs +28 -0
- package/templates/docker/docker-compose.test.yml.ejs +54 -0
- package/templates/docker/docker-compose.yml.ejs +76 -0
- package/templates/docker/nginx.conf.ejs +21 -0
- package/templates/frontend/App.tsx.ejs +64 -0
- package/templates/frontend/DashboardPage.tsx.ejs +37 -0
- package/templates/frontend/LoginPage.tsx.ejs +20 -0
- package/templates/frontend/NotFoundPage.tsx.ejs +15 -0
- package/templates/frontend/api-client.ts.ejs +15 -0
- package/templates/frontend/index.css.ejs +57 -0
- package/templates/frontend/index.html.ejs +13 -0
- package/templates/frontend/main.tsx.ejs +10 -0
- package/templates/frontend/package.json.ejs +16 -0
- package/templates/frontend/playwright.config.ts.ejs +20 -0
- package/templates/frontend/postcss.config.js.ejs +3 -0
- package/templates/frontend/smoke.spec.ts.ejs +37 -0
- package/templates/frontend/tailwind.config.ts.ejs +56 -0
- package/templates/frontend/tsconfig.json.ejs +25 -0
- package/templates/frontend/tsconfig.node.json.ejs +15 -0
- package/templates/frontend/utils.ts.ejs +6 -0
- package/templates/frontend/vite-env.d.ts.ejs +1 -0
- package/templates/frontend/vite.config.ts.ejs +20 -0
- package/templates/root/gitignore.ejs +9 -0
- package/templates/root/prettierrc.ejs +7 -0
- package/templates/scripts/init-db.sh.ejs +8 -0
- package/templates/scripts/save-auth-state.ts.ejs +24 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Docker Dev Environment
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
```
|
|
5
|
+
Backend (NestJS) → Docker Compose (volume-mounted, watch mode)
|
|
6
|
+
Frontend (Vite) → Native on host (NOT in Docker — HMR reliability)
|
|
7
|
+
Infrastructure → Docker internal network (no ports exposed except API + Keycloak)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Commands
|
|
11
|
+
| Action | Command |
|
|
12
|
+
|--------|---------|
|
|
13
|
+
| Start all | `docker compose up` |
|
|
14
|
+
| Start with rebuild | `docker compose up --build` |
|
|
15
|
+
| Start backend only | `docker compose up backend` |
|
|
16
|
+
| View logs | `docker compose logs -f backend` |
|
|
17
|
+
| Stop all | `docker compose down` |
|
|
18
|
+
| Reset data | `docker compose down -v && docker compose up` |
|
|
19
|
+
| Shell into container | `docker compose exec backend sh` |
|
|
20
|
+
| Check health | `docker compose ps` |
|
|
21
|
+
|
|
22
|
+
## Ports (exposed to host)
|
|
23
|
+
| Port | Service | Purpose |
|
|
24
|
+
|------|---------|---------|
|
|
25
|
+
| 3000 | Backend API | Vite proxies `/api/*` and `/auth/*` here |
|
|
26
|
+
| 8080 | Keycloak | OIDC browser redirects require direct access |
|
|
27
|
+
| 5173 | Vite (native) | Frontend dev server — NOT in Docker |
|
|
28
|
+
|
|
29
|
+
All other infrastructure (PostgreSQL, Redis, ELK, etc.) stays on Docker's internal network with no host ports.
|
|
30
|
+
|
|
31
|
+
## Daily Workflow
|
|
32
|
+
```bash
|
|
33
|
+
# Terminal 1: Backend + infrastructure
|
|
34
|
+
docker compose up
|
|
35
|
+
|
|
36
|
+
# Terminal 2: Frontend (native Vite)
|
|
37
|
+
cd client && npm run dev
|
|
38
|
+
|
|
39
|
+
# Browser: http://localhost:5173
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Troubleshooting
|
|
43
|
+
|
|
44
|
+
### Container won't start
|
|
45
|
+
```bash
|
|
46
|
+
docker compose logs <service> --tail=50
|
|
47
|
+
docker compose ps # check health status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Database issues
|
|
51
|
+
```bash
|
|
52
|
+
docker compose exec postgres psql -U postgres -d autoflux
|
|
53
|
+
npx typeorm migration:show # check pending migrations
|
|
54
|
+
npx typeorm migration:run # apply pending
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Redis issues
|
|
58
|
+
```bash
|
|
59
|
+
docker compose exec redis redis-cli PING
|
|
60
|
+
docker compose exec redis redis-cli MONITOR # watch all commands
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Port conflicts
|
|
64
|
+
```bash
|
|
65
|
+
lsof -i :3000 # find what's using the port
|
|
66
|
+
docker compose down && docker compose up # restart clean
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Volume mount not syncing
|
|
70
|
+
```bash
|
|
71
|
+
docker compose restart backend # force re-read of mounted source
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Adding Infrastructure
|
|
75
|
+
1. Add service to `docker-compose.yml` with healthcheck
|
|
76
|
+
2. Add to backend `depends_on` with `condition: service_healthy`
|
|
77
|
+
3. Use Docker hostname in backend config (e.g., `postgres`, `redis`) — NOT `localhost`
|
|
78
|
+
4. Do NOT expose port to host unless absolutely required
|
|
79
|
+
|
|
80
|
+
## Rules
|
|
81
|
+
- NEVER run Vite inside Docker — HMR is unreliable with volume mounts
|
|
82
|
+
- NEVER expose infrastructure ports to host (except Keycloak for OIDC redirects)
|
|
83
|
+
- NEVER hardcode API URLs in frontend — use relative paths (`/api/...`)
|
|
84
|
+
- NEVER use `docker compose up` for tests — use `docker-compose.test.yml`
|
|
85
|
+
- NEVER run services as root in production images
|
|
86
|
+
- Backend uses Docker hostnames (`postgres`, `redis`, `keycloak`) — NOT `localhost`
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# E2E Audit — Verify Existing Specs Against Real Pages
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/e2e-audit # Audit all specs
|
|
6
|
+
/e2e-audit client/e2e/projects-list.spec.ts # Audit one spec
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## What this does
|
|
10
|
+
|
|
11
|
+
For each spec file in `client/e2e/`, open the corresponding page via Playwright MCP and compare what's on screen vs what the spec tests. Report gaps and fix them.
|
|
12
|
+
|
|
13
|
+
**Announce "using Playwright MCP" before the first `browser_navigate`.**
|
|
14
|
+
|
|
15
|
+
## Reproducing Failing Coded Specs
|
|
16
|
+
|
|
17
|
+
If a coded spec in `client/e2e/` is failing in CI, do NOT guess at the fix from the stack trace alone. Open the exact route via MCP, read the accessibility tree, and diff it against the selectors in the failing test. Paste the a11y snapshot into the fix commit message so the next reviewer can see what the live DOM looked like.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
1. Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
|
|
22
|
+
2. Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
|
|
23
|
+
3. Auth state saved (or authenticate via MCP on first `browser_navigate`)
|
|
24
|
+
|
|
25
|
+
**IMPORTANT:** Always use the isolated test stack (`docker-compose.test.yml`) — NEVER `docker compose up` against the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
|
|
26
|
+
|
|
27
|
+
## Base URL
|
|
28
|
+
|
|
29
|
+
`http://localhost:5199`
|
|
30
|
+
|
|
31
|
+
## Process per spec file
|
|
32
|
+
|
|
33
|
+
### 1. Read the spec
|
|
34
|
+
Read the spec file. Note which route it tests, what selectors it uses, and which states it covers.
|
|
35
|
+
|
|
36
|
+
### 2. Open the page via MCP
|
|
37
|
+
- `browser_navigate` to the route
|
|
38
|
+
- `browser_screenshot` to see the current layout
|
|
39
|
+
- Read the accessibility tree
|
|
40
|
+
|
|
41
|
+
### 3. Compare and report
|
|
42
|
+
|
|
43
|
+
For each spec, check:
|
|
44
|
+
|
|
45
|
+
| Check | Pass/Fail |
|
|
46
|
+
|-------|-----------|
|
|
47
|
+
| **All 4 states tested?** (happy, error, empty, loading) | |
|
|
48
|
+
| **Selectors match real elements?** (heading text, button labels, etc.) | |
|
|
49
|
+
| **No stale selectors?** (elements that no longer exist) | |
|
|
50
|
+
| **No missing elements?** (interactive elements on page not tested) | |
|
|
51
|
+
| **Auth boundary tested?** (unauthenticated redirect) | |
|
|
52
|
+
| **No anti-patterns?** (CSS selectors, waitForTimeout, isVisible().toBe(true)) | |
|
|
53
|
+
|
|
54
|
+
### 4. Fix issues found
|
|
55
|
+
- Update stale selectors to match current accessibility tree
|
|
56
|
+
- Add missing state tests (error, empty, loading)
|
|
57
|
+
- Remove tests for elements that no longer exist
|
|
58
|
+
- Add tests for new elements discovered via MCP
|
|
59
|
+
|
|
60
|
+
## Spec files to audit
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
client/e2e/login.spec.ts
|
|
64
|
+
client/e2e/dashboard.spec.ts
|
|
65
|
+
client/e2e/projects-list.spec.ts
|
|
66
|
+
client/e2e/create-project.spec.ts
|
|
67
|
+
client/e2e/project-detail.spec.ts
|
|
68
|
+
client/e2e/prompt-templates.spec.ts
|
|
69
|
+
client/e2e/profile.spec.ts
|
|
70
|
+
client/e2e/settings.spec.ts
|
|
71
|
+
client/e2e/users.spec.ts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Output format
|
|
75
|
+
|
|
76
|
+
Print a summary table at the end:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
| Spec | 4 States | Selectors OK | Anti-patterns | Action |
|
|
80
|
+
|------|----------|--------------|---------------|--------|
|
|
81
|
+
| login.spec.ts | 3/4 (missing empty) | OK | None | N/A — no data endpoint |
|
|
82
|
+
| dashboard.spec.ts | 2/4 | OK | .animate-spin | Added loading test |
|
|
83
|
+
| projects-list.spec.ts | 4/4 | 1 stale | None | Fixed heading selector |
|
|
84
|
+
| ... | ... | ... | ... | ... |
|
|
85
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# E2E Full — Orchestrated Test Suite
|
|
2
|
+
|
|
3
|
+
Run all E2E skills in the correct sequence. Each phase feeds into the next.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
- `/e2e-full` — run all 3 phases in order
|
|
8
|
+
- `/e2e-full scan` — run only the scan phase
|
|
9
|
+
- `/e2e-full audit` — run only the audit phase
|
|
10
|
+
- `/e2e-full verify` — run only the verify phase
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- Base URL: `http://localhost:5199`
|
|
15
|
+
- Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
|
|
16
|
+
- Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
|
|
17
|
+
|
|
18
|
+
Phase 0 handles the rest automatically.
|
|
19
|
+
|
|
20
|
+
**IMPORTANT:** E2E tests MUST use the isolated test stack (`docker-compose.test.yml`) with separate ports — NEVER the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
|
|
21
|
+
|
|
22
|
+
## Execution Order
|
|
23
|
+
|
|
24
|
+
### Phase 0: Clean Stack (automatic)
|
|
25
|
+
|
|
26
|
+
**Purpose:** Guarantee a clean database, fresh containers, and a working MCP toolchain before any test phase runs.
|
|
27
|
+
|
|
28
|
+
1. **MCP preflight** — verify the toolchain before touching Docker:
|
|
29
|
+
- `node --version` must report **v18 or higher**
|
|
30
|
+
- Confirm `.claude/mcp.json` pins a specific `@playwright/mcp` version (NOT `@latest`)
|
|
31
|
+
- Run `npx playwright install` to ensure browser binaries match the pinned MCP version
|
|
32
|
+
2. Tear down any existing test stack:
|
|
33
|
+
```bash
|
|
34
|
+
docker compose -f docker-compose.test.yml down -v
|
|
35
|
+
```
|
|
36
|
+
3. Rebuild and start the test stack:
|
|
37
|
+
```bash
|
|
38
|
+
docker compose -f docker-compose.test.yml up -d --build
|
|
39
|
+
```
|
|
40
|
+
4. Wait for all services to be healthy (postgres, redis, keycloak, backend)
|
|
41
|
+
5. Start frontend dev server on test port:
|
|
42
|
+
```bash
|
|
43
|
+
cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199 &
|
|
44
|
+
```
|
|
45
|
+
6. Save auth state for MCP journeys (against test stack):
|
|
46
|
+
```bash
|
|
47
|
+
cd client && KEYCLOAK_PORT=8099 API_PORT=3099 npx tsx ../scripts/save-auth-state.ts
|
|
48
|
+
```
|
|
49
|
+
7. **MCP smoke test** — before declaring Phase 0 done, `browser_navigate` to `http://localhost:5199/` and confirm the accessibility tree returns. If MCP tools don't respond, STOP and report the MCP failure rather than running journeys blind.
|
|
50
|
+
|
|
51
|
+
**Stop condition:** If any service fails to become healthy within 3 minutes, STOP and report which service is unhealthy. Do not proceed to Phase 1. If the MCP smoke test fails, STOP — re-check `.claude/mcp.json` and Node version.
|
|
52
|
+
|
|
53
|
+
**Output:** Service health status table.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Phase 1: Scan (`/e2e-scan`)
|
|
58
|
+
|
|
59
|
+
**Purpose:** Find missing journey coverage before testing.
|
|
60
|
+
|
|
61
|
+
1. Load `/e2e-scan` skill
|
|
62
|
+
2. Execute the scan — it reads routes, forms, hooks, and diffs against existing specs in `client/e2e/`
|
|
63
|
+
3. If gaps are found, the scan generates missing spec files
|
|
64
|
+
|
|
65
|
+
**Stop condition:** None — scan always completes. Report any gaps found.
|
|
66
|
+
|
|
67
|
+
**Output:** Gap report table + list of specs generated (if any).
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Phase 2: Audit (`/e2e-audit`)
|
|
72
|
+
|
|
73
|
+
**Purpose:** Verify Playwright spec files match the real UI after code changes.
|
|
74
|
+
|
|
75
|
+
1. Load `/e2e-audit` skill
|
|
76
|
+
2. For each spec file in `client/e2e/`, open the page via MCP and compare selectors against the accessibility tree
|
|
77
|
+
3. Report stale selectors, missing state tests, anti-patterns
|
|
78
|
+
|
|
79
|
+
**Stop condition:** None — audit always completes. Report all findings.
|
|
80
|
+
|
|
81
|
+
**Output:** Per-spec table with status (OK / STALE / MISSING) and recommended fixes.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Phase 3: Verify (`/e2e-verify`)
|
|
86
|
+
|
|
87
|
+
**Purpose:** Walk through all user journeys and confirm pages render, forms work, navigation flows.
|
|
88
|
+
|
|
89
|
+
1. Load `/e2e-verify` skill
|
|
90
|
+
2. Execute ALL journeys (currently 10) — do not stop early
|
|
91
|
+
3. Report each journey as PASS / FAIL / SKIP / UNTESTED
|
|
92
|
+
|
|
93
|
+
**Stop condition:** If more than 3 journeys FAIL, stop and report. Likely a systemic issue (auth expired, server down) rather than individual bugs.
|
|
94
|
+
|
|
95
|
+
**Session recovery:** If any journey redirects to `/login` unexpectedly mid-run, the storage state has expired. Re-run `cd client && npx tsx ../scripts/save-auth-state.ts` and retry the failed journey ONCE before marking it FAIL.
|
|
96
|
+
|
|
97
|
+
**Output:** Completion checklist table with result per journey.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Final Report
|
|
102
|
+
|
|
103
|
+
After all phases complete, produce a summary:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
## E2E Full Run Summary
|
|
107
|
+
|
|
108
|
+
| Phase | Status | Details |
|
|
109
|
+
|-------|--------|---------|
|
|
110
|
+
| 0. Clean Stack | DONE | test stack down -v + up --build, all services healthy |
|
|
111
|
+
| 1. Scan | DONE | X gaps found, Y specs generated |
|
|
112
|
+
| 2. Audit | DONE | X specs OK, Y stale, Z missing |
|
|
113
|
+
| 3. Verify | DONE | X pass, Y fail, Z skip |
|
|
114
|
+
|
|
115
|
+
### Failed Journeys (action required)
|
|
116
|
+
- [Phase 3] Journey #N: <name> — <what failed>
|
|
117
|
+
|
|
118
|
+
### Stale Specs (action required)
|
|
119
|
+
- <spec file> — <selector> no longer matches
|
|
120
|
+
|
|
121
|
+
### Gaps Added (review recommended)
|
|
122
|
+
- <spec file> generated for <route>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Rules
|
|
126
|
+
|
|
127
|
+
- **NEVER skip Phase 0.** Every `/e2e-full` run starts with a clean `docker compose -f docker-compose.test.yml down -v` + `up --build`. Stale data causes false passes.
|
|
128
|
+
- **NEVER use the dev stack (`docker compose up`) for E2E tests.** Always use `docker-compose.test.yml` with isolated test ports (API 3099, Keycloak 8099, Frontend 5199).
|
|
129
|
+
- **NEVER skip a phase silently.** If you can't run a phase, report it as SKIPPED with reason.
|
|
130
|
+
- **NEVER combine phases.** Each phase is a distinct section with its own output.
|
|
131
|
+
- **If running a single phase** (e.g. `/e2e-full verify`), only run that phase and produce its section of the report.
|
|
132
|
+
- **Context management:** If context is running low during Phase 3, mark remaining journeys as UNTESTED rather than silently omitting them.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# E2E Scan — Discover Missing Test Coverage & Generate Specs
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/e2e-scan # Full scan — all pages, all flows
|
|
6
|
+
/e2e-scan project # Scan only project-related flows
|
|
7
|
+
/e2e-scan --report-only # Report gaps without generating specs
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## What this does
|
|
11
|
+
|
|
12
|
+
Scans the codebase to discover all user-facing flows (pages, forms, multi-step wizards, interactions), compares them against existing Playwright specs in `client/e2e/`, reports gaps, and generates missing spec files.
|
|
13
|
+
|
|
14
|
+
## Process
|
|
15
|
+
|
|
16
|
+
### Phase 1: Discover All Flows
|
|
17
|
+
|
|
18
|
+
Scan these sources to build a complete inventory of user-facing flows:
|
|
19
|
+
|
|
20
|
+
#### 1a. Routes & Pages
|
|
21
|
+
- Read the router config (React Router) for all route definitions
|
|
22
|
+
- Read each page component in `client/src/pages/` — note form steps, tabs, interactive elements
|
|
23
|
+
- Note protected vs public routes
|
|
24
|
+
|
|
25
|
+
#### 1b. Multi-Step Forms
|
|
26
|
+
- Search `client/src/pages/` for step-based forms (look for `step`, `currentStep`, `setStep`, stepper patterns)
|
|
27
|
+
- For each form, list all steps and the fields/interactions in each step
|
|
28
|
+
- Note form submission endpoints and success redirects
|
|
29
|
+
|
|
30
|
+
#### 1c. Interactive Features
|
|
31
|
+
- Search for drawers, modals, dialogs (`Dialog`, `Drawer`, `Sheet`) and what triggers them
|
|
32
|
+
- Search for tab switchers (`Tabs`, `TabsList`, tab state) and what content each tab shows
|
|
33
|
+
- Search for filter/search components and what they filter
|
|
34
|
+
- Search for infinite scroll / pagination (`usePaginatedQuery`, "Load more")
|
|
35
|
+
|
|
36
|
+
#### 1d. API-Driven Flows
|
|
37
|
+
- Read `client/src/hooks/` for all `useApiQuery`/`useApiMutation` hooks — each mutation represents a flow
|
|
38
|
+
- Note which hooks are used by which pages (grep for hook names in pages)
|
|
39
|
+
- Pay attention to mutations that trigger navigation or state changes
|
|
40
|
+
|
|
41
|
+
#### 1e. Schema Drift Check
|
|
42
|
+
- Read backend DTOs (`src/**/dtos/*.dto.ts`) for field additions/removals
|
|
43
|
+
- Cross-reference with E2E mock data — if a DTO field exists that no mock covers, the E2E coverage has a gap
|
|
44
|
+
|
|
45
|
+
### Phase 2: Read Existing Test Coverage
|
|
46
|
+
|
|
47
|
+
- List all spec files in `client/e2e/` — extract the routes and flows each covers
|
|
48
|
+
- Read each spec to understand which states are tested (happy, error, empty, loading)
|
|
49
|
+
- Build a coverage matrix: route → states tested
|
|
50
|
+
|
|
51
|
+
### Phase 3: Gap Analysis
|
|
52
|
+
|
|
53
|
+
For each discovered flow, check:
|
|
54
|
+
|
|
55
|
+
| Check | Covered? |
|
|
56
|
+
|-------|----------|
|
|
57
|
+
| Page renders & basic navigation | Spec file exists? |
|
|
58
|
+
| Happy path (data loads, displays correctly) | `test('shows ... on success')` exists? |
|
|
59
|
+
| Error state (API failure) | `test('shows error')` exists? |
|
|
60
|
+
| Empty state (no data) | `test('shows empty state')` exists? |
|
|
61
|
+
| Loading state (skeleton/spinner) | `test('shows loading')` exists? |
|
|
62
|
+
| Form submission + validation errors | Mutation flow tested? |
|
|
63
|
+
| All tabs/views on the page | Each tab has assertions? |
|
|
64
|
+
| Responsive (mobile viewport) | Mobile test exists? |
|
|
65
|
+
|
|
66
|
+
### Phase 4: Report
|
|
67
|
+
|
|
68
|
+
Print a gap analysis table:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
## E2E Coverage Report
|
|
72
|
+
|
|
73
|
+
| Route / Flow | Spec File | Happy | Error | Empty | Loading | Gap |
|
|
74
|
+
|---|---|---|---|---|---|---|
|
|
75
|
+
| /projects | projects.spec.ts | ✅ | ✅ | ❌ | ❌ | Missing empty + loading states |
|
|
76
|
+
| /projects/:id | - | ❌ | ❌ | ❌ | ❌ | No spec file |
|
|
77
|
+
| /settings | settings.spec.ts | ✅ | ❌ | N/A | ❌ | Missing error + loading |
|
|
78
|
+
| ...
|
|
79
|
+
|
|
80
|
+
### Summary
|
|
81
|
+
- **Covered:** N routes with full 4-state coverage
|
|
82
|
+
- **Partial:** M routes missing some states
|
|
83
|
+
- **Uncovered:** K routes with no spec at all
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Phase 5: Generate Missing Specs
|
|
87
|
+
|
|
88
|
+
For each uncovered or partially covered route, generate a spec file following the `/write-ui-tests` pattern:
|
|
89
|
+
|
|
90
|
+
1. Create spec at `client/e2e/<route-name>.spec.ts`
|
|
91
|
+
2. Include all 4 mandatory states (happy, error, empty, loading)
|
|
92
|
+
3. Mock auth via `page.route('**/auth/me', ...)`
|
|
93
|
+
4. Mock API endpoints via `page.route()`
|
|
94
|
+
5. Use semantic locators (`getByRole`, `getByText`) — NEVER CSS selectors
|
|
95
|
+
|
|
96
|
+
#### Spec template
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { test, expect } from '@playwright/test';
|
|
100
|
+
|
|
101
|
+
test.describe('<PageName> Page', () => {
|
|
102
|
+
test.beforeEach(async ({ page }) => {
|
|
103
|
+
await page.route('**/auth/me', route => route.fulfill({
|
|
104
|
+
status: 200,
|
|
105
|
+
contentType: 'application/json',
|
|
106
|
+
body: JSON.stringify({ keycloakId: 'kc-1', email: 'test@test.com', roles: ['user'] }),
|
|
107
|
+
}));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('shows data on success', async ({ page }) => {
|
|
111
|
+
await page.route('**/api/<endpoint>*', route => route.fulfill({
|
|
112
|
+
status: 200, json: { data: [/* mock data */] },
|
|
113
|
+
}));
|
|
114
|
+
await page.goto('/<route>');
|
|
115
|
+
await expect(page.getByRole('heading', { name: '<expected>' })).toBeVisible();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('shows error on API failure', async ({ page }) => {
|
|
119
|
+
await page.route('**/api/<endpoint>*', route => route.fulfill({ status: 500 }));
|
|
120
|
+
await page.goto('/<route>');
|
|
121
|
+
await expect(page.getByText(/something went wrong|error|try again/i)).toBeVisible();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('shows empty state when no data', async ({ page }) => {
|
|
125
|
+
await page.route('**/api/<endpoint>*', route => route.fulfill({
|
|
126
|
+
status: 200, json: { data: [] },
|
|
127
|
+
}));
|
|
128
|
+
await page.goto('/<route>');
|
|
129
|
+
await expect(page.getByText(/no <items>/i)).toBeVisible();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('shows loading while fetching', async ({ page }) => {
|
|
133
|
+
await page.route('**/api/<endpoint>*', async route => {
|
|
134
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
135
|
+
await route.fulfill({ status: 200, json: { data: [] } });
|
|
136
|
+
});
|
|
137
|
+
await page.goto('/<route>');
|
|
138
|
+
// Assert skeleton visible
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Phase 6: Verify Generated Specs
|
|
144
|
+
|
|
145
|
+
- Read each generated spec to confirm selectors are plausible (based on component source)
|
|
146
|
+
- Confirm mock data shape matches the actual API response DTOs
|
|
147
|
+
- Run: `cd client && npx playwright test <spec-file> --reporter=list`
|
|
148
|
+
|
|
149
|
+
## What NOT to do
|
|
150
|
+
|
|
151
|
+
- Don't generate specs for static pages with no API calls (just a heading check is enough)
|
|
152
|
+
- Don't duplicate coverage already in existing specs
|
|
153
|
+
- Don't guess at selectors — read the component source to find actual text/roles
|
|
154
|
+
- Don't test third-party service behavior
|
|
155
|
+
- Don't test backend-only flows (those belong in `/write-backend-tests`)
|
|
156
|
+
|
|
157
|
+
## Output
|
|
158
|
+
|
|
159
|
+
End with a summary:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
## Generated Specs
|
|
163
|
+
|
|
164
|
+
- client/e2e/project-detail.spec.ts — covers /projects/:id (4 states)
|
|
165
|
+
- client/e2e/settings.spec.ts — added missing error + loading tests
|
|
166
|
+
|
|
167
|
+
## Still Needs Manual Attention
|
|
168
|
+
|
|
169
|
+
- /ai-gateway/* — complex multi-step flow, needs manual spec design
|
|
170
|
+
- /admin/* — requires admin role seeding
|
|
171
|
+
```
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# E2E Verify — Playwright MCP Journeys
|
|
2
|
+
|
|
3
|
+
Walk through user journeys interactively using Playwright MCP browser control. No spec files, no selectors to maintain.
|
|
4
|
+
|
|
5
|
+
**Announce "using Playwright MCP" before the first `browser_navigate`** — this prevents Claude from falling back to Bash-driven Playwright.
|
|
6
|
+
|
|
7
|
+
## Viewport Matrix
|
|
8
|
+
|
|
9
|
+
For journeys that verify rendering/layout, resize the browser and re-check at two viewports:
|
|
10
|
+
|
|
11
|
+
| Viewport | Size | Purpose |
|
|
12
|
+
|----------|------|---------|
|
|
13
|
+
| Desktop | 1440 × 900 | Primary layout with sidebar |
|
|
14
|
+
| Tablet | 768 × 1024 | Collapsed sidebar, responsive grid |
|
|
15
|
+
|
|
16
|
+
Use `browser_resize` between viewports.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
1. Docker test stack running: `docker compose -f docker-compose.test.yml up -d`
|
|
21
|
+
2. Frontend dev server running: `cd client && VITE_API_URL=http://localhost:3099 npm run dev -- --port 5199`
|
|
22
|
+
3. Auth state saved (against test stack): `cd client && KEYCLOAK_PORT=8099 API_PORT=3099 npx tsx ../scripts/save-auth-state.ts`
|
|
23
|
+
- This completes the BFF OIDC login flow and saves the httpOnly session cookie
|
|
24
|
+
- The app uses BFF cookies for auth — NOT sessionStorage/localStorage tokens
|
|
25
|
+
4. If auth state is empty or expired, authenticate via MCP:
|
|
26
|
+
- Navigate to `/auth/login?provider=keycloak&returnTo=/`
|
|
27
|
+
- Fill Keycloak form (testuser / TestPassword1!)
|
|
28
|
+
- Verify redirect back to app with session cookie set
|
|
29
|
+
|
|
30
|
+
**IMPORTANT:** Always use the isolated test stack (`docker-compose.test.yml`) — NEVER `docker compose up` against the dev stack. Test ports: API 3099, Keycloak 8099, Frontend 5199.
|
|
31
|
+
|
|
32
|
+
## Base URL
|
|
33
|
+
|
|
34
|
+
`http://localhost:5199`
|
|
35
|
+
|
|
36
|
+
## Journeys
|
|
37
|
+
|
|
38
|
+
### 1. Auth Boundaries
|
|
39
|
+
1. Without auth, navigate to `/projects` — verify redirect to `/login`
|
|
40
|
+
2. Navigate to `/login` — verify login page with Keycloak and Google sign-in buttons
|
|
41
|
+
3. Authenticate via BFF `/auth/login?provider=keycloak` — verify Keycloak form, login, redirect to app
|
|
42
|
+
4. After auth, navigate to `/login` — verify redirect to `/` (dashboard)
|
|
43
|
+
|
|
44
|
+
### 2. Dashboard
|
|
45
|
+
1. Navigate to `/` — verify heading "Dashboard"
|
|
46
|
+
2. Verify welcome message shows user display name ("Welcome back, <name>")
|
|
47
|
+
3. Verify "Getting Started" card with "Your AutoFlux workspace is ready" description
|
|
48
|
+
4. Verify navigation hint to Projects
|
|
49
|
+
|
|
50
|
+
### 3. Sidebar Navigation
|
|
51
|
+
1. Verify sidebar renders with navigation links: Dashboard, Projects, Users, Settings
|
|
52
|
+
2. Verify active link styling matches current route
|
|
53
|
+
3. Click collapse toggle — verify sidebar collapses (icons only)
|
|
54
|
+
4. Click expand toggle — verify sidebar expands back
|
|
55
|
+
5. Verify logout button present and functional
|
|
56
|
+
6. Verify admin links visible only for admin role (Prompt Templates)
|
|
57
|
+
|
|
58
|
+
### 4. Projects List
|
|
59
|
+
1. Navigate to `/projects` — verify heading "Projects"
|
|
60
|
+
2. If projects exist — verify project cards render with name and GitHub repo URL
|
|
61
|
+
3. If no projects — verify empty state "No projects yet" with "Create your first project" CTA
|
|
62
|
+
4. Verify "New Project" link/button navigates to `/projects/new`
|
|
63
|
+
|
|
64
|
+
### 5. Create Project
|
|
65
|
+
1. Navigate to `/projects/new` — verify heading "Create Project"
|
|
66
|
+
2. Verify form fields: Project Name input, GitHub Organization dropdown (async-loaded), Repository Name input
|
|
67
|
+
3. Verify organization dropdown shows loading state then populates from GitHub API
|
|
68
|
+
4. Enter repo name — verify real-time validation (alphanumeric, hyphens, underscores, dots)
|
|
69
|
+
5. Enter invalid repo name (e.g. "my repo!") — verify validation error message
|
|
70
|
+
6. Fill all fields with valid data — verify preview URL shows `github.com/<org>/<repo>`
|
|
71
|
+
7. Click "Create Project" — verify submission spinner, then redirect to `/projects`
|
|
72
|
+
8. Verify cancel button navigates back to `/projects`
|
|
73
|
+
|
|
74
|
+
### 6. Project Detail & Planning
|
|
75
|
+
1. Navigate to `/projects/:id` — verify project name heading, GitHub repo URL link
|
|
76
|
+
2. Verify BRD upload section renders with drag-and-drop zone
|
|
77
|
+
3. Verify "Start Planning" button is disabled before file selection
|
|
78
|
+
4. Select a file (drag or click) — verify file name shown, "Start Planning" enabled, "Clear" visible
|
|
79
|
+
5. Click "Start Planning" — verify spinner during upload
|
|
80
|
+
6. After success — verify "Planning run started" message
|
|
81
|
+
7. If API returns error — verify error message displayed
|
|
82
|
+
|
|
83
|
+
### 7. Profile
|
|
84
|
+
1. Navigate to `/profile` — verify heading "Profile"
|
|
85
|
+
2. Verify avatar with initials (derived from display name)
|
|
86
|
+
3. Verify display name, email, role, and user ID displayed
|
|
87
|
+
4. Verify card layout with proper labels
|
|
88
|
+
|
|
89
|
+
### 8. Admin — Prompt Templates
|
|
90
|
+
1. Navigate to `/admin/prompt-templates` — verify heading "Prompt Templates"
|
|
91
|
+
2. If templates exist — verify step cards with step number, name, template preview, approver roles
|
|
92
|
+
3. If no templates — verify "None defined yet" empty state
|
|
93
|
+
4. Click "Add Step" — verify create form opens with step name input, template textarea
|
|
94
|
+
5. Fill form and submit — verify new step appears in list
|
|
95
|
+
6. Click "Edit" on a template — verify inline edit mode with textarea
|
|
96
|
+
7. Edit and save — verify updated content persists
|
|
97
|
+
8. Verify error handling on create failure (validation error displayed)
|
|
98
|
+
|
|
99
|
+
### 9. Settings (Stub)
|
|
100
|
+
1. Navigate to `/settings` — verify heading "Settings" with "Configure your workspace" subtitle
|
|
101
|
+
2. Verify "Workspace Settings" card with admin-only description
|
|
102
|
+
|
|
103
|
+
### 10. Users (Stub)
|
|
104
|
+
1. Navigate to `/users` — verify heading "Users" with "Manage users and their roles" subtitle
|
|
105
|
+
2. Verify "User Management" card with admin-only description
|
|
106
|
+
|
|
107
|
+
## Reporting
|
|
108
|
+
|
|
109
|
+
**MANDATORY: Complete ALL journeys.** Do not stop early. If context is running low, summarize remaining journeys as UNTESTED rather than silently omitting them.
|
|
110
|
+
|
|
111
|
+
For each journey, report:
|
|
112
|
+
- **PASS** — all pages render correctly, navigation works
|
|
113
|
+
- **FAIL** — specify which step failed and what was wrong (include screenshot)
|
|
114
|
+
- **SKIP** — if prerequisite data doesn't exist
|
|
115
|
+
- **UNTESTED** — journey was not attempted (context limit, blocker, etc.)
|
|
116
|
+
|
|
117
|
+
### Completion Checklist (copy into your final report)
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
| # | Journey | Result |
|
|
121
|
+
|----|----------------------------|----------|
|
|
122
|
+
| 1 | Auth Boundaries | |
|
|
123
|
+
| 2 | Dashboard | |
|
|
124
|
+
| 3 | Sidebar Navigation | |
|
|
125
|
+
| 4 | Projects List | |
|
|
126
|
+
| 5 | Create Project | |
|
|
127
|
+
| 6 | Project Detail & Planning | |
|
|
128
|
+
| 7 | Profile | |
|
|
129
|
+
| 8 | Admin — Prompt Templates | |
|
|
130
|
+
| 9 | Settings (Stub) | |
|
|
131
|
+
| 10 | Users (Stub) | |
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Every row must have a result.** An incomplete checklist is a failed run.
|
|
135
|
+
|
|
136
|
+
## What MCP Covers vs What Coded Tests Cover
|
|
137
|
+
|
|
138
|
+
| MCP Journeys | Coded Tests (`client/e2e/`) |
|
|
139
|
+
|---|---|
|
|
140
|
+
| Page renders correctly | Mock-based state assertions |
|
|
141
|
+
| Navigation flows work | 4-state coverage (happy/error/empty/loading) |
|
|
142
|
+
| Forms display fields & validate | API response shape verification |
|
|
143
|
+
| Visual layout intact | Isolated page-level testing |
|
|
144
|
+
| Interactive elements respond | Auth boundary testing |
|
|
145
|
+
| File upload UX works | Form submission flows |
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Fix Bug
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```
|
|
5
|
+
/fix-bug <issue-number-or-description>
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
## Process (this order is mandatory)
|
|
9
|
+
|
|
10
|
+
### Step 1: Reproduce
|
|
11
|
+
- Read the bug report (issue, error log, or description)
|
|
12
|
+
- Identify the failing behavior and expected behavior
|
|
13
|
+
- Find the relevant code paths
|
|
14
|
+
|
|
15
|
+
### Step 2: Regression Test FIRST
|
|
16
|
+
- Write a test that reproduces the bug
|
|
17
|
+
- Run it — **verify it fails** (this proves the bug exists and the test catches it)
|
|
18
|
+
- If the test passes, your test is wrong — it does not reproduce the bug
|
|
19
|
+
|
|
20
|
+
### Step 3: Fix
|
|
21
|
+
- Analyze the root cause (not just the symptom)
|
|
22
|
+
- Implement the minimal fix
|
|
23
|
+
- Run the regression test — **verify it now passes**
|
|
24
|
+
- Run `npm run build && npm test` — verify nothing else broke
|
|
25
|
+
|
|
26
|
+
### Step 4: Commit
|
|
27
|
+
- Commit with message: `fix: <what-was-fixed> (#<issue-number>)`
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
- The regression test MUST exist before the fix — no exceptions
|
|
31
|
+
- Fix the root cause, not the symptom
|
|
32
|
+
- Keep the fix minimal — don't refactor surrounding code
|
|
33
|
+
- Follow project conventions in CLAUDE.md and `.claude/rules/`
|