openspec-playwright 0.1.41 → 0.1.44

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.
@@ -3,11 +3,9 @@ name: openspec-e2e
3
3
  description: Run Playwright E2E verification for an OpenSpec change. Use when the user wants to validate that the implementation works end-to-end by running Playwright tests generated from the specs.
4
4
  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
-
7
- **Architecture**: Uses CLI + SKILLs (not `init-agents`). This follows Playwright's recommended approach for coding agents — CLI is more token-efficient than loading MCP tool schemas into context. MCP is used only for Healer (UI inspection on failure).
8
6
  metadata:
9
7
  author: openspec-playwright
10
- version: "2.7"
8
+ version: "2.8"
11
9
  ---
12
10
 
13
11
  ## Input
@@ -25,13 +23,9 @@ metadata:
25
23
 
26
24
  ## Architecture
27
25
 
28
- This skill implements the Playwright Test Agents pipeline:
29
-
30
- - **🎭 Planner** (Step 4): Consumes OpenSpec specs (`specs/*.md`) and produces `test-plan.md` — combines OpenSpec's structured requirements with LLM编排.
31
- - **🎭 Generator** (Step 5): Transforms the Markdown test-plan into real Playwright `.spec.ts` files using LLM code generation.
32
- - **🎭 Healer** (Step 8): Executes the test suite and automatically repairs failing selectors via Playwright MCP tools.
26
+ Pipeline: **Planner** (Step 4) **Generator** (Step 5) → **Healer** (Step 8).
33
27
 
34
- Uses CLI + SKILLs (not `init-agents`). This follows Playwright's recommended approach for coding agents — CLI is more token-efficient than loading MCP tool schemas into context. 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 only for Healer (UI inspection on failure).
35
29
 
36
30
  **Schema owns templates. CLI handles execution. Skill handles cognitive work.**
37
31
 
@@ -56,7 +50,7 @@ If `openspec/changes/<name>/specs/` is empty, inform the user and stop. E2E requ
56
50
 
57
51
  Read all files from `openspec/changes/<name>/specs/*.md`. Extract functional requirements.
58
52
 
59
- Detect if auth is required. Mark as **auth required** only when BOTH conditions are met:
53
+ Detect if auth is required only when BOTH conditions are met:
60
54
 
61
55
  **Condition A — Explicit markers**: "login", "signin", "logout", "authenticate", "protected", "authenticated", "session", "unauthorized"
62
56
 
@@ -71,169 +65,172 @@ Detect if auth is required. Mark as **auth required** only when BOTH conditions
71
65
 
72
66
  ### 3. Validate environment
73
67
 
74
- Before generating tests, verify the environment is ready by running the seed test:
75
-
68
+ Run the seed test before generating tests:
76
69
  ```bash
77
70
  npx playwright test tests/playwright/seed.spec.ts --project=chromium
78
71
  ```
79
72
 
80
- **What this validates**:
81
- - App server is reachable (BASE_URL accessible)
82
- - Auth fixtures (`storageState`) are initialized if auth is required
83
- - Playwright browser and config are working
73
+ This validates: app server reachable, auth fixtures initialized, Playwright working.
84
74
 
85
- **If seed test fails**: Stop and report the failure. User must fix the environment before proceeding.
86
-
87
- **If seed test passes or no auth required**: Proceed to Step 4.
75
+ **If seed test fails**: Stop and report. Fix the environment before proceeding.
88
76
 
89
77
  ### 4. Generate test plan
90
78
 
91
- Create `openspec/changes/<name>/specs/playwright/test-plan.md` by:
92
- - Listing each functional requirement as a test case
93
- - Marking each with `@role(user|admin|guest|none)` and `@auth(required|none)`
94
- - Including happy path AND key error paths
95
- - Referencing the route/page each test targets
79
+ Create `openspec/changes/<name>/specs/playwright/test-plan.md`:
80
+ - List each functional requirement as a test case
81
+ - Mark with `@role(user|admin|guest|none)` and `@auth(required|none)`
82
+ - Include happy path AND error paths
83
+ - Reference the route/page each test targets
96
84
 
97
- **Idempotency**: If test-plan.md already exists → read it, use it, do NOT regenerate unless user explicitly asks.
85
+ **Idempotency**: If test-plan.md already exists → read it, use it, do NOT regenerate.
98
86
 
99
- ### 5. Generate test file (LLM-driven)
87
+ ### 5. Generate test file
100
88
 
101
- Use your file writing capability to create `tests/playwright/<name>.spec.ts`.
89
+ Create `tests/playwright/<name>.spec.ts`:
102
90
 
103
91
  **Read inputs first**:
104
- - `openspec/changes/<name>/specs/playwright/test-plan.md` — test cases with `@role` and `@auth` tags
105
- - `tests/playwright/seed.spec.ts` — code pattern, BASE_URL, and page object structure
106
-
107
- **Generate Playwright code** for each test case from test-plan.md:
108
- - Follow the same structure as `seed.spec.ts`
109
- - Prefer `data-testid` selectors; fallback to `input[name="..."]` or semantic selectors
110
- - Include **happy path** AND **error/edge cases**
111
- - Use `test.describe(...)` for grouping related tests
92
+ - `openspec/changes/<name>/specs/playwright/test-plan.md`
93
+ - `tests/playwright/seed.spec.ts`
94
+
95
+ **Generate** Playwright code for each test case:
96
+ - Follow `seed.spec.ts` structure
97
+ - Prefer `data-testid`; fallback to `getByRole`, `getByLabel`, `getByText`
98
+ - Include happy path AND error/edge cases
99
+ - Use `test.describe(...)` for grouping
112
100
  - Each test: `test('描述性名称', async ({ page }) => { ... })`
113
- - Add `@project(user)` / `@project(admin)` on role-specific tests
114
101
 
115
- ### Anti-Pattern Warnings (Generator)
102
+ #### Anti-Pattern Warnings
116
103
 
117
- **🚫 NEVER do this False Pass pattern:**
104
+ **🚫 False Pass**never silently skip when element is missing:
118
105
  ```typescript
119
- // WRONG: If button doesn't exist, test silently passes and tests nothing
120
- const btn = page.getByRole('button', { name: '取消' }).first();
121
- if (await btn.isVisible().catch(() => false)) {
122
- await btn.click();
123
- await expect(page.getByText('成功')).toBeVisible();
124
- }
125
- // ✅ CORRECT: Use assertion — test fails if element is missing
106
+ // WRONG
107
+ if (await btn.isVisible().catch(() => false)) { ... }
108
+ // CORRECT
126
109
  await expect(page.getByRole('button', { name: '取消' })).toBeVisible();
127
- await page.getByRole('button', { name: '取消' }).click();
128
- await expect(page.getByText('成功')).toBeVisible();
129
110
  ```
