openspec-playwright 0.2.8 → 0.2.10
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/.claude/skills/openspec-e2e/SKILL.md +53 -22
- package/employee-standards.md +68 -21
- package/package.json +1 -1
|
@@ -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
|
+
version: "2.24"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Input
|
|
@@ -44,13 +44,7 @@ Both modes update `app-knowledge.md` and `app-exploration.md`. All `.spec.ts` fi
|
|
|
44
44
|
用户操作 → 浏览器 UI → 后端 → 数据库 → UI 反馈
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
**API only as fallback** —
|
|
48
|
-
|
|
49
|
-
- Triggering HTTP 5xx/4xx error responses (hard to reach via UI)
|
|
50
|
-
- Edge cases requiring pre-condition data that UI cannot set up
|
|
51
|
-
- Cases where Step 4 exploration confirmed no UI element exists
|
|
52
|
-
|
|
53
|
-
**Setup vs Assertion**: API is acceptable for **setup/precondition** (preparing test data). Every **final assertion** about visible UI state must use UI selectors — never use `page.request` to assert something the user can see on screen.
|
|
47
|
+
**API only as fallback** — See **Mock data rule** below. `page.request` is acceptable for pre-condition setup (preparing test data) and API-level mocking via `page.route()`. Every **final assertion** about visible UI state must use UI selectors — never use `page.request` to assert something the user can see on screen.
|
|
54
48
|
|
|
55
49
|
**Decision rule (per assertion)**:
|
|
56
50
|
|
|
@@ -71,7 +65,24 @@ Is the assertion about a computed/counted/calculated value?
|
|
|
71
65
|
→ No → UI assertion is sufficient
|
|
72
66
|
```
|
|
73
67
|
|
|
74
|
-
**
|
|
68
|
+
**Mock data rule:**
|
|
69
|
+
|
|
70
|
+
- **Frontend: forbidden.** UI interactions must use real browser + real app data. Mocking frontend code (JS variables, component state, module-level stubs) hides real integration issues. If the frontend cannot reach a scenario through normal UI flow → **ask the user**.
|
|
71
|
+
- **API: allowed at HTTP level.** Use `page.route()` to intercept and mock API responses (status codes, body data, latency) when:
|
|
72
|
+
- Triggering HTTP 5xx/4xx error responses (hard to reach via UI)
|
|
73
|
+
- Edge cases requiring pre-condition data that UI cannot set up
|
|
74
|
+
- Third-party API failures (payment, SMS, email providers)
|
|
75
|
+
- **Scope: API level only** — `page.route()` intercepts HTTP; do NOT mock at the database or backend service level. Mocking below the HTTP layer bypasses the real API contract and produces false confidence.
|
|
76
|
+
- **User consent required.** Before using `page.route()` mocking, stop and ask:
|
|
77
|
+
```
|
|
78
|
+
API mocking needed for: <reason>
|
|
79
|
+
Mocked endpoint: <URL or pattern>
|
|
80
|
+
Expected behavior: <what the test verifies>
|
|
81
|
+
Reply **yes** to proceed, or tell me to find a UI-based approach instead.
|
|
82
|
+
```
|
|
83
|
+
If the user says no → attempt a UI-based approach or skip that test case.
|
|
84
|
+
|
|
85
|
+
**Examples where API assertion is required:
|
|
75
86
|
|
|
76
87
|
```typescript
|
|
77
88
|
// ❌ UI-only assertion — hides calculation bugs
|
|
@@ -316,8 +327,6 @@ Record findings in `app-exploration.md` → **Special Elements Detected** table.
|
|
|
316
327
|
|
|
317
328
|
Output: `openspec/changes/<name>/specs/playwright/app-exploration.md`
|
|
318
329
|
|
|
319
|
-
Template: read from `.claude/skills/openspec-e2e/templates/app-exploration.md` (project-local skill directory)
|
|
320
|
-
|
|
321
330
|
Key fields per route:
|
|
322
331
|
|
|
323
332
|
- **URL**: `${BASE_URL}<path>`
|
|
@@ -349,7 +358,7 @@ After writing `app-exploration.md`, extract **project-level shared knowledge** a
|
|
|
349
358
|
| Common Selector Patterns | New patterns discovered that apply across routes |
|
|
350
359
|
| SPA Routing | SPA framework, routing behavior |
|
|
351
360
|
| Project Conventions | BASE_URL, auth method, multi-user roles |
|
|
352
|
-
| Selector Fixes | Healed selectors (see Step 9) — route, old
|
|
361
|
+
| Selector Fixes | Healed selectors (see Step 9) — route, old → new selector, reason, date |
|
|
353
362
|
|
|
354
363
|
Append only new/changed items — preserve existing content.
|
|
355
364
|
|
|
@@ -383,7 +392,7 @@ Reply **yes** to proceed, or tell me to exclude routes or adjust strategies.
|
|
|
383
392
|
|
|
384
393
|
**Create test cases**: functional requirement → test case, with `@role` and `@auth` tags. Reference verified selectors from app-exploration.md.
|
|
385
394
|
|
|
386
|
-
|
|
395
|
+
If a test case requires `page.route()` API mocking → append `⚠️ API Mock` flag to the test case line in the summary, with reason.
|
|
387
396
|
|
|
388
397
|
**Idempotency**: If test-plan.md exists → read and use, **but you MAY supplement missing test cases**. "Do not regenerate" means: do not discard existing cases, but you CAN add new ones discovered during Step 4 exploration that weren't in the original spec (e.g., empty states, error paths found during DOM exploration).
|
|
389
398
|
|
|
@@ -430,8 +439,6 @@ If the user requests changes → update test-plan.md → re-display summary →
|
|
|
430
439
|
|
|
431
440
|
**Page Object pattern** — read before writing any page file:
|
|
432
441
|
|
|
433
|
-
Read: `.claude/skills/openspec-e2e/templates/e2e-test.ts` → LoginPage example
|
|
434
|
-
|
|
435
442
|
```typescript
|
|
436
443
|
// ✅ 正确:getters + async actions + this.click/fill
|
|
437
444
|
export class LoginPage extends BasePage {
|
|
@@ -497,7 +504,7 @@ Is this assertion about a visible UI result?
|
|
|
497
504
|
|
|
498
505
|
**Test coverage — empty states**: For list/detail pages, explore the empty state. If the app shows a "no data" UI when the list is empty, generate a test to verify it. Empty states are often missing from specs but are real user paths.
|
|
499
506
|
|
|
500
|
-
**Test coverage — special elements**: Check `app-exploration.md` → **Special Elements Detected** table. For each special element, generate tests using
|
|
507
|
+
**Test coverage — special elements**: Check `app-exploration.md` → **Special Elements Detected** table. For each special element, generate tests using the following strategies:
|
|
501
508
|
- Canvas: screenshot + boundingBox → dimensions > 0, or 2D pixel verification
|
|
502
509
|
- WebGL: screenshot only (no pixel comparison — rendering varies)
|
|
503
510
|
- Iframe: `frameLocator` + assert inner content visible
|
|
@@ -508,7 +515,7 @@ Is this assertion about a visible UI result?
|
|
|
508
515
|
**Test coverage — AI-opaque elements**: For CAPTCHA, OTP, slider CAPTCHA, file upload, and drag-drop — elements that Playwright cannot reliably automate:
|
|
509
516
|
|
|
510
517
|
1. Mark the element in `app-exploration.md` → **Special Elements Detected** table with type and automation strategy
|
|
511
|
-
2. Generate the test using the appropriate strategy
|
|
518
|
+
2. Generate the test using the appropriate strategy:
|
|
512
519
|
- **CAPTCHA**: Bypass via `auth.setup.ts` storageState, or skip with `test.skip()`, or verify via API
|
|
513
520
|
- **OTP**: Use pre-verified test credentials (`E2E_OTP_CODE` env var), or development bypass flag
|
|
514
521
|
- **File upload**: Use `page.setInputFiles()` with fixture files
|
|
@@ -586,7 +593,7 @@ test('user can login', async ({ page }) => {
|
|
|
586
593
|
| `getByRole`, `getByTestId`, `getByLabel` | CSS class (`'.notification-bell'`), CSS ID (`'#avatarBtn'`) |
|
|
587
594
|
| `waitForSelector(targetElement)` | hardcoded `200ms` / `500ms` delays |
|
|
588
595
|
|
|
589
|
-
See
|
|
596
|
+
See above for Page Object pattern, LoginPage example, and BasePage utilities.
|
|
590
597
|
|
|
591
598
|
If the file exists → diff against test-plan, add only missing test cases.
|
|
592
599
|
|
|
@@ -621,7 +628,7 @@ Auth required. To set up:
|
|
|
621
628
|
|
|
622
629
|
**Output**: `playwright.config.ts` (project root; or `tests/playwright/playwright.config.ts` if config already exists there)
|
|
623
630
|
|
|
624
|
-
If missing → generate
|
|
631
|
+
If missing → generate a minimal `playwright.config.ts` with webServer, projects, and reporters.
|
|
625
632
|
|
|
626
633
|
**Auto-detect BASE_URL** (in priority order):
|
|
627
634
|
|
|
@@ -660,6 +667,10 @@ If tests fail → use Playwright MCP tools to inspect UI, fix selectors, re-run.
|
|
|
660
667
|
| `browser_take_screenshot` | Visually compare before/after fixes |
|
|
661
668
|
| `browser_run_code` | Execute custom fix logic (optional) |
|
|
662
669
|
|
|
670
|
+
**Before Phase 1 — check accumulated knowledge:**
|
|
671
|
+
|
|
672
|
+
Read `tests/playwright/app-knowledge.md` → **Selector Fixes** table. If the failing test's selector or route matches a known fix, use it directly (skip Phase 2). If partial match → use as the top candidate in Phase 2 Step 5a. If file does not exist → skip.
|
|
673
|
+
|
|
663
674
|
**Healer — Phase 1: Triage**
|
|
664
675
|
|
|
665
676
|
When a test fails, classify before attempting repair.
|
|
@@ -761,9 +772,29 @@ After Triage classifies failure as "Test Bug" or "Ambiguous":
|
|
|
761
772
|
- Data values differ (e.g., expected "¥1000" but got "¥999" → **Phase 3**, could be rounding, discount, or calculation bug)
|
|
762
773
|
- Missing elements after interaction (e.g., "after creating order, success message should appear" → no message → **Phase 3**)
|
|
763
774
|
|
|
764
|
-
5. If selector issue →
|
|
775
|
+
5. If selector issue → generate candidate list, then select:
|
|
776
|
+
|
|
777
|
+
**5a. Extract candidates** — identify the target element from the failing test's assertion, then from the snapshot list all selectors for that element:
|
|
778
|
+
|
|
779
|
+
First check `app-knowledge.md` → **Common Selector Patterns** for project-specific conventions (e.g., if project uses Tailwind and `.btn-primary` is listed as preferred → treat it as Fair or higher, not Fragile).
|
|
780
|
+
|
|
781
|
+
```
|
|
782
|
+
Target: <element from failing assertion, e.g. "button with text 'Submit'">
|
|
783
|
+
Candidates (stable → fragile):
|
|
784
|
+
- getByRole(button, { name: 'Submit' }) ← Stable (semantic)
|
|
785
|
+
- getByText('Submit') ← Fair (unique text)
|
|
786
|
+
- getByLabel('Email') ← Fair (form fields)
|
|
787
|
+
- locator('#submit') ← Fair (id attribute)
|
|
788
|
+
- locator('.btn-primary') ← Fragile (style class) — upgrade if listed in Common Selector Patterns
|
|
789
|
+
- locator('button:nth-child(3)') ← Fragile (DOM order)
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
Stability: `getByRole` > `getByText`/`getByLabel` > `locator('#id')` > `locator('.class')` > `locator('nth-child')`. Upgrade stability if `app-knowledge.md` → **Common Selector Patterns** explicitly lists the selector as preferred for this project.
|
|
793
|
+
|
|
794
|
+
**5b. Select top candidate** — pick the highest-stability candidate that matches the target. Output: `SELECTED: <selector> — reason: <why this one>`.
|
|
795
|
+
|
|
765
796
|
6. Apply fix → re-run **only that test** (attempt 1/3)
|
|
766
|
-
7. If healed → append to `app-knowledge.md` → **Selector Fixes** table (route, old → new selector, reason)
|
|
797
|
+
7. If healed → append to `app-knowledge.md` → **Selector Fixes** table (route, old → new selector, reason, date)
|
|
767
798
|
|
|
768
799
|
**Element Missing handling (when browser_snapshot shows element not found):**
|
|
769
800
|
|
|
@@ -858,7 +889,7 @@ Read report at `openspec/reports/playwright-e2e-<name>-<timestamp>.md`. Present:
|
|
|
858
889
|
- Human Escalations (if any, with user decision)
|
|
859
890
|
- Recommendations with `file:line` references
|
|
860
891
|
|
|
861
|
-
|
|
892
|
+
Generate report based on the structure described in Step 11.
|
|
862
893
|
|
|
863
894
|
**Update tasks.md**:
|
|
864
895
|
- If 0 active App Bugs → find E2E-related items, append `✅ Verified via Playwright E2E (<timestamp>)`.
|
package/employee-standards.md
CHANGED
|
@@ -1,50 +1,97 @@
|
|
|
1
|
-
# Claude Code Employee-Grade Configuration
|
|
1
|
+
# Claude Code Employee-Grade Configuration + gstack + openspec-playwright 生产闭环
|
|
2
2
|
|
|
3
3
|
> 员工级行为规范,适用于 OpenSpec 项目。
|
|
4
|
-
>
|
|
4
|
+
> 严格遵循 OpenSpec 规范驱动开发 + gstack 角色化虚拟工程团队 + Playwright 自动 E2E 验证。
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 0. 适用范围
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
本规范适用于 OpenSpec + openspec-playwright 项目(Claude Code 作为开发工具)。
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
E2E 工作流前提(由用户确保,非 AI 操作):
|
|
13
|
+
- OpenSpec CLI:`npm install -g @fission-ai/openspec && openspec init`(提供 `/opsx:propose`、`/opsx:archive` 等命令)
|
|
14
|
+
- openspec-playwright:`openspec-pw init`(提供 `/opsx:e2e` 命令)
|
|
15
|
+
- Playwright MCP:`claude mcp add playwright npx @playwright/mcp@latest`
|
|
16
|
+
- 浏览器已安装:`npx playwright install --with-deps`
|
|
17
|
+
- 项目包含 `specs/`、`changes/`、`tests/playwright/` 目录
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
## 1. 浏览器操作约束
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
所有浏览器操作**必须**使用 gstack 的 `/browse`(禁止使用其他 MCP Chrome 工具)。
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
Claude Code 会根据上下文自动调度 gstack 技能,无需手动路由。
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
**冲突解决**:gstack 任何想直接修改代码的行为,都必须先确认当前 OpenSpec proposal 是否已存在并通过(检查 `changes/<name>/proposal.md` 是否处于 `approved` 状态)。
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
## 2. 代码质量(强制执行)
|
|
28
|
+
**lint + typecheck 后才能算成功**。动手前,先探索项目用什么工具:查看 `package.json` scripts、`Makefile`、`pyproject.toml`、`justfile` 等,找到该语言的 lint + typecheck 命令并执行。工具不存在时,明确告知用户,不得假装成功。
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
**拒绝"够用就行"**。架构缺陷、状态重复、模式不一致——必须说出来并修复。
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
**安全防护**:写 Go 时关注内存安全,写 Python 时关注反序列化,写 Web/API 时参考 OWASP Top 10 / OWASP API Top 10。先了解所用场景的风险模型。
|
|
33
|
+
|
|
34
|
+
## 3. 上下文管理
|
|
35
|
+
**文件读取完整**:超过 500 行的文件,不要假设单次读取覆盖完整内容——根据需要分次读取或编辑前重新读取完整文件。超过 10 条消息后,编辑任何文件前强制重新读取。
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
**OpenSpec 阶段隔离**:`specs/playwright/`、`tests/playwright/`(seed 除外)和 `test-plan.md` 由 `/opsx:e2e` 显式触发,不由 explore/propose/continue/apply/verify 等阶段自动推断。E2E 工作流是独立的。
|
|
38
|
+
|
|
39
|
+
**重构前清死代码**:未使用的 import/export/prop/console.log 先删掉,单独提交,再做重构。
|
|
29
40
|
|
|
41
|
+
## 4. 大规模任务处理
|
|
30
42
|
**子 Agent 并行化**:任务涉及超过 5 个独立文件时,启动并行子 agent(每个 5-8 个文件),每个拥有独立 token budget。
|
|
31
43
|
|
|
32
44
|
**分阶段执行**:每个阶段不超过 5 个文件,完成后验证,等待用户批准再继续。
|
|
33
45
|
|
|
34
|
-
**200 行以上修改必须走 OpenSpec**:代码改动超过 200 行时,禁止直接修改,必须通过 OpenSpec
|
|
46
|
+
**200 行以上修改必须走 OpenSpec**:代码改动超过 200 行时,禁止直接修改,必须通过 OpenSpec 工作流(/opsx:propose)。
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
## 5. 工具限制与编辑安全
|
|
49
|
+
**搜索要全**:重命名时,用 Grep 覆盖调用、类型、字符串、`import`、barrel file、测试 mock,不得假设一次覆盖所有情况。
|
|
37
50
|
|
|
38
|
-
|
|
51
|
+
**编辑要求**:编辑后重新读取文件确认变更正确应用。同一文件连续编辑不超过 3 次,中间必须重新读取。变更完成后,明确告知用户可能遗漏的区域(动态引用、测试 mock 等),提示人工复查。
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
**不主动推送**:除非用户明确要求,否则不推送代码。
|
|
54
|
+
|
|
55
|
+
**中文回复**:用中文回复用户。
|
|
41
56
|
|
|
42
57
|
---
|
|
43
58
|
|
|
44
|
-
##
|
|
59
|
+
## 6. 完整生产工作流(严格执行 + 反馈循环)
|
|
45
60
|
|
|
46
|
-
|
|
61
|
+
```
|
|
62
|
+
1. 探索与提案 → /opsx:propose → 生成 proposal + scenarios
|
|
63
|
+
2. 产品与架构思考(按需触发)
|
|
64
|
+
3. 设计审查 → Build(遵守 OpenSpec delta markers)→ /review 自审
|
|
65
|
+
4. E2E 测试 → /opsx:e2e <change-name> → /qa(真实浏览器 + healer)
|
|
66
|
+
5. 验证通过后 → /opsx:archive
|
|
67
|
+
6. 发布 → /ship 或 /land-and-deploy
|
|
68
|
+
7. 迭代回顾 → /retro
|
|
69
|
+
```
|
|
47
70
|
|
|
48
|
-
|
|
71
|
+
### 步骤详解
|
|
49
72
|
|
|
50
|
-
|
|
73
|
+
**1. 探索与规范**:`/opsx:propose` → 生成 proposal + scenarios(记录到 `specs/` 和 `changes/`)。对 proposal 进行评审和调整。如需代码探索,单独使用 `/opsx:explore`(不是生成规范)。
|
|
74
|
+
|
|
75
|
+
**2. 产品与架构思考**(按需触发,不是每个功能都走):
|
|
76
|
+
- `/office-hours`:产品方向、范围、优先级不确定时
|
|
77
|
+
- `/plan-ceo-review`:产品战略影响、竞争格局变化时
|
|
78
|
+
- `/plan-eng-review`:架构影响(新增服务、API 契约变更、数据模型重构)时
|
|
79
|
+
|
|
80
|
+
**3. 设计与实现**:设计审查 → Build(遵守 OpenSpec delta markers),过程中 `/review` 自审。构建完成后,E2E 测试覆盖通过才能继续。
|
|
81
|
+
|
|
82
|
+
**4. E2E 测试生成与执行**:`/opsx:e2e <change-name>` 生成 Playwright 测试并执行 → 执行 `/qa`(真实浏览器 + healer)验证。E2E 通过后进入发布环节。
|
|
83
|
+
|
|
84
|
+
**5. 验证通过后**:`/opsx:archive` 永久归档,更新 `specs/`
|
|
85
|
+
|
|
86
|
+
**6. 发布**:`/ship` 或 `/land-and-deploy`
|
|
87
|
+
|
|
88
|
+
**7. 迭代回顾**:`/retro`
|
|
89
|
+
|
|
90
|
+
### 反馈循环(生产中必然发生)
|
|
91
|
+
|
|
92
|
+
| 信号 | 回到 |
|
|
93
|
+
|------|------|
|
|
94
|
+
| 测试失败(App Bug) | 步骤 3 修复后 → 步骤 4 重新测试 |
|
|
95
|
+
| 发现架构问题 | 步骤 2 重新评审 → 步骤 3 修复 |
|
|
96
|
+
| proposal 需调整 | 步骤 1 重新提案 |
|
|
97
|
+
| 评审不通过 | 回到对应步骤重新处理 |
|