openspec-playwright 0.2.0 → 0.2.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.
@@ -49,12 +49,14 @@ Both modes update `app-knowledge.md` and `app-exploration.md`. All `.spec.ts` fi
49
49
  - Edge cases requiring pre-condition data that UI cannot set up
50
50
  - Cases where Step 4 exploration confirmed no UI element exists
51
51
 
52
- **Decision rule**:
52
+ **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.
53
+
54
+ **Decision rule (per assertion)**:
53
55
 
54
56
  ```
55
- Can this be tested through the UI?
56
- → Yes → page.getByRole/ByLabel/ByText + click/fill/type + assert UI
57
- → No → record reason → use page.request
57
+ Can the user SEE this on screen?
58
+ → Yes → MUST use: page.getByRole/ByLabel/ByText + expect()
59
+ → No → Record reason → page.request acceptable
58
60
  ```
59
61
 
60
62
  **Never use API calls to replace routine UI flows.** If a test completes in < 200ms, it is almost certainly using `page.request` instead of real UI interactions.
@@ -192,8 +194,9 @@ await browser_navigate(`${BASE_URL}/<route>`);
192
194
 
193
195
  Wait for page stability:
194
196
 
195
- - Prefer `browser_wait_for` with text or selector
196
- - Avoid `networkidle` / `load` — too slow or unreliable
197
+ - **React 19 / Next.js App Router**: use `page.waitForLoadState('networkidle')` React 19 concurrent mode batches events asynchronously; 200-500ms timeouts are unreliable under resource contention
198
+ - **Vue 2/3 / Angular / React 18 / Plain JS / jQuery**: `waitForSelector(targetElement)` is sufficient and faster DOM updates are synchronous; Playwright's actionability checks auto-wait correctly
199
+ - Prefer specific element waits (`waitForSelector`) over generic load states
197
200
  - Ready signal: heading, spinner disappears, or URL change
198
201
 
199
202
  #### 4.3. Parse the snapshot
@@ -472,6 +475,16 @@ For each discovered route:
472
475
  - Read: test-plan.md, app-exploration.md, app-knowledge.md, seed.spec.ts
473
476
  - For each test case: verify selectors in real browser, then write Playwright code
474
477
 
478
+ **Per-assertion UI check** (before writing each assertion):
479
+ ```
480
+ Is this assertion about a visible UI result?
481
+ → Yes → MUST use: expect(locator) with page selector
482
+ → No → Is this a precondition or unreachable HTTP error?
483
+ → Yes → page.request is acceptable (record reason)
484
+ → No → This is a bug — rewrite with UI selector
485
+ ```
486
+ **Never use page.request for assertions the user can see on screen.** If you wrote page.request.get() for a visible result → rewrite with expect(locator) from the browser snapshot.
487
+
475
488
  **Selector verification (change mode)**:
476
489
 
477
490
  1. Navigate to route with correct auth state
@@ -809,7 +822,7 @@ When a test fails, classify before attempting repair:
809
822
  | **Auth Expired** | Redirected to login mid-test | **Flaky** | Re-run auth.setup → re-run |
810
823
  | **Selector Not Found** | Element not found | **Test Bug** | → Phase 2 Healer |
811
824
  | **Assertion Mismatch** | Wrong content/value | **Ambiguous** | → Phase 2 Healer |
812
- | **Timeout** | waitFor/evaluate timeout | **Flaky** | Retry isolated (1×, not counted in heal attempts) |
825
+ | **Timeout** | waitFor/evaluate timeout | **Flaky** | Retry isolated (1×, not counted in heal attempts). If it passes isolated but fails in suite → **RAFT**. If it consistently times out → check framework: React 19 / Next.js App Router: add `page.waitForLoadState('networkidle')`. Vue/Angular/React 18 / Plain JS / jQuery: use `waitForSelector(targetElement)` instead of timeout tuning. |
813
826
  | **Same test fails in suite, passes isolated** | — | **RAFT** | `test.skip()` in suite, note RAFT in report |
814
827
 
815
828
  - **App Bug** → skip immediately (no healing needed)