130
111
 
131
- **Why it matters**: A test that passes but skipped its logic gives **false confidence**. It reports green but tests nothing. Worse if the test modifies data, a skipped run can corrupt state for the next test.
132
-
133
- **🚫 NEVER rely on Playwright projects for permission filtering:**
112
+ **🚫 Permission filtering** — use `@tag` with `--grep`, not projects:
134
113
  ```typescript
135
- // WRONG: All tests run under both admin AND user projects false "16 tests" impression
136
- projects: [{ name: 'admin' }, { name: 'user' }]
137
-
138
- // ✅ CORRECT: Use @tag for permission-based test filtering
139
- test('admin only - activate subscription', { tag: '@admin' }, async ({ page }) => { ... });
140
- test('user only - view subscription', { tag: '@user' }, async ({ page }) => { ... });
114
+ test('admin only', { tag: '@admin' }, async ({ page }) => { ... });
141
115
  // Run with: npx playwright test --grep "@admin"
142
116
  ```
143
117
 
144
- **🚫 NEVER skip auth guard tests:**
145
- The auth guard is a **critical security feature**. Skipping it leaves a gap in coverage.
118
+ **🚫 Auth guard** test with FRESH browser context (no inherited cookies):
146
119
  ```typescript
147
- // ✅ CORRECT: Test auth guard with a FRESH browser context (no cookies, no storage)
148
120
  test('redirects unauthenticated user to login', async ({ browser }) => {
149
- const freshContext = await browser.newContext(); // No session cookies
150
- const freshPage = await freshContext.newPage();
121
+ const freshPage = await browser.newContext().newPage();
151
122
  await freshPage.goto(`${BASE_URL}/dashboard`);
152
123
  await expect(freshPage).toHaveURL(/login|auth/);
153
- await freshContext.close();
154
124
  });
155
125
  ```
156
126
 
157
- **Always include error path tests** (not just happy paths):
158
- - API returns 500 → UI error message displayed?
159
- - API returns 404 graceful "not found" handling?
160
- - Network timeout → retry or error UX?
161
- - Invalid input → validation message shown?
127
+ #### Playwright API Guardrails
128
+
129
+ These are the most common mistakes that cause test failures. **Always follow these rules:**
162
130
 
163
- **Example pattern** (from seed.spec.ts):
131
+ **API calls use `request` API, NOT `page.evaluate()`:**
164
132
  ```typescript
165
- import { test, expect } from '@playwright/test';
166
-
167
- const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
168
-
169
- test.describe('Feature Name', () => {
170
- test('happy path - action succeeds', async ({ page }) => {
171
- await page.goto(`${BASE_URL}/path`);
172
- await page.getByTestId('element').click();
173
- await expect(page.getByTestId('result')).toBeVisible();
174
- });
175
-
176
- test('error case - invalid input shows message', async ({ page }) => {
177
- await page.goto(`${BASE_URL}/path`);
178
- await page.getByTestId('input').fill('invalid');
179
- await page.getByTestId('submit').click();
180
- await expect(page.getByTestId('error')).toContainText('Error text');
181
- });
133
+ // WRONG — page.evaluate timeout, wrong context, CORS issues
134
+ const result = await page.evaluate(async () => {
135
+ const res = await fetch('/api/data');
136
+ return res.json();
182
137
  });
138
+
139
+ // ✅ CORRECT — direct HTTP, no browser context, fast
140
+ const res = await page.request.get(`${BASE_URL}/api/data`);
141
+ expect(res.status()).toBe(200);
142
+ const data = await res.json();
143
+ ```
144
+
145
+ **Browser context cleanup — `dispose()` NOT `close()`:**
146
+ ```typescript
147
+ // ❌ WRONG — close() is not a function on APIRequestContext
148
+ const ctx = await page.request.newContext();
149
+ await ctx.dispose(); // actually correct, but this is CommonContext
150
+ const context = await browser.newContext();
151
+ await context.close(); // ← WRONG
152
+
153
+ // ✅ CORRECT
154
+ const context = await browser.newContext();
155
+ await context.close(); // close() is correct for BrowserContext
156
+
157
+ // For APIRequestContext (from page.request):
158
+ // No cleanup needed — it's managed by Playwright automatically
183
159
  ```
184
160
 
185
- **Write the file** using the Write tool. If the file already exists → diff against test-plan, add only missing test cases, preserve existing implementations.
161
+ **File uploads use `setInputFiles()`, NOT `page.evaluate()` + fetch:**
162
+ ```typescript
163
+ // ❌ WRONG
164
+ await page.evaluate(() => {
165
+ const input = document.querySelector('input[type=file]');
166
+ // ...
167
+ });
186
168
 
187
- **Selector guidance**: If no `data-testid` exists in the app, prefer `getByRole`, `getByLabel`, `getByText` over fragile selectors like CSS paths.
169
+ // CORRECT
170
+ await page.locator('input[type="file"]').setInputFiles('/path/to/file.pdf');
171
+ ```
188
172
 
189
- ### 6. Configure auth (if required)
173
+ **Form submissions prefer Playwright locators, not JS clicks:**
174
+ ```typescript
175
+ // ❌ WRONG — bypasses Playwright's actionability checks
176
+ await page.evaluate(() => document.querySelector('button[type=submit]').click());
190
177
 
191
- If auth is required:
178
+ // CORRECT — respects visibility, enabled, stable
179
+ await page.getByRole('button', { name: 'Submit' }).click();
180
+ ```
192
181
 
193
- **API login**: If specs mention `/api/auth/login` or similar generate `tests/playwright/auth.setup.ts` using API login with `E2E_USERNAME`/`E2E_PASSWORD`.
182
+ **Always include error path tests** API 500, 404, network timeout, invalid input.
194
183
 
195
- **UI login**: Otherwisegenerate `tests/playwright/auth.setup.ts` using UI login. Update selectors to match the login page (look for `data-testid` attributes or fallback to `input[name="..."]`).
184
+ If the file exists diff against test-plan, add only missing test cases.
196
185
 
197
- **Multi-user**: If specs mention multiple roles (admin + user) → generate separate `auth.setup.ts` blocks for each role with different `storageState` paths.
186
+ ### 6. Configure auth (if required)
198
187
 
