openspec-playwright 0.1.62 → 0.1.63
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/LICENSE +21 -0
- package/README.md +4 -3
- package/README.zh-CN.md +4 -3
- package/bin/CLAUDE.md +11 -0
- package/dist/CLAUDE.md +17 -0
- package/dist/commands/doctor.d.ts +4 -1
- package/dist/commands/doctor.js +110 -73
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/editors.js +149 -95
- package/dist/commands/editors.js.map +1 -1
- package/dist/commands/init.js +105 -97
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcpSync.js +46 -31
- package/dist/commands/mcpSync.js.map +1 -1
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +74 -51
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +133 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.js +79 -68
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +33 -26
- package/dist/index.js.map +1 -1
- package/package.json +19 -1
- package/schemas/playwright-e2e/templates/playwright.config.ts +22 -22
- package/templates/CLAUDE.md +15 -0
- package/templates/seed.spec.ts +5 -3
- package/.claude/commands/opsx/e2e-body.md +0 -39
- package/.claude/commands/opsx/e2e.md +0 -47
- package/.claude/skills/openspec-e2e/SKILL.md +0 -464
- package/.github/workflows/release.yml +0 -81
- package/docs/plans/2026-03-26-openspec-playwright-design.md +0 -180
- package/employee-standards.md +0 -44
- package/openspec/schemas/playwright-e2e/schema.yaml +0 -56
- package/openspec/schemas/playwright-e2e/templates/e2e-test.ts +0 -55
- package/openspec/schemas/playwright-e2e/templates/playwright.config.ts +0 -52
- package/openspec/schemas/playwright-e2e/templates/report.md +0 -27
- package/openspec/schemas/playwright-e2e/templates/test-plan.md +0 -24
- package/openspec-playwright-0.1.62.tgz +0 -0
- package/release-notes.md +0 -5
- package/src/commands/doctor.ts +0 -115
- package/src/commands/editors.ts +0 -606
- package/src/commands/init.ts +0 -252
- package/src/commands/mcpSync.ts +0 -160
- package/src/commands/run.ts +0 -172
- package/src/commands/update.ts +0 -192
- package/src/index.ts +0 -47
- package/tests/editors.test.ts +0 -180
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -9
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
# OpenSpec + Playwright E2E Integration Design
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-03-26
|
|
4
|
-
**Updated:** 2026-03-27
|
|
5
|
-
**Status:** Implemented (MVP)
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
Integrate OpenSpec's spec-driven development workflow with Playwright Test Agents' three-agent harness (Planner / Generator / Healer) for automated E2E verification.
|
|
10
|
-
|
|
11
|
-
**Design decision:** Add a new independent command `/openspec-e2e` rather than hooking into `/opsx:verify`. This keeps concerns separated and allows each verification to be run independently.
|
|
12
|
-
|
|
13
|
-
## Architecture
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
openspec-pw (CLI - setup only)
|
|
17
|
-
openspec-pw init → installs Playwright + configures MCP + installs skill
|
|
18
|
-
openspec-pw doctor → checks prerequisites
|
|
19
|
-
|
|
20
|
-
/openspec-e2e (Claude Code skill - runs in Claude)
|
|
21
|
-
│
|
|
22
|
-
├── 1. Read OpenSpec specs from openspec/changes/<name>/specs/
|
|
23
|
-
├── 2. Planner Agent → specs/playwright/test-plan.md
|
|
24
|
-
├── 3. Generator Agent → tests/playwright/<name>.spec.ts
|
|
25
|
-
└── 4. Healer Agent → run tests + auto-heal
|
|
26
|
-
│
|
|
27
|
-
└── Report: openspec/reports/playwright-e2e-<name>-<ts>.md
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Two Verification Layers
|
|
31
|
-
|
|
32
|
-
| Layer | Command | Runs in | What it checks |
|
|
33
|
-
|-------|---------|---------|----------------|
|
|
34
|
-
| Static | `/opsx:verify` | Claude Code (OpenSpec skill) | Implementation matches artifacts |
|
|
35
|
-
| E2E | `/openspec-e2e` | Claude Code (this skill) | App works when running |
|
|
36
|
-
|
|
37
|
-
## Key Design Decisions
|
|
38
|
-
|
|
39
|
-
- **Separate command, not hook**: `/openspec-e2e` is independent from `/opsx:verify`. Users run them separately or together.
|
|
40
|
-
- **CLI as setup only**: The CLI does not run agents. It only installs/configures. Agents run in Claude Code.
|
|
41
|
-
- **Playwright MCP**: Playwright agents use the MCP protocol, configured in `.claude/settings.local.json`.
|
|
42
|
-
- **Seed test**: A `tests/playwright/seed.spec.ts` template guides the Generator agent.
|
|
43
|
-
- **No re-exploration**: Planner uses OpenSpec specs directly as the source of truth, no app exploration needed.
|
|
44
|
-
|
|
45
|
-
## CLI Commands
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm install -g wxhou/openspec-playwright
|
|
49
|
-
|
|
50
|
-
openspec-pw init # Setup: Playwright + MCP + skill + seed
|
|
51
|
-
openspec-pw doctor # Check prerequisites
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## What `openspec-pw init` Does
|
|
55
|
-
|
|
56
|
-
1. `npx playwright init-agents --loop=claude` — installs Playwright agents
|
|
57
|
-
2. Configure Playwright MCP in `.claude/settings.local.json`
|
|
58
|
-
3. Install skill: `.claude/skills/openspec-e2e/SKILL.md`
|
|
59
|
-
4. Install command: `.claude/commands/opsx-e2e.md`
|
|
60
|
-
5. Generate `tests/playwright/seed.spec.ts` template
|
|
61
|
-
|
|
62
|
-
## SKILL.md Format
|
|
63
|
-
|
|
64
|
-
Follows the OpenSpec standard format:
|
|
65
|
-
- YAML frontmatter: `name`, `description`, `license`, `compatibility`, `metadata`
|
|
66
|
-
- Bold step names: `**Step 1: Name**`
|
|
67
|
-
- Output fenced code blocks: `**Output During Implementation**`, `**Output On Completion**`
|
|
68
|
-
- Guardrails section
|
|
69
|
-
- Fluid Workflow Integration section
|
|
70
|
-
|
|
71
|
-
## Directory Structure
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
project/
|
|
75
|
-
├── .claude/
|
|
76
|
-
│ ├── skills/
|
|
77
|
-
│ │ └── openspec-e2e/
|
|
78
|
-
│ │ └── SKILL.md # The /openspec-e2e skill
|
|
79
|
-
│ ├── commands/
|
|
80
|
-
│ │ └── opsx-e2e.md # The /openspec-e2e command
|
|
81
|
-
│ └── settings.local.json # Playwright MCP config
|
|
82
|
-
├── .github/ # Playwright agent definitions
|
|
83
|
-
│ └── ...
|
|
84
|
-
├── openspec/
|
|
85
|
-
│ ├── changes/<name>/
|
|
86
|
-
│ │ ├── specs/
|
|
87
|
-
│ │ │ ├── *.md # OpenSpec propose output
|
|
88
|
-
│ │ │ └── playwright/
|
|
89
|
-
│ │ │ └── test-plan.md # Planner output
|
|
90
|
-
│ │ ├── design.md
|
|
91
|
-
│ │ └── tasks.md
|
|
92
|
-
│ └── reports/
|
|
93
|
-
│ └── playwright-e2e-<name>-<ts>.md # Healer report
|
|
94
|
-
└── tests/playwright/
|
|
95
|
-
├── seed.spec.ts # Seed test template
|
|
96
|
-
└── <name>.spec.ts # Generated tests
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## SKILL.md Sections (OpenSpec Standard)
|
|
100
|
-
|
|
101
|
-
```yaml
|
|
102
|
-
---
|
|
103
|
-
name: openspec-e2e
|
|
104
|
-
description: Run Playwright E2E verification for an OpenSpec change...
|
|
105
|
-
license: MIT
|
|
106
|
-
compatibility: Requires openspec CLI and Playwright Test Agents...
|
|
107
|
-
metadata:
|
|
108
|
-
author: openspec-playwright
|
|
109
|
-
version: "0.1.0"
|
|
110
|
-
generatedBy: "openspec-playwright"
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
Run Playwright E2E verification for an OpenSpec change...
|
|
114
|
-
|
|
115
|
-
## Step 1: Identify the Change
|
|
116
|
-
...
|
|
117
|
-
|
|
118
|
-
## Step 2: Verify Prerequisites
|
|
119
|
-
...
|
|
120
|
-
|
|
121
|
-
**Output During Implementation**
|
|
122
|
-
```markdown
|
|
123
|
-
## E2E Verification: <name>
|
|
124
|
-
Status: 🔄 In Progress
|
|
125
|
-
```
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
**Output On Completion**
|
|
129
|
-
```markdown
|
|
130
|
-
## E2E Verify Report: <name>
|
|
131
|
-
| Check | Status |
|
|
132
|
-
|-------|--------|
|
|
133
|
-
...
|
|
134
|
-
```
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Guardrails**
|
|
138
|
-
- Always read specs from `openspec/changes/<name>/specs/` as source of truth
|
|
139
|
-
- Do not generate tests that contradict the specs
|
|
140
|
-
- Cap auto-heal attempts at 3
|
|
141
|
-
...
|
|
142
|
-
|
|
143
|
-
**Fluid Workflow Integration**
|
|
144
|
-
- Before: /opsx:propose → /opsx:apply
|
|
145
|
-
- This skill: /openspec-e2e
|
|
146
|
-
- After: /opsx:archive
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Error Handling
|
|
150
|
-
|
|
151
|
-
| Scenario | Action |
|
|
152
|
-
|----------|--------|
|
|
153
|
-
| No specs found | Prompt to run `/opsx:propose` first |
|
|
154
|
-
| Prerequisites missing | Prompt to run `openspec-pw init` |
|
|
155
|
-
| Dev server not running | Prompt to start before proceeding |
|
|
156
|
-
| Planner fails | Log error, mark FAILED |
|
|
157
|
-
| Generator fails | Log error, mark FAILED |
|
|
158
|
-
| Healer guardrails trigger | Report failures, mark PARTIAL |
|
|
159
|
-
|
|
160
|
-
## Project Structure
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
openspec-playwright/
|
|
164
|
-
├── src/
|
|
165
|
-
│ ├── index.ts # CLI entry
|
|
166
|
-
│ └── commands/
|
|
167
|
-
│ ├── init.ts # openspec-pw init
|
|
168
|
-
│ └── doctor.ts # openspec-pw doctor
|
|
169
|
-
├── .claude/
|
|
170
|
-
│ ├── skills/
|
|
171
|
-
│ │ └── openspec-e2e/
|
|
172
|
-
│ │ └── SKILL.md # The Claude Code skill
|
|
173
|
-
│ └── commands/
|
|
174
|
-
│ └── opsx-e2e.md # The command file
|
|
175
|
-
├── templates/
|
|
176
|
-
│ └── seed.spec.ts # Playwright seed test template
|
|
177
|
-
├── README.md
|
|
178
|
-
├── package.json
|
|
179
|
-
└── tsconfig.json
|
|
180
|
-
```
|
package/employee-standards.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Claude Code Employee-Grade Configuration
|
|
2
|
-
|
|
3
|
-
> 员工级行为规范,适用于 OpenSpec 项目。
|
|
4
|
-
> 遵循 OpenSpec 规范驱动开发流程(详见 /openspec/)。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 一、代码质量
|
|
9
|
-
|
|
10
|
-
**验证后才能报告成功**。运行项目的 linter 和 type checker:查看 `package.json`/`pyproject.toml`/`go.mod`/`Cargo.toml` 中的 scripts,使用对应的 `lint`/`typecheck` 命令。不存在时,明确告知用户,不得假装成功。
|
|
11
|
-
|
|
12
|
-
**拒绝'够用就行'**。架构缺陷、状态重复、模式不一致——说出来并修复。高级工程师在 code review 中会拒绝什么?全部修掉。
|
|
13
|
-
|
|
14
|
-
**安全防护**:防范 XSS、SQL 注入、命令注入(OWASP Top 10)。
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## 二、上下文管理
|
|
19
|
-
|
|
20
|
-
**文件读取完整**:超过 500 行的文件,不要假设单次读取覆盖了完整文件——根据需要分次读取相关段落,或编辑前重新读取完整文件。超过 10 条消息后,编辑任何文件前强制重新读取。
|
|
21
|
-
|
|
22
|
-
**重构前清死代码**:未使用的 import/export/prop/console.log 先删掉,单独提交,再做重构。
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## 三,大规模任务
|
|
27
|
-
|
|
28
|
-
**子 Agent 并行化**:任务涉及超过 5 个独立文件时,启动并行子 agent(每个 5-8 个文件),每个拥有独立 token budget。
|
|
29
|
-
|
|
30
|
-
**分阶段执行**:每个阶段不超过 5 个文件,完成后验证,等待用户批准再继续。
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 四、工具限制
|
|
35
|
-
|
|
36
|
-
**搜索维度完整**:重命名函数/类型/变量时,必须覆盖:直接调用、类型级引用、字符串字面量、`require()`/`import`、barrel file、测试 mock。不得假设一次 grep 覆盖所有情况。
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## 五、编辑安全
|
|
41
|
-
|
|
42
|
-
**验证后才算完成**:编辑后再次读取确认变更正确应用。同一文件连续编辑不超过 3 次,中间必须验证。变更完成后,明确告知用户可能遗漏的区域(动态引用、测试 mock 等),提示人工复查。
|
|
43
|
-
|
|
44
|
-
**不主动推送**:除非用户明确要求,否则不推送代码。
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
name: playwright-e2e
|
|
2
|
-
version: 1
|
|
3
|
-
description: Playwright E2E verification for an OpenSpec change
|
|
4
|
-
|
|
5
|
-
artifacts:
|
|
6
|
-
- id: test-plan
|
|
7
|
-
generates: specs/playwright/test-plan.md
|
|
8
|
-
description: Test plan derived from change specs
|
|
9
|
-
template: test-plan.md
|
|
10
|
-
instruction: |
|
|
11
|
-
Generate a test plan from the change specs. Each functional requirement becomes
|
|
12
|
-
one or more test cases.
|
|
13
|
-
|
|
14
|
-
For each test case, specify:
|
|
15
|
-
- **Test name** (kebab-case): what it verifies
|
|
16
|
-
- **Route/Page**: which URL or UI component it targets
|
|
17
|
-
- **Prerequisites**: auth role needed (user/admin/guest/none)
|
|
18
|
-
- **Happy path**: main user flow to verify
|
|
19
|
-
- **Error paths**: key error conditions to verify
|
|
20
|
-
|
|
21
|
-
Mark tests with role tags: `@role(user)`, `@role(admin)`, `@role(guest)`, `@role(none)`.
|
|
22
|
-
Mark auth requirement: `@auth(required)` or `@auth(none)`.
|
|
23
|
-
|
|
24
|
-
- id: e2e-test
|
|
25
|
-
generates: tests/playwright/<change>.spec.ts
|
|
26
|
-
description: Playwright E2E test suite
|
|
27
|
-
template: e2e-test.ts
|
|
28
|
-
instruction: |
|
|
29
|
-
Generate Playwright tests from the test-plan.
|
|
30
|
-
|
|
31
|
-
Rules:
|
|
32
|
-
- Follow the page object pattern from seed.spec.ts
|
|
33
|
-
- Prefer `data-testid` selectors, fall back to semantic selectors
|
|
34
|
-
- Each test maps to one test case from the test-plan
|
|
35
|
-
- Use `@project(user)` / `@project(admin)` for role-specific tests
|
|
36
|
-
- Cover happy path AND key error paths
|
|
37
|
-
- Name tests descriptively: `test('shows error on invalid input')`
|
|
38
|
-
|
|
39
|
-
- id: playwright-config
|
|
40
|
-
generates: playwright.config.ts
|
|
41
|
-
description: Playwright config with webServer and auth projects
|
|
42
|
-
template: playwright.config.ts
|
|
43
|
-
instruction: |
|
|
44
|
-
Configure Playwright for E2E testing.
|
|
45
|
-
|
|
46
|
-
- Set webServer command and url from BASE_URL
|
|
47
|
-
- Set baseURL for all tests
|
|
48
|
-
- Add auth setup project if credentials are configured
|
|
49
|
-
- Preserve any existing config fields (browsers, retries, etc.)
|
|
50
|
-
- Do NOT overwrite existing projects unless they conflict
|
|
51
|
-
|
|
52
|
-
apply:
|
|
53
|
-
requires: [test-plan, e2e-test]
|
|
54
|
-
instruction: |
|
|
55
|
-
Run tests via: openspec-pw run <change-name>
|
|
56
|
-
Analyze results and generate report at openspec/reports/playwright-e2e-<change>-<timestamp>.md
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { test, expect, Page } from '@playwright/test';
|
|
2
|
-
|
|
3
|
-
// ──────────────────────────────────────────────
|
|
4
|
-
// Test plan: <change-name>
|
|
5
|
-
// Generated from: openspec/changes/<change-name>/specs/playwright/test-plan.md
|
|
6
|
-
// ──────────────────────────────────────────────
|
|
7
|
-
|
|
8
|
-
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Page Object Pattern - add selectors for your app's pages
|
|
12
|
-
*/
|
|
13
|
-
class AppPage {
|
|
14
|
-
constructor(private page: Page) {}
|
|
15
|
-
|
|
16
|
-
async goto(path: string = '/') {
|
|
17
|
-
await this.page.goto(`${BASE_URL}${path}`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async getByTestId(id: string) {
|
|
21
|
-
return this.page.locator(`[data-testid="${id}"]`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async waitForToast(message?: string) {
|
|
25
|
-
if (message) {
|
|
26
|
-
await this.page.getByText(message, { state: 'visible' }).waitFor();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function createPage(page: Page): AppPage {
|
|
32
|
-
return new AppPage(page);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ──────────────────────────────────────────────
|
|
36
|
-
// Tests - generated from test-plan.md
|
|
37
|
-
// Customize selectors and assertions to match your app
|
|
38
|
-
// ──────────────────────────────────────────────
|
|
39
|
-
|
|
40
|
-
test.describe('<change-name>: E2E verification', () => {
|
|
41
|
-
|
|
42
|
-
test.beforeEach(async ({ page }) => {
|
|
43
|
-
const app = createPage(page);
|
|
44
|
-
await app.goto('/');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// TODO: Add test cases from specs/playwright/test-plan.md
|
|
48
|
-
// Example:
|
|
49
|
-
// test('shows expected content on page load', async ({ page }) => {
|
|
50
|
-
// const app = createPage(page);
|
|
51
|
-
// await app.goto('/');
|
|
52
|
-
// await expect(app.getByTestId('main-heading')).toBeVisible();
|
|
53
|
-
// });
|
|
54
|
-
|
|
55
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
-
import { readFileSync, existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
|
|
5
|
-
// ─── BASE_URL: prefer env, then seed.spec.ts, then default ───
|
|
6
|
-
const seedSpec = join(__dirname, '../tests/playwright/seed.spec.ts');
|
|
7
|
-
let baseUrl = process.env.BASE_URL || 'http://localhost:3000';
|
|
8
|
-
if (existsSync(seedSpec)) {
|
|
9
|
-
const content = readFileSync(seedSpec, 'utf-8');
|
|
10
|
-
const m = content.match(/BASE_URL\s*=\s*process\.env\.BASE_URL\s*\|\|\s*['"]([^'"]+)['"]/);
|
|
11
|
-
if (m) baseUrl = m[1];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// ─── Dev command: detect from package.json scripts ───
|
|
15
|
-
const pkgPath = join(__dirname, '../package.json');
|
|
16
|
-
let devCmd = 'npm run dev';
|
|
17
|
-
if (existsSync(pkgPath)) {
|
|
18
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
19
|
-
const scripts = pkg.scripts ?? {};
|
|
20
|
-
// Prefer in order: dev, start, serve, preview
|
|
21
|
-
devCmd = scripts.dev ?? scripts.start ?? scripts.serve ?? scripts.preview ?? devCmd;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default defineConfig({
|
|
25
|
-
testDir: '../tests/playwright',
|
|
26
|
-
// Keep test artifacts inside tests/playwright/ instead of project root
|
|
27
|
-
outputDir: '../tests/playwright/test-results',
|
|
28
|
-
fullyParallel: true,
|
|
29
|
-
forbidOnly: !!process.env.CI,
|
|
30
|
-
retries: process.env.CI ? 2 : 0,
|
|
31
|
-
workers: process.env.CI ? 1 : undefined,
|
|
32
|
-
reporter: 'list',
|
|
33
|
-
|
|
34
|
-
use: {
|
|
35
|
-
baseURL: baseUrl,
|
|
36
|
-
trace: 'on-first-retry',
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
// Dev server lifecycle - Playwright starts/stops automatically
|
|
40
|
-
webServer: {
|
|
41
|
-
command: devCmd,
|
|
42
|
-
url: baseUrl,
|
|
43
|
-
timeout: 120000,
|
|
44
|
-
reuseExistingServer: true,
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
// Setup project for authentication (configured by openspec-pw run)
|
|
48
|
-
projects: [
|
|
49
|
-
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
|
|
50
|
-
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
51
|
-
],
|
|
52
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# E2E Verify Report: <change-name>
|
|
2
|
-
|
|
3
|
-
**Change**: `<change-name>`
|
|
4
|
-
**Generated**: `<timestamp>`
|
|
5
|
-
**Auth**: `<required|none>`
|
|
6
|
-
|
|
7
|
-
## Summary
|
|
8
|
-
|
|
9
|
-
| Check | Status |
|
|
10
|
-
|-------|--------|
|
|
11
|
-
| Tests Run | <N> |
|
|
12
|
-
| Passed | <X> |
|
|
13
|
-
| Failed | <Y> |
|
|
14
|
-
| Auto-heals | <Z> |
|
|
15
|
-
| Final Status | <PASS|FAIL> |
|
|
16
|
-
|
|
17
|
-
## Test Results
|
|
18
|
-
|
|
19
|
-
<!-- List each test with pass/fail status -->
|
|
20
|
-
|
|
21
|
-
## Auto-Heal Log
|
|
22
|
-
|
|
23
|
-
<!-- If heals were performed, document each attempt -->
|
|
24
|
-
|
|
25
|
-
## Recommendations
|
|
26
|
-
|
|
27
|
-
<!-- For failed tests, specific file:line references and fixes -->
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Test Plan: <change-name>
|
|
2
|
-
|
|
3
|
-
Generated from: `openspec/changes/<change-name>/specs/`
|
|
4
|
-
|
|
5
|
-
## Auth Requirements
|
|
6
|
-
|
|
7
|
-
<!-- Mark auth requirements based on specs analysis: -->
|
|
8
|
-
- Auth required: **yes / no**
|
|
9
|
-
- Roles needed: none / user / admin / user+admin
|
|
10
|
-
|
|
11
|
-
## Test Cases
|
|
12
|
-
|
|
13
|
-
### <test-name>
|
|
14
|
-
|
|
15
|
-
- **Route**: `/<page>`
|
|
16
|
-
- **Role**: `@role(<role>)`
|
|
17
|
-
- **Auth**: `@auth(required|none)`
|
|
18
|
-
|
|
19
|
-
**Happy path:**
|
|
20
|
-
- Step 1: ...
|
|
21
|
-
- Step 2: ...
|
|
22
|
-
|
|
23
|
-
**Error paths:**
|
|
24
|
-
- ...
|
|
Binary file
|
package/release-notes.md
DELETED
package/src/commands/doctor.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { homedir } from 'os';
|
|
4
|
-
import { execSync } from 'child_process';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
|
|
7
|
-
export async function doctor() {
|
|
8
|
-
console.log(chalk.blue('\n🔍 OpenSpec + Playwright E2E Prerequisites Check\n'));
|
|
9
|
-
|
|
10
|
-
const projectRoot = process.cwd();
|
|
11
|
-
let allOk = true;
|
|
12
|
-
|
|
13
|
-
// Node.js
|
|
14
|
-
console.log(chalk.blue('─── Node.js ───'));
|
|
15
|
-
try {
|
|
16
|
-
const node = execSync('node --version', { encoding: 'utf-8' }).trim();
|
|
17
|
-
console.log(chalk.green(` ✓ Node.js ${node}`));
|
|
18
|
-
} catch {
|
|
19
|
-
console.log(chalk.red(' ✗ Node.js not found'));
|
|
20
|
-
allOk = false;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// npm
|
|
24
|
-
console.log(chalk.blue('\n─── npm ───'));
|
|
25
|
-
try {
|
|
26
|
-
const npm = execSync('npm --version', { encoding: 'utf-8' }).trim();
|
|
27
|
-
console.log(chalk.green(` ✓ npm ${npm}`));
|
|
28
|
-
} catch {
|
|
29
|
-
console.log(chalk.red(' ✗ npm not found'));
|
|
30
|
-
allOk = false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// OpenSpec
|
|
34
|
-
console.log(chalk.blue('\n─── OpenSpec ───'));
|
|
35
|
-
const hasOpenSpec = existsSync(join(projectRoot, 'openspec'));
|
|
36
|
-
if (hasOpenSpec) {
|
|
37
|
-
console.log(chalk.green(' ✓ OpenSpec initialized'));
|
|
38
|
-
} else {
|
|
39
|
-
console.log(chalk.red(' ✗ OpenSpec not initialized'));
|
|
40
|
-
console.log(chalk.gray(' Run: openspec init'));
|
|
41
|
-
allOk = false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Playwright browsers
|
|
45
|
-
console.log(chalk.blue('\n─── Playwright Browsers ───'));
|
|
46
|
-
try {
|
|
47
|
-
const pw = execSync('npx playwright --version', { encoding: 'utf-8' }).trim();
|
|
48
|
-
console.log(chalk.green(` ✓ Playwright ${pw}`));
|
|
49
|
-
} catch {
|
|
50
|
-
console.log(chalk.red(' ✗ Playwright browsers not installed'));
|
|
51
|
-
console.log(chalk.gray(' Run: npx playwright install --with-deps'));
|
|
52
|
-
allOk = false;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Playwright MCP (global)
|
|
56
|
-
console.log(chalk.blue('\n─── Playwright MCP ───'));
|
|
57
|
-
const homeDir = homedir();
|
|
58
|
-
const claudeJsonPath = join(homeDir, '.claude.json');
|
|
59
|
-
let mcpInstalled = false;
|
|
60
|
-
if (existsSync(claudeJsonPath)) {
|
|
61
|
-
try {
|
|
62
|
-
const claudeJson = JSON.parse(readFileSync(claudeJsonPath, 'utf-8'));
|
|
63
|
-
const globalMcp = claudeJson?.mcpServers ?? {};
|
|
64
|
-
const localMcp = claudeJson?.projects?.[projectRoot]?.mcpServers ?? {};
|
|
65
|
-
if (globalMcp['playwright'] || localMcp['playwright']) {
|
|
66
|
-
mcpInstalled = true;
|
|
67
|
-
}
|
|
68
|
-
} catch {
|
|
69
|
-
// ignore
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (mcpInstalled) {
|
|
73
|
-
console.log(chalk.green(' ✓ Playwright MCP installed globally'));
|
|
74
|
-
} else {
|
|
75
|
-
console.log(chalk.red(' ✗ Playwright MCP not configured'));
|
|
76
|
-
console.log(chalk.gray(' Run: openspec-pw init'));
|
|
77
|
-
allOk = false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Skill
|
|
81
|
-
console.log(chalk.blue('\n─── Claude Code Skill ───'));
|
|
82
|
-
const hasSkill = existsSync(
|
|
83
|
-
join(projectRoot, '.claude', 'skills', 'openspec-e2e', 'SKILL.md')
|
|
84
|
-
);
|
|
85
|
-
if (hasSkill) {
|
|
86
|
-
console.log(chalk.green(' ✓ /openspec-e2e skill installed'));
|
|
87
|
-
} else {
|
|
88
|
-
console.log(chalk.red(' ✗ Skill not installed'));
|
|
89
|
-
console.log(chalk.gray(' Run: openspec-pw init'));
|
|
90
|
-
allOk = false;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Seed test
|
|
94
|
-
console.log(chalk.blue('\n─── Seed Test ───'));
|
|
95
|
-
const hasSeed = existsSync(
|
|
96
|
-
join(projectRoot, 'tests', 'playwright', 'seed.spec.ts')
|
|
97
|
-
);
|
|
98
|
-
if (hasSeed) {
|
|
99
|
-
console.log(chalk.green(' ✓ seed.spec.ts found'));
|
|
100
|
-
} else {
|
|
101
|
-
console.log(chalk.yellow(' ⚠ seed.spec.ts not found (optional)'));
|
|
102
|
-
console.log(chalk.gray(' Run: openspec-pw init'));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Summary
|
|
106
|
-
console.log(chalk.blue('\n─── Summary ───'));
|
|
107
|
-
if (allOk) {
|
|
108
|
-
console.log(chalk.green(' ✅ All prerequisites met!\n'));
|
|
109
|
-
console.log(chalk.gray(' Run: /opsx:e2e <change-name> in Claude Code\n'));
|
|
110
|
-
} else {
|
|
111
|
-
console.log(chalk.red(' ❌ Some prerequisites are missing\n'));
|
|
112
|
-
console.log(chalk.gray(' Run: openspec-pw init to fix\n'));
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
}
|