@@ -866,6 +879,17 @@ Please decide:
866
879
 
867
880
  Wait for user input before proceeding.
868
881
 
882
+ **Decision tree — follow the path based on user's choice:**
883
+
884
+ | Choice | What to do | After fix, do this |
885
+ |--------|-----------|-------------------|
886
+ | **(a)** Fix the app to match the spec | Fix the app code | Re-run: `npx playwright test tests/playwright/<name>.spec.ts` to verify fix, then re-run `/opsx:e2e <change-name>` to confirm full suite passes |
887
+ | **(b)** Update the spec to match the app | Edit the spec file | Then update the test assertion (→ option c), or regenerate the affected part of the test |
888
+ | **(c)** Update the test assertion | Fix the assertion in `tests/playwright/<name>.spec.ts` | Re-run: `npx playwright test tests/playwright/<name>.spec.ts` to verify, then re-run `/opsx:e2e <change-name>` for full suite |
889
+ | **(d)** Skip with `test.skip()` | Add `test.skip()` to the test | Note in `app-knowledge.md` → `Selector Fixes` table with reason "human escalation — skipped pending resolution" |
890
+
891
+ **Same choice ≥ 2 times without progress**: If user picks the same option twice but the test still doesn't pass, STOP and ask: "This was tried before without success. Are you sure the root cause is still the same, or has something changed?"
892
+
869
893
  After the issue is resolved, re-run:
870
894
  ```
871
895
  /opsx:e2e <change-name>
package/README.md CHANGED
@@ -92,6 +92,22 @@ claude mcp add playwright npx @playwright/mcp@latest
92
92
 
93
93
  > **Note**: After running `openspec-pw init`, manually install Playwright browsers: `npx playwright install --with-deps`
94
94
 
95
+ ## First-Time Setup Checklist
96
+
97
+ Run through these steps in order when using the E2E workflow for the first time:
98
+
99
+ | Step | Command | If it fails |
100
+ |------|---------|-------------|
101
+ | 1. Install CLI | `npm install -g openspec-playwright` | Check Node.js version `node -v` (needs >= 20) |
102
+ | 2. Install OpenSpec | `npm install -g @fission-ai/openspec && openspec init` | `npm cache clean -f && npm install -g @fission-ai/openspec` |
103
+ | 3. Initialize E2E | `openspec-pw init` | Run `openspec-pw doctor` to see what's missing |
104
+ | 4. Install Playwright MCP | `claude mcp add playwright npx @playwright/mcp@latest` | `claude mcp list` to confirm installation |
105
+ | 5. Install browsers | `npx playwright install --with-deps` | macOS may need `xcode-select --install` first |
106
+ | 6. Start dev server | `npm run dev` (in a separate terminal) | Confirm port, set `BASE_URL` if non-standard |
107
+ | 7. Validate env | `npx playwright test tests/playwright/seed.spec.ts` | Check `webServer` in `playwright.config.ts` |
108
+ | 8. Configure auth (if needed) | See "Authentication" below | Debug with `npx playwright test --project=setup` |
109
+ | 9. Run first E2E | `/opsx:e2e <change-name>` | Check `openspec/reports/` for the report |
110
+
95
111
  ## Authentication
96
112
 
97
113
  If your app requires login, set up credentials once, then all tests run authenticated automatically.
package/README.zh-CN.md CHANGED
@@ -10,6 +10,17 @@
10
10
  npm install -g openspec-playwright
11
11
  ```
12
12
 
13
+ ## 前置条件
14
+
15
+ 1. **Node.js >= 20**
16
+ 2. **OpenSpec** 已初始化: `npm install -g @fission-ai/openspec && openspec init`
17
+ 3. **Claude Code** 且项目中有 `.claude/` 目录
18
+
19
+ 安装 Playwright MCP:
20
+ ```bash
21
+ claude mcp add playwright npx @playwright/mcp@latest
22
+ ```
23
+
13
24
  ## 初始化
14
25
 
