openspec-playwright 0.1.44 → 0.1.46

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.
@@ -5,7 +5,7 @@ license: MIT
5
5
  compatibility: Requires openspec CLI, Playwright (with browsers installed), and @playwright/mcp (globally installed via `claude mcp add playwright npx @playwright/mcp@latest`).
6
6
  metadata:
7
7
  author: openspec-playwright
8
- version: "2.8"
8
+ version: "2.9"
9
9
  ---
10
10
 
11
11
  ## Input
@@ -23,11 +23,11 @@ metadata:
23
23
 
24
24
  ## Architecture
25
25
 
26
- Pipeline: **Planner** (Step 4) → **Generator** (Step 5) → **Healer** (Step 8).
26
+ Pipeline: **Planner** (Step 5) → **Generator** (Step 6) → **Healer** (Step 9).
27
27
 
28
- Uses CLI + SKILLs (not `init-agents`). CLI is ~4x more token-efficient than loading MCP tool schemas. MCP is used only for Healer (UI inspection on failure).
28
+ Uses CLI + SKILLs (not `init-agents`). CLI is ~4x more token-efficient than loading MCP tool schemas. MCP is used for **Explore** (Step 4, real DOM data) and **Healer** (UI inspection on failure).
29
29
 
30
- **Schema owns templates. CLI handles execution. Skill handles cognitive work.**
30
+ **Schema owns templates. CLI handles execution. Skill handles cognitive work. Exploration drives generation.**
31
31
 
32
32
  ## Steps
33
33
 
@@ -74,25 +74,211 @@ This validates: app server reachable, auth fixtures initialized, Playwright work
74
74
 
75
75
  **If seed test fails**: Stop and report. Fix the environment before proceeding.
76
76
 
77
- ### 4. Generate test plan
77
+ ### 4. Explore application
78
+
79
+ **Before writing test plan, explore the app to collect real DOM data.** This is the most critical step — it eliminates blind selector guessing.
80
+
81
+ **Prerequisites**: seed test pass. If auth is required, ensure `auth.setup.ts` has been run (Step 7).
82
+
83
+ #### 4.1. Extract routes from specs
84
+
85
+ Read all files in `openspec/changes/<name>/specs/*.md`. Extract every URL, route, or path mentioned:
86
+
87
+ - Full URLs: `http://localhost:3000/dashboard`, `BASE_URL + /admin`
88
+ - Relative paths: `/dashboard`, `/api/auth/login`, `/admin/settings`
89
+ - Infer routes from text: "navigate to the dashboard" → check if `/dashboard` exists
90
+
91
+ Group routes by role:
92
+ - **Guest routes**: `/`, `/login`, `/about` (no auth needed)
93
+ - **Protected routes**: `/dashboard`, `/profile`, `/admin` (auth required)
94
+
95
+ #### 4.2. Explore each route via Playwright MCP
96
+
97
+ For each route, use these tools in order:
98
+
99
+ ```
100
+ browser_navigate → browser_snapshot → browser_take_screenshot
101
+ ```
102
+
103
+ **For guest routes** (no auth):
104
+ ```javascript
105
+ // Navigate directly
106
+ await browser_navigate(`${BASE_URL}/<route>`)
107
+ ```
108
+
109
+ **For protected routes** (auth required):
110
+ ```javascript
111
+ // Option A: use existing storageState (recommended if auth.setup.ts already ran)
112
+ // Option B: navigate to /login first, fill form, then navigate to target
113
+ // Option C: use browser_run_code to set auth cookies directly
114
+ ```
115
+
116
+ Wait for page stability after navigation:
117
+ - Prefer waiting for a specific element: `browser_wait_for` with text or selector
118
+ - Avoid `networkidle` / `load` — they are too slow or unreliable
119
+ - Use a "page ready" signal: look for a heading, a loading spinner disappearing, or a URL change
120
+
121
+ #### 4.3. Parse the snapshot
122
+
123
+ From `browser_snapshot` output, extract **interactive elements** for each route:
124
+
125
+ | Element type | What to capture | Priority |
126
+ |---|---|---|
127
+ | **Buttons** | text, selector (`getByRole`, `getByLabel`, `data-testid`) | data-testid > role > label > text |
128
+ | **Form fields** | name, type, label, selector | data-testid > name > label |
129
+ | **Navigation links** | text, href, selector | text > href |
130
+ | **Headings** | text content, selector | for assertions |
131
+ | **Error messages** | text patterns, selector | for error path testing |
132
+ | **Dynamic content** | structure (not content) — row counts, card layouts | for data-driven tests |
133
+
134
+ **Selector strategy** (in priority order):
135
+ 1. `[data-testid="..."]` — most stable, prefer these
136
+ 2. `getByRole('button', { name: '...' })` — semantic, stable
137
+ 3. `getByLabel('...')` — for form fields
138
+ 4. `getByText('...')` — fallback, fragile
139
+ 5. CSS selectors — last resort
140
+
141
+ #### 4.4. Write app-exploration.md
142
+
143
+ Output: `openspec/changes/<name>/specs/playwright/app-exploration.md`
144
+
145
+ ```markdown
146
+ # App Exploration — <name>
147
+ Generated: <timestamp>
148
+ BASE_URL: <from env or seed.spec.ts>
149
+
150
+ ## Route: /
151
+ - **Auth**: none
152
+ - **URL**: ${BASE_URL}/
153
+ - **Ready signal**: page has heading
154
+ - **Elements**:
155
+ - login link: `a:text("登录")`
156
+ - signup link: `[data-testid="signup-link"]`
157
+ - **Screenshot**: `__screenshots__/index.png`
158
+
159
+ ## Route: /dashboard (user)
160
+ - **Auth**: required (storageState: playwright/.auth/user.json)
161
+ - **URL**: ${BASE_URL}/dashboard
162
+ - **Ready signal**: [data-testid="dashboard-heading"] visible
163
+ - **Elements**:
164
+ - heading: `[data-testid="page-title"]`
165
+ - logout btn: `[data-testid="logout-btn"]`
166
+ - profile form: `form >> input[name="displayName"]`
167
+ - settings link: `nav >> text=Settings`
168
+ - **Screenshot**: `__screenshots__/dashboard-user.png`
169
+
170
+ ## Route: /admin (admin)
171
+ - **Auth**: required (storageState: playwright/.auth/admin.json)
172
+ - **URL**: ${BASE_URL}/admin
173
+ - **Ready signal**: [data-testid="admin-panel"] visible
174
+ - **Elements**:
175
+ - admin panel: `[data-testid="admin-panel"]`
176
+ - user table: `table#user-table tbody tr`
177
+ - add user btn: `[data-testid="add-user-btn"]`
178
+ - delete btn: `button:has-text("Delete")`
179
+ - **Screenshot**: `__screenshots__/admin-panel.png`
180
+
181
+ ## Exploration Notes
182
+ - Route /admin → user gets redirected to /login (no admin role)
183
+ - /dashboard loads user-specific data (test assertions should use toContainText, not toHaveText)
184
+ ```
185
+
186
+ #### 4.5. Edge cases
187
+
188
+ | Situation | What to do |
189
+ |-----------|-----------|
190
+ | Route 404 | Mark as "⚠️ route not found — verify URL in specs" |
191
+ | Network error | Mark as "⚠️ unreachable — check if server is running" |
192
+ | Auth required, no storageState | Skip protected routes → note which routes need auth |
193
+ | SPA routing (URL changes but page doesn't reload) | Explore via navigation clicks from known routes, not direct URLs |
194
+ | Page loads but no interactive elements | Try waiting longer for SPA hydration |
195
+ | Dynamic content (user-specific) | Record structure, not content — use `toContainText`, not `toHaveText` |
196
+
197
+ **Idempotency**: If `app-exploration.md` already exists → read it, verify routes still match specs, update only new routes or changed pages.
198
+
199
+ #### 4.6. Update app-knowledge.md
200
+
201
+ After writing `app-exploration.md`, extract **project-level shared knowledge** and append to `tests/playwright/app-knowledge.md`:
202
+
203
+ | Section | What to extract |
204
+ |---------|----------------|
205
+ | Credential Format | Login endpoint, username format (email vs username) |
206
+ | Common Selector Patterns | New patterns discovered that apply across routes |
207
+ | SPA Routing | SPA framework, routing behavior |
208
+ | Project Conventions | BASE_URL, auth method, multi-user roles |
209
+
210
+ Append only new/changed items — preserve existing content.
211
+
212
+ #### 4.7. After exploration
213
+
214
+ Pass `app-exploration.md` to:
215
+ - **Step 5 (Planner)**: reference real routes, auth states, and elements in test-plan.md
216
+ - **Step 6 (Generator)**: use verified selectors instead of inferring
217
+
218
+ Read `tests/playwright/app-knowledge.md` as context for cross-change patterns.
219
+
220
+ ### 5. Generate test plan
78
221
 
79
222
  Create `openspec/changes/<name>/specs/playwright/test-plan.md`:
223
+
224
+ **Read inputs first**:
225
+ - `openspec/changes/<name>/specs/*.md` — functional requirements
226
+ - `openspec/changes/<name>/specs/playwright/app-exploration.md` — **real routes and verified selectors**
227
+ - `tests/playwright/app-knowledge.md` — project-level shared knowledge
228
+
229
+ Create test cases:
80
230
  - List each functional requirement as a test case
81
231
  - Mark with `@role(user|admin|guest|none)` and `@auth(required|none)`
82
232
  - Include happy path AND error paths
83
- - Reference the route/page each test targets
233
+ - Reference the **real route URL** from app-exploration.md for each test
234
+ - Reference **verified selectors** from app-exploration.md instead of inferring
235
+
236
+ ```markdown
237
+ ### User can view dashboard
238
+ - **Route**: /dashboard (from app-exploration.md)
239
+ - **Auth**: required (user storageState)
240
+ - **Test steps**:
241
+ 1. Go to `/dashboard`
242
+ 2. Assert page heading: `[data-testid="page-title"]` contains "Dashboard"
243
+ 3. Assert logout button visible: `[data-testid="logout-btn"]`
244
+ ```
84
245
 
85
246
  **Idempotency**: If test-plan.md already exists → read it, use it, do NOT regenerate.
86
247
 
87
- ### 5. Generate test file
248
+ ### 6. Generate test file
88
249
 
89
250
  Create `tests/playwright/<name>.spec.ts`:
90
251
 
91
252
  **Read inputs first**:
92
- - `openspec/changes/<name>/specs/playwright/test-plan.md`
93
- - `tests/playwright/seed.spec.ts`
253
+ - `openspec/changes/<name>/specs/playwright/test-plan.md` — test cases
254
+ - `openspec/changes/<name>/specs/playwright/app-exploration.md` — **verified routes and selectors**
255
+ - `tests/playwright/app-knowledge.md` — project-level patterns and conventions
256
+ - `tests/playwright/seed.spec.ts` — code pattern and page object structure
257
+
258
+ #### Verify selectors before writing
259
+
260
+ **For each test case, verify selectors in a real browser BEFORE writing the test code.** This is the most important step — do not skip it.
261
+
262
+ ```
263
+ For each test case in test-plan.md:
264
+
265
+ 1. Determine target route (from app-exploration.md)
266
+ 2. Determine auth state (load storageState if @auth(required))
267
+ 3. Navigate: browser_navigate to the route
268
+ 4. Wait for page ready: browser_wait_for with a key element
269
+ 5. Verify: browser_snapshot to confirm page loaded
270
+ 6. For each selector in the test case:
271
+ a. Check if selector exists in app-exploration.md
272
+ b. If yes → verify it's still valid via browser_snapshot
273
+ c. If no → find equivalent from current snapshot
274
+ d. Selector priority: data-testid > getByRole > getByLabel > getByText
275
+ 7. Write test code with verified selectors
276
+ 8. If selector cannot be verified → note it for Healer (Step 9)
277
+ ```
278
+
279
+ This ensures every selector in the generated test code has been validated against the live DOM.
94
280
 
95
- **Generate** Playwright code for each test case:
281
+ **Generate** Playwright code for each verified test case:
96
282
  - Follow `seed.spec.ts` structure
97
283
  - Prefer `data-testid`; fallback to `getByRole`, `getByLabel`, `getByText`
98
284
  - Include happy path AND error/edge cases
@@ -183,7 +369,7 @@ await page.getByRole('button', { name: 'Submit' }).click();
183
369
 
184
370
  If the file exists → diff against test-plan, add only missing test cases.
185
371
 
186
- ### 6. Configure auth (if required)
372
+ ### 7. Configure auth (if required)
187
373
 
188
374
  - **API login**: Generate `auth.setup.ts` using `E2E_USERNAME`/`E2E_PASSWORD` + POST to login endpoint
189
375
  - **UI login**: Generate `auth.setup.ts` using browser form fill. Update selectors to match your login page
@@ -206,7 +392,7 @@ Auth required. To set up:
206
392
 
207
393
  **Idempotency**: If `auth.setup.ts` already exists → verify format, update only if stale.
208
394
 
209
- ### 7. Configure playwright.config.ts
395
+ ### 8. Configure playwright.config.ts
210
396
 
211
397
  If missing → generate from `openspec/schemas/playwright-e2e/templates/playwright.config.ts`.
212
398
 
@@ -222,7 +408,7 @@ If missing → generate from `openspec/schemas/playwright-e2e/templates/playwrig
222
408
 
223
409
  If playwright.config.ts exists → READ first, preserve ALL existing fields, add only missing `webServer` block.
224
410
 
225
- ### 8. Execute tests
411
+ ### 9. Execute tests
226
412
 
227
413
  ```bash
228
414
  openspec-pw run <name> --project=<role>
@@ -260,7 +446,7 @@ If tests fail → use Playwright MCP tools to inspect UI, fix selectors, re-run.
260
446
  3. **Attempt heal** (≤3 times): snapshot → fix → re-run
261
447
  4. **After 3 failures**: collect evidence checklist → `test.skip()` if app bug, report recommendation if test bug
262
448
 
263
- ### 9. False Pass Detection
449
+ ### 10. False Pass Detection
264
450
 
265
451
  Run after test suite completes (even if all pass):
266
452
 
@@ -270,7 +456,7 @@ Run after test suite completes (even if all pass):
270
456
 
271
457
  Report any gaps in a **⚠️ Coverage Gap** section.
272
458
 
273
- ### 10. Report results
459
+ ### 11. Report results
274
460
 
275
461
  Read report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`. Present:
276
462
  - Summary table (tests, passed, failed, duration, status)
@@ -324,6 +510,8 @@ Read report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`. Present:
324
510
  | No specs | Stop — E2E requires specs |
325
511
  | Seed test fails | Stop — fix environment |
326
512
  | No auth required | Skip auth setup |
513
+ | app-exploration.md exists | Read and use (never regenerate) |
514
+ | app-knowledge.md exists | Read and use (append new patterns only) |
327
515
  | test-plan.md exists | Read and use (never regenerate) |
328
516
  | auth.setup.ts exists | Verify format (update only if stale) |
329
517
  | playwright.config.ts exists | Preserve all fields (add only missing) |
@@ -337,6 +525,7 @@ Read report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`. Present:
337
525
  - Read specs from `openspec/changes/<name>/specs/` as source of truth
338
526
  - Do NOT generate tests that contradict the specs
339
527
  - **DO generate real, runnable Playwright test code** — not placeholders or TODOs
340
- - Do NOT overwrite files outside: `specs/playwright/`, `tests/playwright/`, `openspec/reports/`, `playwright.config.ts`
528
+ - Do NOT overwrite files outside: `specs/playwright/`, `tests/playwright/`, `openspec/reports/`, `playwright.config.ts`, `auth.setup.ts`, `app-exploration.md`, `app-knowledge.md`
529
+ - **Always explore before generating** — Step 4 is mandatory for accurate selectors
341
530
  - Cap auto-heal at 3 attempts
342
531
  - If no change specified → always ask user to select
@@ -99,13 +99,16 @@ export async function init(options) {
99
99
  console.log(chalk.blue('\n─── Generating Seed Test ───'));
100
100
  await generateSeedTest(projectRoot);
101
101
  }
102
- // 8. Install employee-grade CLAUDE.md
102
+ // 8. Generate app-knowledge.md
103
+ console.log(chalk.blue('\n─── Generating App Knowledge ───'));
104
+ await generateAppKnowledge(projectRoot);
105
+ // 9. Install employee-grade CLAUDE.md
103
106
  console.log(chalk.blue('\n─── Installing Employee Standards ───'));
104
107
  const standards = readEmployeeStandards(EMPLOYEE_STANDARDS_SRC);
105
108
  if (standards) {
106
109
  installProjectClaudeMd(projectRoot, standards);
107
110
  }
108
- // 9. Summary
111
+ // 10. Summary
109
112
  console.log(chalk.blue('\n─── Summary ───'));
110
113
  console.log(chalk.green(' ✓ Setup complete!\n'));
111
114
  console.log(chalk.bold('Next steps:'));
@@ -158,6 +161,18 @@ async function generateSeedTest(projectRoot) {
158
161
  }
159
162
  console.log(chalk.gray(' (Customize BASE_URL and credentials for your app)'));
160
163
  }
164
+ async function generateAppKnowledge(projectRoot) {
165
+ const src = join(SCHEMA_DIR, 'playwright-e2e', 'templates', 'app-knowledge.md');
166
+ const dest = join(projectRoot, 'tests', 'playwright', 'app-knowledge.md');
167
+ if (existsSync(dest)) {
168
+ console.log(chalk.gray(' - app-knowledge.md already exists, skipping'));
169
+ return;
170
+ }
171
+ if (existsSync(src)) {
172
+ writeFileSync(dest, readFileSync(src));
173
+ console.log(chalk.green(' ✓ Generated: tests/playwright/app-knowledge.md'));
174
+ }
175
+ }
161
176
  async function installSchema(projectRoot) {
162
177
  const schemaSrc = SCHEMA_DIR + '/playwright-e2e';
163
178
  const schemaDest = join(projectRoot, 'openspec', 'schemas', 'playwright-e2e');
@@ -174,7 +189,7 @@ async function installSchema(projectRoot) {
174
189
  const templatesSrc = join(schemaSrc, 'templates');
175
190
  const templatesDest = join(schemaDest, 'templates');
176
191
  mkdirSync(templatesDest, { recursive: true });
177
- const templateFiles = ['test-plan.md', 'report.md', 'e2e-test.ts', 'playwright.config.ts'];
192
+ const templateFiles = ['test-plan.md', 'report.md', 'e2e-test.ts', 'playwright.config.ts', 'app-knowledge.md'];
178
193
  for (const file of templateFiles) {
179
194
  const src = join(templatesSrc, file);
180
195
  const dest = join(templatesDest, file);
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openspec-playwright",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "OpenSpec + Playwright E2E verification setup tool for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
package/release-notes.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ## What's Changed
2
2
 
3
- - feat(SKILL): add Playwright API guardrails and expand Healer decision tree
3
+ - chore: bump version
4
4
 
5
- **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.44
5
+ **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.46
@@ -0,0 +1,51 @@
1
+ # App Exploration — <change-name>
2
+
3
+ Generated: <timestamp>
4
+ BASE_URL: <from env or seed.spec.ts>
5
+
6
+ ## Exploration Summary
7
+
8
+ | Route | Auth | Status | Ready Signal |
9
+ |-------|------|--------|-------------|
10
+ | / | none | ✅ explored | page has heading |
11
+ | /login | none | ✅ explored | [data-testid="login-form"] visible |
12
+ | /dashboard | required (user) | ✅ explored | [data-testid="page-title"] visible |
13
+ | /admin | required (admin) | ✅ explored | [data-testid="admin-panel"] visible |
14
+
15
+ ## Route: <path>
16
+
17
+ - **Auth**: none / required (storageState: <path>)
18
+ - **URL**: ${BASE_URL}<path>
19
+ - **Ready signal**: <how to know page is loaded>
20
+ - **Screenshot**: `__screenshots__/<path-slug>.png`
21
+
22
+ ### Interactive Elements (from real DOM)
23
+
24
+ | Element | Selector | Notes |
25
+ |---------|----------|-------|
26
+ | heading | `[data-testid="..."]` or `h1` | |
27
+ | submit btn | `getByRole('button', { name: '...' })` | |
28
+ | logout btn | `[data-testid="logout-btn"]` | |
29
+ | form | `form >> input[name="..."]` | |
30
+ | nav link | `a:text("...")` or `nav >> text=...` | |
31
+
32
+ ### Navigation Context
33
+
34
+ - How to reach this page: <from homepage / from dashboard / etc.>
35
+ - Redirects: <any redirects observed>
36
+
37
+ ### Dynamic Content Notes
38
+
39
+ - <any dynamic content that was observed>
40
+ - <test assertions should use toContainText, not toHaveText for user-specific data>
41
+
42
+ ## Exploration Failures
43
+
44
+ | Route | Error | Notes |
45
+ |-------|-------|-------|
46
+ | | | |
47
+
48
+ ## Next Steps
49
+
50
+ After exploration, pass this file to Step 5 (Planner) and Step 6 (Generator).
51
+ Also extract project-level patterns → append to `tests/playwright/app-knowledge.md`.
@@ -0,0 +1,73 @@
1
+ # App Knowledge — <project-name>
2
+
3
+ Generated: <timestamp>
4
+ Last updated: <timestamp>
5
+
6
+ Cross-change E2E knowledge. Updated by Step 4 exploration, read by Step 5/6.
7
+
8
+ ## Credential Format
9
+
10
+ | Field | Format | Source |
11
+ |-------|--------|--------|
12
+ | username | `<pattern>` | e.g. `email@example.com` or `test_user_001` |
13
+ | password | `<pattern>` | |
14
+ | login endpoint | `<path>` | e.g. `/api/auth/login` |
15
+
16
+ ## Common Selector Patterns
17
+
18
+ Priority: `[data-testid]` > `getByRole` > `getByLabel` > `getByText` > CSS
19
+
20
+ ### Forms
21
+
22
+ | Element | Selector | Notes |
23
+ |---------|----------|-------|
24
+ | submit btn | `[data-testid="..."]` or `getByRole('button', { name: '...' })` | |
25
+ | text input | `getByLabel('...')` or `[data-testid="..."]` | |
26
+ | password input | `getByLabel('...')` or `[name="..."]` | |
27
+
28
+ ### Navigation
29
+
30
+ | Element | Selector | Notes |
31
+ |---------|----------|-------|
32
+ | nav link | `a:text("...")` or `nav >> text=...` | |
33
+ | logout btn | `[data-testid="logout-btn"]` | |
34
+
35
+ ### Feedback
36
+
37
+ | Element | Selector | Notes |
38
+ |---------|----------|-------|
39
+ | error msg | `[data-testid="error-msg"]` or `.error` | |
40
+ | success msg | `[data-testid="success-msg"]` | |
41
+ | loading spinner | `[data-testid="loading"]` | |
42
+
43
+ ## SPA Routing
44
+
45
+ - Framework: <e.g. React Router / Vue Router / Next.js>
46
+ - URL changes without page reload: <yes/no>
47
+ - History API: <yes/no>
48
+ - Hash routing: <yes/no>
49
+
50
+ ## Dynamic Content Conventions
51
+
52
+ - User-specific data: use `toContainText`, never `toHaveText`
53
+ - Timestamps: normalize or use regex
54
+ - Random IDs: avoid asserting on auto-generated values
55
+ - Pagination: test first/last page, boundary conditions
56
+
57
+ ## Project Conventions
58
+
59
+ | Convention | Value | Notes |
60
+ |------------|-------|-------|
61
+ | BASE_URL | `<default>` | Override with env |
62
+ | auth method | API / UI | See auth.setup.ts |
63
+ | multi-user roles | `<roles>` | e.g. admin, user, guest |
64
+
65
+ ## Changelog
66
+
67
+ | Date | Change | By |
68
+ |------|--------|-----|
69
+ | | | |
70
+
71
+ ---
72
+
73
+ > **Updating this file**: After each E2E exploration (Step 4), extract new shared patterns and update this file. Generator (Step 6) reads this before writing tests.
@@ -122,14 +122,18 @@ export async function init(options: InitOptions) {
122
122
  await generateSeedTest(projectRoot);
123
123
  }
124
124
 
125
- // 8. Install employee-grade CLAUDE.md
125
+ // 8. Generate app-knowledge.md
126
+ console.log(chalk.blue('\n─── Generating App Knowledge ───'));
127
+ await generateAppKnowledge(projectRoot);
128
+
129
+ // 9. Install employee-grade CLAUDE.md
126
130
  console.log(chalk.blue('\n─── Installing Employee Standards ───'));
127
131
  const standards = readEmployeeStandards(EMPLOYEE_STANDARDS_SRC);
128
132
  if (standards) {
129
133
  installProjectClaudeMd(projectRoot, standards);
130
134
  }
131
135
 
132
- // 9. Summary
136
+ // 10. Summary
133
137
  console.log(chalk.blue('\n─── Summary ───'));
134
138
  console.log(chalk.green(' ✓ Setup complete!\n'));
135
139
 
@@ -187,6 +191,21 @@ async function generateSeedTest(projectRoot: string) {
187
191
  console.log(chalk.gray(' (Customize BASE_URL and credentials for your app)'));
188
192
  }
189
193
 
194
+ async function generateAppKnowledge(projectRoot: string) {
195
+ const src = join(SCHEMA_DIR, 'playwright-e2e', 'templates', 'app-knowledge.md');
196
+ const dest = join(projectRoot, 'tests', 'playwright', 'app-knowledge.md');
197
+
198
+ if (existsSync(dest)) {
199
+ console.log(chalk.gray(' - app-knowledge.md already exists, skipping'));
200
+ return;
201
+ }
202
+
203
+ if (existsSync(src)) {
204
+ writeFileSync(dest, readFileSync(src));
205
+ console.log(chalk.green(' ✓ Generated: tests/playwright/app-knowledge.md'));
206
+ }
207
+ }
208
+
190
209
  async function installSchema(projectRoot: string) {
191
210
  const schemaSrc = SCHEMA_DIR + '/playwright-e2e';
192
211
  const schemaDest = join(projectRoot, 'openspec', 'schemas', 'playwright-e2e');
@@ -205,7 +224,7 @@ async function installSchema(projectRoot: string) {
205
224
  const templatesSrc = join(schemaSrc, 'templates');
206
225
  const templatesDest = join(schemaDest, 'templates');
207
226
  mkdirSync(templatesDest, { recursive: true });
208
- const templateFiles = ['test-plan.md', 'report.md', 'e2e-test.ts', 'playwright.config.ts'];
227
+ const templateFiles = ['test-plan.md', 'report.md', 'e2e-test.ts', 'playwright.config.ts', 'app-knowledge.md'];
209
228
  for (const file of templateFiles) {
210
229
  const src = join(templatesSrc, file);
211
230
  const dest = join(templatesDest, file);
Binary file