199
- **Prompt user** with:
200
- ```
201
- Auth required. To set up credentials:
188
+ - **API login**: Generate `auth.setup.ts` using `E2E_USERNAME`/`E2E_PASSWORD` + POST to login endpoint
189
+ - **UI login**: Generate `auth.setup.ts` using browser form fill. Update selectors to match your login page
190
+ - **Multi-user**: Separate `storageState` paths per role
191
+
192
+ **Credential format guidance**:
193
+ - If the app uses **email** for login → use `CHANGE_ME@example.com`
194
+ - If the app uses **username** (alphanumeric + underscore) → use `test_user_001` (more universal)
195
+ - Check existing test files or login page to determine the format
196
+ - Always set credentials via environment variables — never hardcode
202
197
 
203
- 1. Customize tests/playwright/credentials.yaml with your test user
198
+ **Prompt user**:
199
+ ```
200
+ Auth required. To set up:
201
+ 1. Customize tests/playwright/credentials.yaml
204
202
  2. Export: export E2E_USERNAME=xxx E2E_PASSWORD=yyy
205
203
  3. Run auth: npx playwright test --project=setup
206
- 4. Then re-run /opsx:e2e to execute tests
204
+ 4. Re-run /opsx:e2e to execute tests
207
205
  ```
208
206
 
209
207
  **Idempotency**: If `auth.setup.ts` already exists → verify format, update only if stale.
210
208
 
211
- ### 7. Configure playwright.config.ts (non-destructive)
209
+ ### 7. Configure playwright.config.ts
212
210
 
213
- If `playwright.config.ts` does not exist → generate it from the schema template at `openspec/schemas/playwright-e2e/templates/playwright.config.ts`. The template auto-detects:
214
- - **BASE_URL**: from `process.env.BASE_URL`, falling back to `tests/playwright/seed.spec.ts` → `BASE_URL` value, then `http://localhost:3000`
215
- - **Dev command**: from `package.json` → scripts in order: `dev` → `start` → `serve` → `preview` → `npm run dev`
211
+ If missing → generate from `openspec/schemas/playwright-e2e/templates/playwright.config.ts`.
216
212
 
217
- If `playwright.config.ts` exists READ it first. Extract existing `webServer`, `use.baseURL`, and `projects`. Preserve ALL existing fields. Add `webServer` block if missing. Do NOT replace existing config values.
213
+ **Auto-detect BASE_URL** (in priority order):
214
+ 1. `process.env.BASE_URL` if already set
215
+ 2. `tests/playwright/seed.spec.ts` → extract `BASE_URL` value
216
+ 3. Read `vite.config.ts` (or `vite.config.js`) → extract `server.port` + infer protocol (`https` if `server.https`, else `http`)
217
+ 4. Read `package.json` → `scripts.dev` or `scripts.start` → extract port from `--port` flag
218
+ 5. Fallback: `http://localhost:3000`
218
219
 
219
- ### 8. Execute tests via CLI
220
+ **Auto-detect dev command**:
221
+ 1. `package.json` → scripts in order: `dev` → `start` → `serve` → `preview` → `npm run dev`
220
222
 
221
- ```bash
222
- openspec-pw run <name> --project=<role>
223
- ```
223
+ If playwright.config.ts exists → READ first, preserve ALL existing fields, add only missing `webServer` block.
224
+
225
+ ### 8. Execute tests
224
226
 
225
- **For role-based tests using `@tag`** (recommended over `--project` filtering):
226
227
  ```bash
227
- npx playwright test tests/playwright/<name>.spec.ts --grep "@<role>"
228
+ openspec-pw run <name> --project=<role>
228
229
  ```
229
- The `--project` approach runs ALL tests under each project's credentials — use `@tag` with `--grep` for precise filtering.
230
230
 
231
- The CLI handles:
232
- - Server lifecycle (start → wait for HTTP → test → stop)
233
- - Port mismatch detection
234
- - Report generation at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`
231
+ The CLI handles: server lifecycle, port mismatch, report generation.
235
232
 
236
- If tests fail → analyze failures, use **Playwright MCP tools** to inspect UI state, fix selectors in the test file, and re-run.
233
+ If tests fail → use Playwright MCP tools to inspect UI, fix selectors, re-run.
237
234
 
238
235
  **Healer MCP tools** (in order of use):
239
236
  <!-- MCP_VERSION: 0.0.68 -->
@@ -247,77 +244,44 @@ If tests fail → analyze failures, use **Playwright MCP tools** to inspect UI s
247
244
  | `browser_run_code` | Execute custom fix logic (optional) |
248
245
 
249
246
  **Healer workflow**:
250
- 1. Read the failing test → identify failure type by checking error message and console output
251
- 2. Classify the failure:
247
+ 1. Read the failing test → identify failure type
248
+ 2. Classify:
252
249
 
253
250
  | Failure type | Signal | Action |
254
251
  |-------------|--------|--------|
255
- | **Network/backend** | `fetch failed`, `net::ERR`, 5xx, timeout | `browser_console_messages` → add `test.skip()` + report "backend error" |
256
- | **Selector changed** | Element not found, page loaded | `browser_snapshot` → fix selector → re-run |
257
- | **Assertion mismatch** | Element exists, wrong content/value | `browser_snapshot` → compare → fix assertion → re-run |
258
- | **Timing issue** | `waitFor` timeout, race condition | Adjust wait strategy → re-run |
259
-
260
- 3. **Attempt heal** (up to 3 times):
261
- - Apply fix using `browser_snapshot` (prefer `getByRole`, `getByLabel`, `getByText`)
262
- - Re-run: `openspec-pw run <name> --project=<role>`
263
-
264
- 4. **After 3 failed attempts**, collect evidence:
252
+ | **Network/backend** | `fetch failed`, `net::ERR`, 5xx | `browser_console_messages` → `test.skip()` |
253
+ | **Selector changed** | Element not found | `browser_snapshot` → fix selector → re-run |
254
+ | **Assertion mismatch** | Wrong content/value | `browser_snapshot` → compare → fix assertion → re-run |
255
+ | **Timing issue** | `waitFor`/`page.evaluate` timeout | Switch to `request` API or add `waitFor` → re-run |
256
+ | **Wrong API usage** | `ctx.close is not a function` | Fix: `browser.newContext()` → `close()`; `request.newContext()` → no cleanup needed |
257
+ | **Auth expired** | 401 Unauthorized | Token may have expired — if long suite, recommend splitting or re-auth |
258
+ | **page.evaluate failure** | `fetch` in browser context, CORS errors | Switch to `page.request` API → re-run |
265
259
 
266
- **Evidence checklist** (in order, stop at first match):
267
- | Check | Signal | Decision |
268
- |-------|--------|----------|
269
- | `browser_console_messages` | ERROR-level messages present | App bug → `test.skip()` + report "console error" |
270
- | `browser_snapshot` | Target element missing from DOM | App bug → `test.skip()` + report "element missing" |
271
- | `browser_snapshot` | Element exists, no errors | Test bug → report recommendation |
272
-
273
- - **App bug**: `test.skip('app bug — reason: <signal>')` + detailed report entry
274
- - **Test bug**: report with "likely selector change, verify manually at file:line"
275
- - Do NOT retry after evidence checklist — evidence is conclusive
260
+ 3. **Attempt heal** (≤3 times): snapshot fix → re-run
261
+ 4. **After 3 failures**: collect evidence checklist → `test.skip()` if app bug, report recommendation if test bug
276
262
 
277
263
  ### 9. False Pass Detection
278
264
 
279
- Run **after** the test suite completes (even if all tests pass). Scan for silent skips that give false confidence:
265
+ Run after test suite completes (even if all pass):
280
266
 
281
- **Indicator AConditional test logic:**
282
- Look for patterns in the test file:
283
- ```typescript
284
- if (await locator.isVisible().catch(() => false)) { ... }
285
- ```
286
- → If test passes, the locator might not exist → check with `browser_snapshot`
287
- → Report: "Test passed but may have skipped — conditional visibility check detected"
288
-
289
- **Indicator B — Test ran too fast:**
290
- A test covering a complex flow that completes in < 200ms is suspicious.
291
- → Inspect with `browser_snapshot` to confirm page state
292
- → Report: "Test duration suspiciously short — verify test logic was executed"
293
-
294
- **Indicator C — Auth guard not tested:**
295
- If specs mention "protected route" or "redirect to login" but no test uses a fresh browser context:
296
- → Report: "Auth guard not verified — test uses authenticated context (cookies/storage inherited)"
297
- → Recommendation: Add a test with `browser.newContext()` (no storageState) to verify the guard
267
+ - **Conditional logic**: Look for `if (locator.isVisible().catch(() => false))` if test passes, locator may not exist
268
+ - **Too fast**: < 200ms for a complex flow is suspicious
269
+ - **No fresh auth context**: Protected routes without `browser.newContext()`
298
270
 
299
- If any false-pass indicator is found → add a **⚠️ Coverage Gap** section to the report.
271
+ Report any gaps in a **⚠️ Coverage Gap** section.
300
272
 
301
273
  ### 10. Report results
302
274
 
303
- Read the report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`.
304
-
305
- **Present results to user**:
306
- - Summary table (tests run, passed, failed, duration, final status)
307
- - Any auto-heal notes
308
- - Recommendations for failed tests (with specific `file:line` references)
309
-
310
- **Update tasks.md** (if all tests pass):
311
- - Read `openspec/changes/<name>/tasks.md`
312
- - Find tasks related to E2E testing (look for `[ ]` items mentioning "test", "e2e", "playwright", "verify")
313
- - Append a verification note: e.g. `✅ Verified via Playwright E2E (<timestamp>)`
314
- - Write the updated content back using the Edit tool
275
+ Read report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`. Present:
276
+ - Summary table (tests, passed, failed, duration, status)
277
+ - Auto-heal notes
278
+ - Recommendations with `file:line` references
315
279
 
316
- ## Output Format
280
+ **Update tasks.md** if all tests pass: find E2E-related items, append `✅ Verified via Playwright E2E (<timestamp>)`.
317
281
 
318
- ### Report Structure (`openspec/reports/playwright-e2e-<name>-<timestamp>.md`)
282
+ ## Report Structure
319
283
 
320
- ```
284
+ ```markdown
321
285
  # Playwright E2E Report — <name>
322
286
 
323
287
  ## Summary
@@ -326,7 +290,6 @@ Read the report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`.
326
290
  | N | N | N | Xm Xs | ✅/❌ |
327
291
 
328
292
  ## Results
329
-
330
293
  ### Passed
331
294
  | Test | Duration | Notes |
332
295
  |------|----------|-------|
@@ -345,49 +308,35 @@ Read the report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`.
345
308
  - [ ] Requirement 2 (unverified)
346
309
 
347
310
  ## ⚠️ Coverage Gaps
348
- > Tests passed but coverage gaps were detected. Review carefully.
311
+ > Tests passed but coverage gaps detected.
349
312
 
350
313
  | Test | Gap | Recommendation |
351
314
  |------|-----|----------------|
352
- | ... | Conditional visibility check — test may have skipped | file:line — use `expect().toBeVisible()` |
353
- | ... | Auth guard uses inherited session | Add fresh context test: `browser.newContext()` |
354
- | ... | Suspiciously fast execution (<200ms) | Verify test logic was actually executed |
355
-
356
- ### Updated tasks.md
357
- ```
358
- - [x] Implement feature X ✅ Verified via Playwright E2E (2026-03-28)
315
+ | ... | Conditional visibility check | file:line — use `expect().toBeVisible()` |
316
+ | ... | Auth guard uses inherited session | Add fresh context test |
317
+ | ... | Suspiciously fast execution (<200ms) | Verify test logic executed |
359
318
  ```
360
319
 
361
320
  ## Graceful Degradation
362
321
 
363
322
  | Scenario | Behavior |
364
323
  |----------|----------|
365
- | No specs found | Stop with info message — E2E requires specs |
366
- | Seed test fails | Stop with failure — fix environment before proceeding |
367
- | No auth required | Skip auth setup entirely |
368
- | test-plan.md exists | Read and use it — never regenerate |
369
- | auth.setup.ts exists | Verify format update only if stale |
370
- | playwright.config.ts exists | Read and preserve all fields add only missing |
371
- | Test fails (network/backend) | Skip with `test.skip()` backend/app error, not test fragility |
372
- | Test fails (selector) | Healer: snapshot → fix selector → re-run (≤3 attempts) |
373
- | Test fails (assertion) | Healer: snapshotfix assertion re-run (≤3 attempts) |
374
- | 3 heal attempts failed | Confirm root cause if app bug: `test.skip()` + report; if unclear: report with recommendation |
375
- | False pass detected | Report coverage gap → add to "⚠️ Coverage Gap" section in report |
376
-
377
- ## Verification Heuristics
378
-
379
- - **Coverage**: Every functional requirement → at least one test
380
- - **Selector robustness**: Prefer `data-testid`, fallback to semantic selectors
381
- - **False positives**: If test fails due to test bug (not app bug) → fix the test
382
- - **Actionability**: Every failed test needs a specific recommendation
383
- - **No false passes**: Every passing test must actually execute its test logic — verify absence of `if (isVisible())` conditional patterns
384
- - **Auth guard verified**: Protected routes must have a test using a fresh browser context (no inherited cookies)
324
+ | No specs | Stop — E2E requires specs |
325
+ | Seed test fails | Stop — fix environment |
326
+ | No auth required | Skip auth setup |
327
+ | test-plan.md exists | Read and use (never regenerate) |
328
+ | auth.setup.ts exists | Verify format (update only if stale) |
329
+ | playwright.config.ts exists | Preserve all fields (add only missing) |
330
+ | Test fails (backend) | `test.skip()` + report |
331
+ | Test fails (selector/assertion) | Healer: snapshot → fix → re-run (≤3) |
332
+ | 3 heals failed | Evidence checklistapp bug: `test.skip()`; unclear: report |
333
+ | False pass detected | Add "⚠️ Coverage Gap" to report |
385
334
 
386
335
  ## Guardrails
387
336
 
388
337
  - Read specs from `openspec/changes/<name>/specs/` as source of truth
389
338
  - Do NOT generate tests that contradict the specs
390
- - **DO generate real, runnable Playwright test code** — not placeholders or TODO comments. Every test case in test-plan.md must produce an actual `test(...)` block.
391
- - Do NOT overwrite files outside: `specs/playwright/`, `tests/playwright/`, `openspec/reports/`, `playwright.config.ts`, `tests/auth.setup.ts`
339
+ - **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`
392
341
  - Cap auto-heal at 3 attempts
393
342
  - If no change specified → always ask user to select
@@ -20,6 +20,7 @@ export interface EditorAdapter {
20
20
  }
21
21
  /** Claude Code: .claude/commands/opsx/<id>.md + SKILL.md */
22
22
  declare const claudeAdapter: EditorAdapter;
23
+ declare const ALL_ADAPTERS: EditorAdapter[];
23
24
  /** Detect which editors are installed by checking their config directories */
24
25
  export declare function detectEditors(projectRoot: string): EditorAdapter[];
25
26
  /** Detect Codex by checking if CODEX_HOME or ~/.codex exists */
@@ -30,4 +31,8 @@ export declare function buildCommandMeta(body: string): CommandMeta;
30
31
  export declare function installForAllEditors(body: string, adapters: EditorAdapter[], projectRoot: string): void;
31
32
  /** Install SKILL.md only for Claude Code */
32
33
  export declare function installSkill(projectRoot: string, skillContent: string): void;
33
- export { claudeAdapter };
34
+ /** Install project-level CLAUDE.md with employee-grade standards + OpenSpec context */
35
+ export declare function installProjectClaudeMd(projectRoot: string, standardsContent: string): void;
36
+ /** Read the employee-grade standards from a source file */
37
+ export declare function readEmployeeStandards(srcPath: string): string;
38
+ export { claudeAdapter, ALL_ADAPTERS };
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
1
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import { join, dirname } from 'path';
4
4
  import chalk from 'chalk';
@@ -486,5 +486,35 @@ export function installSkill(projectRoot, skillContent) {
486
486
  writeFileSync(join(skillDir, 'SKILL.md'), skillContent);
487
487
  console.log(chalk.green(` ✓ claude: .claude/skills/openspec-e2e/SKILL.md`));
488
488
  }
489
- export { claudeAdapter };
489
+ /** Install project-level CLAUDE.md with employee-grade standards + OpenSpec context */
490
+ export function installProjectClaudeMd(projectRoot, standardsContent) {
491
+ const dest = join(projectRoot, 'CLAUDE.md');
492
+ const exists = existsSync(dest);
493
+ if (exists) {
494
+ // Append standards inside OPENSPEC:START/END markers
495
+ const existing = readFileSync(dest, 'utf-8');
496
+ const markerStart = '<!-- OPENSPEC:START -->';
497
+ const markerEnd = '<!-- OPENSPEC:END -->';
498
+ if (existing.includes(markerStart) && existing.includes(markerEnd)) {
499
+ // Already has markers, skip
500
+ console.log(chalk.gray(' - CLAUDE.md already has standards markers, skipping'));
501
+ }
502
+ else {
503
+ const updated = existing.trim() + '\n\n' + markerStart + '\n\n' + standardsContent + '\n\n' + markerEnd + '\n';
504
+ writeFileSync(dest, updated);
505
+ console.log(chalk.green(' ✓ CLAUDE.md: appended employee-grade standards'));
506
+ }
507
+ }
508
+ else {
509
+ // No existing CLAUDE.md, create from template
510
+ const content = `# ${projectRoot.split('/').pop()}\n\n` + standardsContent;
511
+ writeFileSync(dest, content);
512
+ console.log(chalk.green(' ✓ CLAUDE.md: created with employee-grade standards'));
513
+ }
514
+ }
515
+ /** Read the employee-grade standards from a source file */
516
+ export function readEmployeeStandards(srcPath) {
517
+ return existsSync(srcPath) ? readFileSync(srcPath, 'utf-8') : '';
518
+ }
519
+ export { claudeAdapter, ALL_ADAPTERS };
490
520
  //# sourceMappingURL=editors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editors.js","sourceRoot":"","sources":["../../src/commands/editors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editors.js","sourceRoot":"","sources":["../../src/commands/editors.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,12 @@ import { fileURLToPath } from 'url';
6
6
  import chalk from 'chalk';
7
7
  import { readFile } from 'fs/promises';
8
8
  import { syncMcpTools } from './mcpSync.js';
9
- import { detectEditors, detectCodex, installForAllEditors, installSkill, claudeAdapter } from './editors.js';
9
+ import { detectEditors, detectCodex, installForAllEditors, installSkill, installProjectClaudeMd, readEmployeeStandards, claudeAdapter } from './editors.js';
10
10
  const TEMPLATE_DIR = fileURLToPath(new URL('../../templates', import.meta.url));
11
11
  const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
12
12
  const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e/SKILL.md', import.meta.url));
13
13
  const CMD_BODY_SRC = fileURLToPath(new URL('../../.claude/commands/opsx/e2e-body.md', import.meta.url));
14
+ const EMPLOYEE_STANDARDS_SRC = fileURLToPath(new URL('../../employee-standards.md', import.meta.url));
14
15
  export async function init(options) {
15
16
  console.log(chalk.blue('\n🔧 OpenSpec + Playwright E2E Setup\n'));
16
17
  const projectRoot = process.cwd();
@@ -98,7 +99,13 @@ export async function init(options) {
98
99
  console.log(chalk.blue('\n─── Generating Seed Test ───'));
99
100
  await generateSeedTest(projectRoot);
100
101
  }
101
- // 8. Summary
102
+ // 8. Install employee-grade CLAUDE.md
103
+ console.log(chalk.blue('\n─── Installing Employee Standards ───'));
104
+ const standards = readEmployeeStandards(EMPLOYEE_STANDARDS_SRC);
105
+ if (standards) {
106
+ installProjectClaudeMd(projectRoot, standards);
107
+ }
108
+ // 9. Summary
102
109
  console.log(chalk.blue('\n─── Summary ───'));
103
110
  console.log(chalk.green(' ✓ Setup complete!\n'));
104
111
  console.log(chalk.bold('Next steps:'));
@@ -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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"}
@@ -0,0 +1,84 @@
1
+ # Claude Code Employee-Grade Configuration
2
+
3
+ > 员工级行为规范,适用于所有项目。
4
+ > 本项目遵循 OpenSpec 规范驱动开发流程(详见 /openspec/)。
5
+
6
+ ---
7
+
8
+ ## 一、代码质量
9
+
10
+ ### 强制验证
11
+
12
+ 禁止在验证完成前报告成功。每次文件修改后必须运行:
13
+
14
+ ```bash
15
+ npx tsc --noEmit && npx eslint . --quiet
16
+ ```
17
+
18
+ 如项目无类型检查,明确告知用户,不得假装成功。
19
+
20
+ ### 高级工程师标准
21
+
22
+ 不接受"最简单方案"和"不超出需求"作为偷懒的借口。如果架构有缺陷、状态重复、模式不一致——说出来并修复。问自己:**高级工程师在 code review 中会拒绝什么?** 把那些全部修掉。
23
+
24
+ ---
25
+
26
+ ## 二、上下文管理
27
+
28
+ ### Step 0 规则
29
+
30
+ 任何结构性重构(>300 LOC)之前,先删除所有死代码(未使用 import/export/prop/console.log)。单独提交清理,再做重构。
31
+ 死代码会提前消耗 token budget,触发 auto-compaction——每次失败会浪费大量 API 调用。保持代码干净直接节省成本。
32
+
33
+ ### 文件读取分段
34
+
35
+ 超过 500 行的文件,不要假设单次读取覆盖了完整文件。根据需要分次读取相关段落,或编辑前重新读取完整文件以确保上下文最新。
36
+
37
+ ### 上下文衰减
38
+
39
+ 超过 10 条消息后,编辑任何文件前必须重新读取。
40
+
41
+ ---
42
+
43
+ ## 三、大规模任务
44
+
45
+ ### 子 Agent 并行化
46
+
47
+ 任务涉及超过 5 个独立文件时,启动并行子 agent(每个 5-8 个文件),每个拥有独立 token budget。
48
+
49
+ ### 分阶段执行
50
+
51
+ 不要在单次响应中完成多文件重构。每个阶段不超过 5 个文件,完成后验证,等待用户批准再继续。
52
+
53
+ ---
54
+
55
+ ## 四、工具限制
56
+
57
+ ### 工具结果截断(50,000 字符)
58
+
59
+ 搜索结果异常少时,用更窄范围重新运行。怀疑截断时告知用户。
60
+
61
+ ### Grep 不是 AST
62
+
63
+ 重命名函数/类型/变量时,必须分开搜索:
64
+
65
+ - 直接调用和引用
66
+ - 类型级引用(interface、泛型)
67
+ - 字符串字面量(动态引用)
68
+ - `require()` / `import`
69
+ - barrel file 和 re-export
70
+ - 测试文件和 mock
71
+
72
+ 不得假设一次 grep 覆盖所有情况。
73
+
74
+ ---
75
+
76
+ ## 五、编辑安全
77
+
78
+ ### 编辑完整性
79
+
80
+ 每次编辑前重新读取文件,编辑后再次读取确认变更正确应用。同一文件连续编辑不超过 3 次,中间必须验证读取。
81
+
82
+ ### 变更完整性
83
+
84
+ 重命名或签名变更完成后,明确告知用户可能遗漏的区域(动态引用、测试 mock 等),提示人工复查。
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openspec-playwright",
3
- "version": "0.1.41",
3
+ "version": "0.1.44",
4
4
  "description": "OpenSpec + Playwright E2E verification setup tool for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,8 @@
8
8
  },
9
9
  "scripts": {
10
10
  "build": "tsc",
11
+ "test": "vitest",
12
+ "test:run": "vitest run",
11
13
  "prepublishOnly": "npm run build",
12
14
  "release": "npm version patch && npm run build && git push && git push --tags && npm publish"
13
15
  },
@@ -18,7 +20,8 @@
18
20
  },
19
21
  "devDependencies": {
20
22
  "@types/node": "^22.0.0",
21
- "typescript": "^5.6.0"
23
+ "typescript": "^5.6.0",
24
+ "vitest": "^4.1.2"
22
25
  },
23
26
  "engines": {
24
27
  "node": ">=20"
package/release-notes.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ## What's Changed
2
2
 
3
- - fix: correct escapeYamlValue usage for all 24 editor adapters
3
+ - feat(SKILL): add Playwright API guardrails and expand Healer decision tree
4
4
 
5
- **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.41
5
+ **Full Changelog**: https://github.com/wxhou/openspec-playwright/releases/tag/v0.1.44
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
1
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import { join, dirname } from 'path';
4
4
  import chalk from 'chalk';
@@ -570,4 +570,35 @@ export function installSkill(projectRoot: string, skillContent: string): void {
570
570
  console.log(chalk.green(` ✓ claude: .claude/skills/openspec-e2e/SKILL.md`));
571
571
  }
572
572
 
573
- export { claudeAdapter };
573
+ /** Install project-level CLAUDE.md with employee-grade standards + OpenSpec context */
574
+ export function installProjectClaudeMd(projectRoot: string, standardsContent: string): void {
575
+ const dest = join(projectRoot, 'CLAUDE.md');
576
+ const exists = existsSync(dest);
577
+ if (exists) {
578
+ // Append standards inside OPENSPEC:START/END markers
579
+ const existing = readFileSync(dest, 'utf-8');
580
+ const markerStart = '<!-- OPENSPEC:START -->';
581
+ const markerEnd = '<!-- OPENSPEC:END -->';
582
+
583
+ if (existing.includes(markerStart) && existing.includes(markerEnd)) {
584
+ // Already has markers, skip
585
+ console.log(chalk.gray(' - CLAUDE.md already has standards markers, skipping'));
586
+ } else {
587
+ const updated = existing.trim() + '\n\n' + markerStart + '\n\n' + standardsContent + '\n\n' + markerEnd + '\n';
588
+ writeFileSync(dest, updated);
589
+ console.log(chalk.green(' ✓ CLAUDE.md: appended employee-grade standards'));
590
+ }
591
+ } else {
592
+ // No existing CLAUDE.md, create from template
593
+ const content = `# ${projectRoot.split('/').pop()}\n\n` + standardsContent;
594
+ writeFileSync(dest, content);
595
+ console.log(chalk.green(' ✓ CLAUDE.md: created with employee-grade standards'));
596
+ }
597
+ }
598
+
599
+ /** Read the employee-grade standards from a source file */
600
+ export function readEmployeeStandards(srcPath: string): string {
601
+ return existsSync(srcPath) ? readFileSync(srcPath, 'utf-8') : '';
602
+ }
603
+
604
+ export { claudeAdapter, ALL_ADAPTERS };
@@ -11,12 +11,13 @@ import { fileURLToPath } from 'url';
11
11
  import chalk from 'chalk';
12
12
  import { readFile } from 'fs/promises';
13
13
  import { syncMcpTools } from './mcpSync.js';
14
- import { detectEditors, detectCodex, installForAllEditors, installSkill, claudeAdapter } from './editors.js';
14
+ import { detectEditors, detectCodex, installForAllEditors, installSkill, installProjectClaudeMd, readEmployeeStandards, claudeAdapter } from './editors.js';
15
15
 
16
16
  const TEMPLATE_DIR = fileURLToPath(new URL('../../templates', import.meta.url));
17
17
  const SCHEMA_DIR = fileURLToPath(new URL('../../schemas', import.meta.url));
18
18
  const SKILL_SRC = fileURLToPath(new URL('../../.claude/skills/openspec-e2e/SKILL.md', import.meta.url));
19
19
  const CMD_BODY_SRC = fileURLToPath(new URL('../../.claude/commands/opsx/e2e-body.md', import.meta.url));
20
+ const EMPLOYEE_STANDARDS_SRC = fileURLToPath(new URL('../../employee-standards.md', import.meta.url));
20
21
 
21
22
  export interface InitOptions {
22
23
  change?: string;
@@ -121,7 +122,14 @@ export async function init(options: InitOptions) {
121
122
  await generateSeedTest(projectRoot);
122
123
  }
123
124
 
124
- // 8. Summary
125
+ // 8. Install employee-grade CLAUDE.md
126
+ console.log(chalk.blue('\n─── Installing Employee Standards ───'));
127
+ const standards = readEmployeeStandards(EMPLOYEE_STANDARDS_SRC);
128
+ if (standards) {
129
+ installProjectClaudeMd(projectRoot, standards);
130
+ }
131
+
132
+ // 9. Summary
125
133
  console.log(chalk.blue('\n─── Summary ───'));
126
134
  console.log(chalk.green(' ✓ Setup complete!\n'));
127
135
 
@@ -13,6 +13,7 @@
13
13
  // For multi-user testing, add more setup blocks with different storageState paths.
14
14
 
15
15
  import { test as setup, expect } from '@playwright/test';
16
+ import { existsSync } from 'fs';
16
17
 
17
18
  // ─── API Login (preferred) ───────────────────────────────────────────────────
18
19
  // If your app has a login API, configure it in tests/playwright/credentials.yaml:
@@ -25,8 +26,10 @@ setup('authenticate via API', async ({ page }) => {
25
26
  const password = process.env.E2E_PASSWORD;
26
27
 
27
28
  if (!username || !password) {
28
- console.warn('⚠ E2E_USERNAME or E2E_PASSWORD not set — skipping API auth');
29
- return;
29
+ throw new Error(
30
+ 'E2E_USERNAME and E2E_PASSWORD environment variables are required.\n' +
31
+ 'Set them with: export E2E_USERNAME=xxx E2E_PASSWORD=yyy'
32
+ );
30
33
  }
31
34
 
32
35
  const res = await page.request.post(`${baseUrl}/api/auth/login`, {
@@ -38,6 +41,10 @@ setup('authenticate via API', async ({ page }) => {
38
41
  }
39
42
 
40
43
  await page.context().storageState({ path: './playwright/.auth/user.json' });
44
+
45
+ if (!existsSync('./playwright/.auth/user.json')) {
46
+ throw new Error('Auth setup failed: storageState file was not created');
47
+ }
41
48
  });
42
49
 
43
50
  // ─── UI Login (fallback) ─────────────────────────────────────────────────────
@@ -49,8 +56,10 @@ setup('authenticate via UI', async ({ page }) => {
49
56
  const password = process.env.E2E_PASSWORD;
50
57
 
51
58
  if (!username || !password) {
52
- console.warn('⚠ E2E_USERNAME or E2E_PASSWORD not set — skipping UI auth');
53
- return;
59
+ throw new Error(
60
+ 'E2E_USERNAME and E2E_PASSWORD environment variables are required.\n' +
61
+ 'Set them with: export E2E_USERNAME=xxx E2E_PASSWORD=yyy'
62
+ );
54
63
  }
55
64
 
56
65
  // TODO: Update these selectors to match your login page
@@ -74,4 +83,8 @@ setup('authenticate via UI', async ({ page }) => {
74
83
  await expect(page).not.toHaveURL(/.*login.*|.*signin.*/);
75
84
 
76
85
  await page.context().storageState({ path: './playwright/.auth/user.json' });
86
+
87
+ if (!existsSync('./playwright/.auth/user.json')) {
88
+ throw new Error('Auth setup failed: storageState file was not created');
89
+ }
77
90
  });
@@ -21,13 +21,13 @@ api: /api/auth/login # Leave empty for UI login
21
21
 
22
22
  users:
23
23
  - name: user
24
- username: test@example.com
25
- password: testpassword123
24
+ username: CHANGE_ME@example.com
25
+ password: CHANGE_ME_PASSWORD
26
26
 
27
27
  # Multi-user example (uncomment and configure for role-based tests):
28
28
  # - name: admin
29
- # username: admin@example.com
30
- # password: adminpassword123
29
+ # username: CHANGE_ME@admin.com
30
+ # password: CHANGE_ME_ADMIN_PASSWORD
31
31
  # - name: premium
32
- # username: premium@example.com
33
- # password: premiumpassword123
32
+ # username: CHANGE_ME@premium.com
33
+ # password: CHANGE_ME_PREMIUM_PASSWORD
@@ -0,0 +1,180 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ escapeYamlValue,
4
+ formatTagsArray,
5
+ buildCommandMeta,
6
+ detectEditors,
7
+ detectCodex,
8
+ ALL_ADAPTERS,
9
+ } from '../src/commands/editors.js';
10
+
11
+ // ─── escapeYamlValue ──────────────────────────────────────────────────────────
12
+
13
+ describe('escapeYamlValue', () => {
14
+ it('returns raw value for plain strings', () => {
15
+ expect(escapeYamlValue('hello world')).toBe('hello world');
16
+ expect(escapeYamlValue('simple')).toBe('simple');
17
+ });
18
+
19
+ it('quotes strings with colons', () => {
20
+ expect(escapeYamlValue('hello: world')).toBe('"hello: world"');
21
+ });
22
+
23
+ it('quotes strings starting with whitespace', () => {
24
+ expect(escapeYamlValue(' hello')).toBe('" hello"');
25
+ });
26
+
27
+ it('quotes strings ending with whitespace', () => {
28
+ expect(escapeYamlValue('hello ')).toBe('"hello "');
29
+ });
30
+
31
+ it('quotes and escapes strings containing quotes', () => {
32
+ expect(escapeYamlValue('say "hello"')).toBe('"say \\"hello\\""');
33
+ });
34
+
35
+ it('quotes and escapes strings containing newlines', () => {
36
+ expect(escapeYamlValue('line1\nline2')).toBe('"line1\\nline2"');
37
+ });
38
+
39
+ it('quotes strings with special YAML chars', () => {
40
+ expect(escapeYamlValue('key: value')).toBe('"key: value"');
41
+ expect(escapeYamlValue('# comment')).toBe('"# comment"');
42
+ expect(escapeYamlValue('a{b}c')).toBe('"a{b}c"');
43
+ });
44
+
45
+ it('quotes strings with array-like chars', () => {
46
+ expect(escapeYamlValue('[a, b]')).toBe('"[a, b]"');
47
+ });
48
+ });
49
+
50
+ // ─── formatTagsArray ─────────────────────────────────────────────────────────
51
+
52
+ describe('formatTagsArray', () => {
53
+ it('formats empty tags', () => {
54
+ expect(formatTagsArray([])).toBe('[]');
55
+ });
56
+
57
+ it('formats single tag', () => {
58
+ expect(formatTagsArray(['openspec'])).toBe('[openspec]');
59
+ });
60
+
61
+ it('formats multiple tags', () => {
62
+ expect(formatTagsArray(['openspec', 'playwright', 'e2e'])).toBe(
63
+ '[openspec, playwright, e2e]'
64
+ );
65
+ });
66
+
67
+ it('escapes tags with colons using YAML quoting', () => {
68
+ // escapeYamlValue quotes 'tag:colon' → "tag:colon", so array has quoted element
69
+ expect(formatTagsArray(['tag:colon'])).toBe('["tag:colon"]');
70
+ });
71
+ });
72
+
73
+ // ─── buildCommandMeta ─────────────────────────────────────────────────────────
74
+
75
+ describe('buildCommandMeta', () => {
76
+ it('creates meta with correct id', () => {
77
+ const meta = buildCommandMeta('test body');
78
+ expect(meta.id).toBe('e2e');
79
+ });
80
+
81
+ it('creates meta with correct fields', () => {
82
+ const meta = buildCommandMeta('test body');
83
+ expect(meta.name).toBe('OPSX: E2E');
84
+ expect(meta.description).toBe('Run Playwright E2E verification for an OpenSpec change');
85
+ expect(meta.category).toBe('OpenSpec');
86
+ expect(meta.tags).toEqual(['openspec', 'playwright', 'e2e', 'testing']);
87
+ expect(meta.body).toBe('test body');
88
+ });
89
+ });
90
+
91
+ // ─── detectEditors ────────────────────────────────────────────────────────────
92
+
93
+ describe('detectEditors', () => {
94
+ it('returns empty array for non-existent directory', () => {
95
+ const result = detectEditors('/tmp/nonexistent-project-xyz-123');
96
+ expect(result).toEqual([]);
97
+ });
98
+
99
+ it('detects Claude Code when .claude directory exists', () => {
100
+ const result = detectEditors('/Users/wxhou/Documents/openspec-playwright');
101
+ const names = result.map(a => a.toolId);
102
+ expect(names).toContain('claude');
103
+ });
104
+ });
105
+
106
+ // ─── detectCodex ─────────────────────────────────────────────────────────────
107
+
108
+ describe('detectCodex', () => {
109
+ it('returns null when CODEX_HOME is set to non-existent path', () => {
110
+ const original = process.env.CODEX_HOME;
111
+ process.env.CODEX_HOME = '/tmp/this-codex-dir-does-not-exist-xyz';
112
+ const result = detectCodex();
113
+ expect(result).toBeNull();
114
+ if (original !== undefined) {
115
+ process.env.CODEX_HOME = original;
116
+ } else {
117
+ delete process.env.CODEX_HOME;
118
+ }
119
+ });
120
+ });
121
+
122
+ // ─── Adapter format correctness ───────────────────────────────────────────────
123
+
124
+ describe('Adapter format correctness', () => {
125
+ it('every adapter has a toolId', () => {
126
+ for (const adapter of ALL_ADAPTERS) {
127
+ expect(adapter.toolId).toBeTruthy();
128
+ }
129
+ });
130
+
131
+ it('every adapter has formatCommand that returns non-empty string', () => {
132
+ const meta = buildCommandMeta('test body content');
133
+ for (const adapter of ALL_ADAPTERS) {
134
+ const output = adapter.formatCommand(meta);
135
+ expect(output.length).toBeGreaterThan(0);
136
+ }
137
+ });
138
+
139
+ it('every adapter getCommandPath returns a path with the id', () => {
140
+ const meta = buildCommandMeta('test');
141
+ for (const adapter of ALL_ADAPTERS) {
142
+ const path = adapter.getCommandPath(meta.id);
143
+ expect(path).toContain('opsx');
144
+ }
145
+ });
146
+
147
+ it('Claude adapter output has YAML frontmatter', () => {
148
+ const meta = buildCommandMeta('body');
149
+ const output = ALL_ADAPTERS[0].formatCommand(meta);
150
+ expect(output).toContain('---');
151
+ expect(output).toContain('name:');
152
+ expect(output).toContain('description:');
153
+ });
154
+
155
+ it('TOML adapters (gemini, qwen) do not use YAML frontmatter', () => {
156
+ const meta = buildCommandMeta('body');
157
+ const adapters = ALL_ADAPTERS.filter(
158
+ a => a.toolId === 'gemini' || a.toolId === 'qwen'
159
+ );
160
+ for (const adapter of adapters) {
161
+ const output = adapter.formatCommand(meta);
162
+ expect(output).not.toContain('---');
163
+ expect(output).toContain('description =');
164
+ expect(output).toContain('prompt =');
165
+ }
166
+ });
167
+
168
+ it('crush and qoder use raw values without escaping in name/description', () => {
169
+ const meta = buildCommandMeta('body');
170
+ const adapters = ALL_ADAPTERS.filter(
171
+ a => a.toolId === 'crush' || a.toolId === 'qoder'
172
+ );
173
+ for (const adapter of adapters) {
174
+ const output = adapter.formatCommand(meta);
175
+ // Should NOT have escaped quotes in the raw-value fields
176
+ expect(output).not.toContain('\\\\"');
177
+ expect(output).toContain('name: OPSX: E2E');
178
+ }
179
+ });
180
+ });
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ['tests/**/*.test.ts'],
6
+ globals: true,
7
+ environment: 'node',
8
+ },
9
+ });
Binary file