15
26
  ```bash
@@ -18,6 +29,8 @@ openspec init # 初始化 OpenSpec
18
29
  openspec-pw init # 安装 Playwright E2E 集成
19
30
  ```
20
31
 
32
+ > **注意**:运行 `openspec-pw init` 后,手动安装 Playwright 浏览器:`npx playwright install --with-deps`
33
+
21
34
  ## 支持的 AI 编码助手
22
35
 
23
36
  Claude Code — E2E 工作流由 SKILL.md 驱动,使用 Playwright MCP 工具(`/opsx:e2e <change-name>`)。
@@ -73,17 +86,6 @@ openspec-pw uninstall # 移除项目中的集成
73
86
  └── 11. 报告 → openspec/reports/playwright-e2e-<name>.md
74
87
  ```
75
88
 
76
- ## 前置条件
77
-
78
- 1. **Node.js >= 20**
79
- 2. **OpenSpec** 已初始化: `npm install -g @fission-ai/openspec && openspec init`
80
- 3. **Claude Code** 且项目中有 `.claude/` 目录
81
-
82
- 安装 Playwright MCP:
83
- ```bash
84
- claude mcp add playwright npx @playwright/mcp@latest
85
- ```
86
-
87
89
  ## `openspec-pw init` 做了什么
88
90
 
89
91
  1. 检测项目中的 Claude Code
@@ -91,9 +93,23 @@ claude mcp add playwright npx @playwright/mcp@latest
91
93
  3. 从最新 `@playwright/mcp` 同步 Healer 工具
92
94
  4. 生成 `tests/playwright/seed.spec.ts`、`auth.setup.ts`、`credentials.yaml`、`app-knowledge.md`
93
95
 
94
- > **注意**:运行 `openspec-pw init` 后,手动安装 Playwright 浏览器:`npx playwright install --with-deps`
96
+ ## 首次配置清单
97
+
98
+ 首次使用 E2E 工作流,按顺序执行以下步骤:
99
+
100
+ | 步骤 | 命令 | 失败时快速修复 |
101
+ |------|------|----------------|
102
+ | 1. 安装 CLI | `npm install -g openspec-playwright` | 检查 Node.js 版本 `node -v`(需 >= 20) |
103
+ | 2. 安装 OpenSpec | `npm install -g @fission-ai/openspec && openspec init` | `npm cache clean -f && npm install -g @fission-ai/openspec` |
104
+ | 3. 初始化 E2E | `openspec-pw init` | 运行 `openspec-pw doctor` 查看具体缺失项 |
105
+ | 4. 安装 Playwright MCP | `claude mcp add playwright npx @playwright/mcp@latest` | `claude mcp list` 确认安装成功 |
106
+ | 5. 安装浏览器 | `npx playwright install --with-deps` | macOS 可能需先运行 `xcode-select --install` |
107
+ | 6. 启动开发服务器 | `npm run dev`(在另一个终端) | 确认端口,配置 `BASE_URL` |
108
+ | 7. 验证环境 | `npx playwright test tests/playwright/seed.spec.ts` | 检查 `playwright.config.ts` 中的 `webServer` 配置 |
109
+ | 8. 配置认证(如需要) | 见下方"认证配置" | `npx playwright test --project=setup` 调试 |
110
+ | 9. 运行第一个 E2E | `/opsx:e2e <change-name>` | 查看 `openspec/reports/` 中的报告 |
95
111
 
96
- ## 认证
112
+ ## 认证配置
97
113
 
98
114
  如果你的应用需要登录,配置一次凭证后,所有测试自动以已登录状态运行。
99
115
 
@@ -31,6 +31,8 @@
31
31
 
32
32
  **分阶段执行**:每个阶段不超过 5 个文件,完成后验证,等待用户批准再继续。
33
33
 
34
+ **200 行以上修改必须走 OpenSpec**:代码改动超过 200 行时,禁止直接修改,必须通过 OpenSpec 工作流。
35
+
34
36
  ---
35
37
 
36
38
  ## 四、工具限制
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openspec-playwright",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "OpenSpec + Playwright E2E verification setup tool for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {