test
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese/test - Web E2E Testing Agent
/test - Web E2E测试Agent
Model: haiku (straightforward test execution)
模型: haiku(用于直接执行测试)
Command Flags
命令行参数
| Flag | Short | Description |
|---|---|---|
| | Show available commands and options |
| | Show workflow skills version |
| CI mode: headless testing with scripts | |
| Delete test scripts after run (use with --ci) |
| 参数 | 简写 | 说明 |
|---|---|---|
| | 查看可用命令和选项 |
| | 查看工作流技能版本 |
| CI模式:使用脚本执行无头测试 | |
| 测试运行后删除测试脚本(需搭配--ci使用) |
Flag Handling
参数处理规则
On or :
-h--help/test - Web E2E Testing Agent
Usage:
/test {ID} Interactive mode (Playwright MCP)
/test --ci {ID} CI mode, keeps test scripts
/test --ci --cleanup {ID} CI mode, deletes scripts after
/test --ci {ID} "instructions" CI mode with custom instructions
/test -h, --help Show this help message
/test -v, --version Show version
Arguments:
{ID} Task ID (number) or task filename (e.g., 001-auth-jwt)
Options:
--ci Headless mode using Playwright test runner
--cleanup Delete test scripts after completion (with --ci)
Examples:
/test 1 # Interactive visual testing
/test 001-auth-jwt # Using task filename
/test --ci 1 # CI mode, scripts kept
/test --ci --cleanup 1 # CI mode, scripts deleted
Next: /document {ID}On or :
Display:
-v--versionWorkflow Skills v1.4.1
https://github.com/eljun/claude-skills使用 或 时输出:
-h--help/test - Web E2E Testing Agent
Usage:
/test {ID} Interactive mode (Playwright MCP)
/test --ci {ID} CI mode, keeps test scripts
/test --ci --cleanup {ID} CI mode, deletes scripts after
/test --ci {ID} "instructions" CI mode with custom instructions
/test -h, --help Show this help message
/test -v, --version Show version
Arguments:
{ID} Task ID (number) or task filename (e.g., 001-auth-jwt)
Options:
--ci Headless mode using Playwright test runner
--cleanup Delete test scripts after completion (with --ci)
Examples:
/test 1 # Interactive visual testing
/test 001-auth-jwt # Using task filename
/test --ci 1 # CI mode, scripts kept
/test --ci --cleanup 1 # CI mode, scripts deleted
Next: /document {ID}使用 或 时输出:
-v--versionWorkflow Skills v1.4.1
https://github.com/eljun/claude-skillsPrerequisites
前置要求
Playwright MCP Setup (One-Time)
Playwright MCP 配置(仅需一次)
Interactive mode requires Playwright MCP. No npm install needed - Claude Code handles it automatically.
Setup Steps:
-
Createin your project root (not in
.mcp.jsonor subdirectories):.claude/json{ "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } -
Restart Claude Code (required after adding/modifying)
.mcp.json -
Verify MCP is active - you should seetools available
mcp__playwright__browser_*
How it works:
- Claude Code reads on startup
.mcp.json - The command auto-downloads the package (no manual install)
npx - MCP server starts automatically and exposes browser control tools
- Tools like ,
mcp__playwright__browser_navigatebecome availablemcp__playwright__browser_click
交互模式需要使用Playwright MCP,无需手动执行npm install,Claude Code会自动处理依赖。
配置步骤:
-
在项目根目录创建文件(不要放在
.mcp.json或子目录下):.claude/json{ "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } -
重启Claude Code(添加/修改后必须执行此操作)
.mcp.json -
验证MCP是否正常激活:你应该能看到可用工具中包含相关的工具
mcp__playwright__browser_*
工作原理:
- Claude Code启动时会读取配置
.mcp.json - 命令会自动下载对应包(无需手动安装)
npx - MCP服务会自动启动并暴露浏览器控制工具
- 、
mcp__playwright__browser_navigate等工具将变为可用状态mcp__playwright__browser_click
Interactive Mode (Default)
交互模式(默认模式)
Playwright MCP is REQUIRED for interactive mode. Before running tests, verify that is available as a tool. If Playwright MCP tools are not available:
mcp__playwright__browser_navigate- STOP - Do not proceed with testing
- Notify the user with this message:
Playwright MCP is not configured. Interactive testing requires the MCP server. Add this to your project's .mcp.json: { "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } Then restart Claude Code and re-run /test. Alternative: Use CI mode which doesn't require MCP: /test --ci {task-name} - Do NOT fall back to curl commands or source code inspection as a substitute for browser testing. This produces misleading test reports.
交互模式必须使用Playwright MCP,运行测试前请确认工具已可用。如果Playwright MCP工具不可用:
mcp__playwright__browser_navigate- 立即停止,不要继续执行测试
- 向用户发送以下提示信息:
Playwright MCP未配置,交互模式测试需要MCP服务支持。 请将以下配置添加到项目的.mcp.json文件中: { "mcpServers": { "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } } 配置完成后重启Claude Code并重新执行/test命令。 替代方案:使用无需MCP的CI模式: /test --ci {task-name} - 不要回退到使用curl命令或源码检查替代浏览器测试,这种方式会生成不准确的测试报告。
CI Mode (--ci
flag)
--ciCI模式(--ci
参数)
--ciPlaywright MCP is NOT required for CI mode. CI mode uses the standard Playwright test runner.
Requirements for CI mode:
bash
undefinedCI模式不需要使用Playwright MCP,CI模式使用标准的Playwright测试运行器。
CI模式依赖要求:
bash
undefinedInstall Playwright as dev dependency (if not already)
安装Playwright作为开发依赖(如果还未安装)
npm install -D @playwright/test
npm install -D @playwright/test
Install browsers (first time only)
安装浏览器(仅首次使用时需要)
npx playwright install
CI mode generates test scripts and runs them with `npx playwright test` - no MCP server needed.
---npx playwright install
CI模式会生成测试脚本并通过`npx playwright test`运行,无需MCP服务。
---CRITICAL: Mode-Specific Rules
重要说明:不同模式的专属规则
Interactive Mode (Default) - What NOT To Do
交互模式(默认)禁止操作
DO NOT generate test script files. Interactive mode uses Playwright MCP tools directly in the conversation - NOT by creating external test files.
Prohibited in Interactive Mode:
- ❌ Creating ,
.ts, or.jstest files (e.g.,.spec,test-app.ts)e2e-test.js - ❌ Creating ,
TEST_REPORT.mdin project rootTEST_SUMMARY.txt - ❌ Creating or similar folders in project root
test-screenshots/ - ❌ Running or similar CLI commands
npx playwright test - ❌ Spawning subagents to run headless tests in background
- ❌ Using "CI/CD style" or "headless mode" testing workflows
Required in Interactive Mode:
- ✅ Use tools directly in conversation
mcp__playwright__browser_* - ✅ Write final report ONLY to
docs/testing/{task-name}.md - ✅ Interactive browser testing where you can see each step
- ✅ Take screenshots using (stored in Playwright's temp directory, not project)
mcp__playwright__browser_take_screenshot
不要生成测试脚本文件,交互模式直接在对话中使用Playwright MCP工具执行测试,不需要创建外部测试文件。
交互模式下禁止操作:
- ❌ 创建、
.ts或.js测试文件(例如.spec、test-app.ts)e2e-test.js - ❌ 在项目根目录创建、
TEST_REPORT.md文件TEST_SUMMARY.txt - ❌ 在项目根目录创建或类似文件夹
test-screenshots/ - ❌ 执行或类似CLI命令
npx playwright test - ❌ 启动子代理在后台执行无头测试
- ❌ 使用「CI/CD风格」或「无头模式」测试工作流
交互模式下必须执行的操作:
- ✅ 直接在对话中使用工具
mcp__playwright__browser_* - ✅ 仅将最终报告写入路径
docs/testing/{task-name}.md - ✅ 执行可查看每一步操作的交互式浏览器测试
- ✅ 使用截图(存储在Playwright临时目录,不会存入项目)
mcp__playwright__browser_take_screenshot
CI Mode (--ci
flag) - Allowed Actions
--ciCI模式(--ci
参数)允许操作
--ciCI mode IS allowed to generate test scripts, but must follow these rules:
Allowed in CI Mode:
- ✅ Create test scripts in (NOT project root)
tests/e2e/{task-name}/ - ✅ Run for headless execution
npx playwright test - ✅ Spawn subagents for parallel test execution
- ✅ Generate temporary screenshots during testing
Required in CI Mode:
- ✅ Write final report to
docs/testing/{task-name}.md - ✅ MUST cleanup all temporary artifacts after tests (see Cleanup section)
- ✅ Ask user if they want to keep test scripts for CI pipeline
- ✅ Never leave artifacts in project root
CI模式允许生成测试脚本,但必须遵循以下规则:
CI模式下允许操作:
- ✅ 在路径下创建测试脚本(不要放在项目根目录)
tests/e2e/{task-name}/ - ✅ 执行进行无头测试
npx playwright test - ✅ 启动子代理执行并行测试
- ✅ 测试过程中生成临时截图
CI模式下必须执行的操作:
- ✅ 将最终报告写入路径
docs/testing/{task-name}.md - ✅ 必须清理测试完成后的所有临时产物(见清理章节)
- ✅ 询问用户是否需要保留测试脚本用于CI流水线
- ✅ 绝对不要在项目根目录遗留任何测试产物
When to Use
适用场景
Invoke when:
/test {ID}- Task is in "Testing" status in TASKS.md
- Implementation is complete from
/implement - Ready to verify the feature works
Example: or
/test 1/test 001-dashboard-redesign满足以下条件时可调用:
/test {ID}- TASKS.md中任务状态为「Testing」
- 命令已完成功能实现
/implement - 已准备好验证功能是否正常运行
示例: 或
/test 1/test 001-dashboard-redesignTask ID Resolution
任务ID解析规则
The can be:
{ID}- Numeric ID: ,
1,2→ Looks up in TASKS.md, finds matching task document3 - Padded ID: ,
001→ Same as numeric002 - Full filename: → Direct file reference
001-dashboard-redesign
{ID}- 数字ID: 、
1、2→ 将在TASKS.md中查找匹配的任务文档3 - 补零ID: 、
001→ 和数字ID逻辑一致002 - 完整文件名: → 直接引用对应文件
001-dashboard-redesign
Syntax
语法规则
/test {ID} → Interactive mode (default)
/test --ci {ID} → CI mode, keeps scripts (default)
/test --ci --cleanup {ID} → CI mode, deletes scripts after test
/test --ci {ID} "instructions" → CI mode with additional test instructionsExamples:
- - Interactive visual testing
/test 1 - - Headless CI testing, scripts kept for regression
/test --ci 2 - - CI testing, scripts deleted (minor changes)
/test --ci --cleanup 3 - - CI mode with specific scenarios
/test --ci 4 "test empty cart and full cart"
/test {ID} → 交互模式(默认)
/test --ci {ID} → CI模式,默认保留脚本
/test --ci --cleanup {ID} → CI模式,测试完成后删除脚本
/test --ci {ID} "instructions" → CI模式,附带自定义测试指令示例:
- - 交互式可视化测试
/test 1 - - 无头CI测试,保留脚本用于回归测试
/test --ci 2 - - CI测试,测试完成后删除脚本(适用于小改动)
/test --ci --cleanup 3 - - CI模式,指定测试场景
/test --ci 4 "test empty cart and full cart"
Flag Reference
参数参考
| Flag | Behavior | Use When |
|---|---|---|
| (none) | Interactive mode with Playwright MCP | Debugging, demos, visual verification |
| Headless mode, keeps scripts | Core features, regression protection |
| Headless mode, deletes scripts | Minor changes, one-time verification |
| 参数 | 行为 | 适用场景 |
|---|---|---|
| 无参数 | 使用Playwright MCP的交互模式 | 调试、演示、可视化验证 |
| 无头模式,保留脚本 | 核心功能、回归防护 |
| 无头模式,删除脚本 | 小改动、一次性验证 |
CRITICAL: Mode Detection (Execute FIRST)
重要说明:模式检测(必须优先执行)
You MUST execute this decision tree BEFORE doing anything else:
┌─────────────────────────────────────────────────────────────┐
│ STEP 1: Parse the command for --ci flag │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
│ │
▼ ▼
Has --ci flag? No --ci flag?
│ │
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────────────────┐
│ MODE = CI │ │ STEP 2: Check for Playwright MCP │
│ Proceed to CI │ │ Is mcp__playwright__browser_* │
│ workflow │ │ available as a tool? │
└─────────────────────┘ └─────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
Available? NOT Available?
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────────────┐
│ MODE = Interactive │ │ **STOP IMMEDIATELY** │
│ Proceed to │ │ │
│ Interactive workflow│ │ Display this message: │
└─────────────────────┘ │ "Playwright MCP is not │
│ configured. See prereqs."│
│ │
│ DO NOT: │
│ - Fall back to CI mode │
│ - Use curl/source code │
│ - Proceed with testing │
└──────────────────────────┘ABSOLUTE RULES:
- No --ci flag + No Playwright MCP = STOP. Do not proceed. Do not fall back.
- No --ci flag + Playwright MCP available = Interactive mode ONLY. Never create test scripts.
- --ci flag present = CI mode. Playwright MCP not required.
How to check for Playwright MCP:
Look for tools starting with in your available tools. If you see tools like , , etc., Playwright MCP is available.
mcp__playwright__browser_mcp__playwright__browser_navigatemcp__playwright__browser_click执行任何其他操作前,必须先按照以下决策树判断运行模式:
┌─────────────────────────────────────────────────────────────┐
│ 步骤1:解析命令是否包含--ci参数 │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
│ │
▼ ▼
包含--ci参数? 不包含--ci参数?
│ │
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────────────────┐
│ 模式 = CI │ │ 步骤2:检查Playwright MCP是否可用 │
│ 进入CI工作流 │ │ 可用工具中是否存在mcp__playwright__browser_*相关工具? |
└─────────────────────┘ └─────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
可用? 不可用?
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────────────┐
│ 模式 = 交互模式 │ │ **立即停止** │
│ 进入交互模式工作流 │ │ │
└─────────────────────┘ │ 显示以下提示: │
│ "Playwright MCP未配置,请查看前置要求"│
│ │
│ 禁止以下操作: │
│ - 回退到CI模式 │
│ - 使用curl/检查源码替代测试 |
│ - 继续执行测试 │
└──────────────────────────┘绝对规则:
- 无--ci参数 + 无Playwright MCP = 立即停止,不要继续操作,不要回退到其他模式。
- 无--ci参数 + Playwright MCP可用 = 仅使用交互模式,绝对不要创建测试脚本。
- 存在--ci参数 = CI模式,不需要Playwright MCP。
检查Playwright MCP是否可用的方法:
查看可用工具中是否有以开头的工具,如果能看到、等工具,说明Playwright MCP已可用。
mcp__playwright__browser_mcp__playwright__browser_navigatemcp__playwright__browser_clickWorkflow
工作流
IMPORTANT: Always execute "Mode Detection" section FIRST before following any workflow below.
重要提示:执行以下任何工作流前,必须先执行「模式检测」章节的步骤。
Interactive Mode (Default) — REQUIRES Playwright MCP
交互模式(默认)- 必须使用Playwright MCP
Entry condition: No flag AND Playwright MCP tools are available.
--ciIf Playwright MCP is NOT available: STOP. Do not use this workflow. Do not fall back to CI mode. Notify user to configure Playwright MCP.
/test {task-name}
↓
0. [ALREADY DONE] Mode Detection confirmed:
- No --ci flag
- Playwright MCP IS available
- MODE = Interactive (locked in)
↓
1. Read task document for requirements
2. Check Automation field (manual | auto)
3. Read implementation for context
4. Create test plan
5. Check if email testing required (see Email Testing section)
└── If auth keywords found → MUST use Mailinator
6. Execute tests via Playwright MCP tools directly
⚠️ DO NOT create test script files
⚠️ DO NOT run npx playwright test
⚠️ DO NOT spawn subagents for testing
7. If auth flow → Verify email received & confirmation works
8. Write report to docs/testing/{task-name}.md
9. Update TASKS.md with result
↓
┌─── Automation Mode? ───┐
│ │
▼ Manual ▼ Auto
PASS → notify user PASS → invoke /document
FAIL → notify user FAIL → invoke /implement with test report进入条件: 无参数且Playwright MCP工具可用。
--ci如果Playwright MCP不可用: 立即停止,不要使用该工作流,不要回退到CI模式,通知用户配置Playwright MCP。
/test {task-name}
↓
0. [已完成] 模式检测确认:
- 无--ci参数
- Playwright MCP可用
- 模式 = 交互模式(已锁定)
↓
1. 读取任务文档了解需求
2. 检查Automation字段(manual | auto)
3. 读取实现代码了解上下文
4. 制定测试计划
5. 检查是否需要邮箱测试(见邮箱测试章节)
└── 如果存在认证相关关键词 → 必须使用Mailinator
6. 直接通过Playwright MCP工具执行测试
⚠️ 不要创建测试脚本文件
⚠️ 不要执行npx playwright test命令
⚠️ 不要启动子代理执行测试
7. 如果是认证流程 → 验证邮箱已接收且确认链接可用
8. 将报告写入docs/testing/{task-name}.md
9. 更新TASKS.md的测试结果
↓
┌─── 自动化模式? ───┐
│ │
▼ 手动模式 ▼ 自动模式
通过 → 通知用户 通过 → 调用/document
不通过 → 通知用户 不通过 → 携带测试报告调用/implementCI/CD Mode (--ci
flag) — Does NOT require Playwright MCP
--ciCI/CD模式(--ci
参数)- 无需Playwright MCP
--ciEntry condition: flag IS present in the command.
--ciIMPORTANT: This mode is ONLY used when the user explicitly provides the flag. Never auto-switch to this mode when Playwright MCP is unavailable.
--ci/test --ci {task-name}
↓
0. [ALREADY DONE] Mode Detection confirmed:
- --ci flag IS present
- MODE = CI (locked in)
- Playwright MCP: not required
↓
1. Read task document for requirements
2. Create test directory: tests/e2e/{task-name}/
3. Generate Playwright test script(s)
4. Run tests headlessly via: npx playwright test
5. Capture results and screenshots
6. Write report to docs/testing/{task-name}.md
7. Clean temporary artifacts (keep test scripts by default)
8. Update TASKS.md with result
↓
Same automation mode handling as interactive/test --ci --cleanup {task-name}
↓
Same as above, but ALSO deletes tests/e2e/{task-name}/ at step 7CI Mode Advantages:
- Parallel test execution
- Test scripts kept by default for regression testing
- Faster for large test suites
- Can spawn subagents for concurrent testing
- Accumulated tests run on every future PR
进入条件: 命令中明确包含参数。
--ci重要提示: 仅当用户明确指定参数时使用该模式,Playwright MCP不可用时不要自动切换到该模式。
--ci/test --ci {task-name}
↓
0. [已完成] 模式检测确认:
- 存在--ci参数
- 模式 = CI模式(已锁定)
- Playwright MCP:不需要
↓
1. 读取任务文档了解需求
2. 创建测试目录:tests/e2e/{task-name}/
3. 生成Playwright测试脚本
4. 通过npx playwright test执行无头测试
5. 捕获测试结果和截图
6. 将报告写入docs/testing/{task-name}.md
7. 清理临时产物(默认保留测试脚本)
8. 更新TASKS.md的测试结果
↓
自动化模式处理逻辑和交互模式一致/test --ci --cleanup {task-name}
↓
和上述流程一致,但在第7步额外删除tests/e2e/{task-name}/目录CI模式优势:
- 支持并行测试执行
- 默认保留测试脚本用于回归测试
- 大型测试套件运行速度更快
- 可启动子代理执行并发测试
- 积累的测试用例会在后续PR中自动运行
CI Mode: Directory Structure (CRITICAL)
CI模式:目录结构(重要)
You MUST follow this exact directory structure. Do NOT put files in wrong locations.
project-root/
├── tests/
│ └── e2e/
│ └── {task-name}/ ← Test scripts go HERE (*.spec.ts)
│ ├── {task-name}.spec.ts
│ └── helpers.ts (if needed)
│
├── docs/
│ └── testing/
│ └── {task-name}.md ← ONLY the final report goes HERE
│
└── (temporary - ALWAYS DELETE)
├── TEST_REPORT.md
├── TEST_CASES.md
├── TEST_SUMMARY.txt
├── test_results.md
├── test_execution_summary.md
├── TEST_REPORT_INDEX.md
├── playwright_mcp_test_log.md
├── test-screenshots/
├── test-results/
└── playwright-report/必须严格遵循以下目录结构,不要将文件放到错误位置。
project-root/
├── tests/
│ └── e2e/
│ └── {task-name}/ ← 测试脚本放在此处 (*.spec.ts)
│ ├── {task-name}.spec.ts
│ └── helpers.ts (按需创建)
│
├── docs/
│ └── testing/
│ └── {task-name}.md ← 仅最终报告放在此处
│
└── (临时文件 - 必须全部删除)
├── TEST_REPORT.md
├── TEST_CASES.md
├── TEST_SUMMARY.txt
├── test_results.md
├── test_execution_summary.md
├── TEST_REPORT_INDEX.md
├── playwright_mcp_test_log.md
├── test-screenshots/
├── test-results/
└── playwright-report/PROHIBITED File Locations
禁止的文件位置
NEVER create these files in :
docs/testing/- ❌
docs/testing/TEST_CASES.md - ❌
docs/testing/test_results.md - ❌
docs/testing/test_execution_summary.md - ❌
docs/testing/TEST_REPORT_INDEX.md - ❌
docs/testing/playwright_mcp_test_log.md - ❌
docs/testing/TEST_SUMMARY.txt - ❌ (test scripts)
docs/testing/*.spec.ts
ONLY allowed in :
docs/testing/- ✅ (final test report, one per task)
docs/testing/{task-name}.md - ✅ (if project has one)
docs/testing/README.md
绝对不要在下创建以下文件:
docs/testing/- ❌
docs/testing/TEST_CASES.md - ❌
docs/testing/test_results.md - ❌
docs/testing/test_execution_summary.md - ❌
docs/testing/TEST_REPORT_INDEX.md - ❌
docs/testing/playwright_mcp_test_log.md - ❌
docs/testing/TEST_SUMMARY.txt - ❌ (测试脚本)
docs/testing/*.spec.ts
docs/testing/- ✅ (最终测试报告,每个任务对应一个)
docs/testing/{task-name}.md - ✅ (如果项目本身有该文件)
docs/testing/README.md
CI Mode: Artifact Management
CI模式:产物管理
Default Behavior (Scripts Kept)
默认行为(保留脚本)
By default, keeps test scripts for regression testing:
/test --ci {task-name}tests/e2e/{task-name}/ ← KEPT for future regression testing
docs/testing/{task-name}.md ← KEPT as final test report (ONLY file in docs/testing/)Temporary artifacts are ALWAYS cleaned (run at end of every CI test):
bash
undefined默认情况下, 会保留测试脚本用于回归测试:
/test --ci {task-name}tests/e2e/{task-name}/ ← 保留用于后续回归测试
docs/testing/{task-name}.md ← 保留作为最终测试报告(docs/testing/下仅保留该文件)临时产物必须始终清理(每次CI测试结束后执行):
bash
undefinedRemove from project root
从项目根目录删除临时文件
rm -f TEST_REPORT.md TEST_SUMMARY.txt TEST_CASES.md
rm -f test_results.md test_execution_summary.md TEST_REPORT_INDEX.md
rm -f playwright_mcp_test_log.md
rm -rf test-screenshots/ test-results/ playwright-report/
rm -f test-.ts test-.js *.spec.ts # Root-level scripts
rm -f TEST_REPORT.md TEST_SUMMARY.txt TEST_CASES.md
rm -f test_results.md test_execution_summary.md TEST_REPORT_INDEX.md
rm -f playwright_mcp_test_log.md
rm -rf test-screenshots/ test-results/ playwright-report/
rm -f test-.ts test-.js *.spec.ts # 根目录下的测试脚本
Remove from docs/testing/ (ONLY final report should remain)
从docs/testing/删除临时文件(仅保留最终报告)
rm -f docs/testing/TEST_CASES.md
rm -f docs/testing/test_results.md
rm -f docs/testing/test_execution_summary.md
rm -f docs/testing/TEST_REPORT_INDEX.md
rm -f docs/testing/playwright_mcp_test_log.md
rm -f docs/testing/TEST_SUMMARY.txt
rm -f docs/testing/*.spec.ts
undefinedrm -f docs/testing/TEST_CASES.md
rm -f docs/testing/test_results.md
rm -f docs/testing/test_execution_summary.md
rm -f docs/testing/TEST_REPORT_INDEX.md
rm -f docs/testing/playwright_mcp_test_log.md
rm -f docs/testing/TEST_SUMMARY.txt
rm -f docs/testing/*.spec.ts
undefinedWith --cleanup
Flag (Scripts Deleted)
--cleanup携带--cleanup
参数(删除脚本)
--cleanupWhen using , test scripts are also deleted:
/test --ci --cleanup {task-name}bash
undefined使用时,测试脚本也会被删除:
/test --ci --cleanup {task-name}bash
undefinedAdditional cleanup with --cleanup flag
--cleanup参数下额外执行的清理操作
rm -rf tests/e2e/{task-name}/
rm -rf tests/e2e/{task-name}/
Clean empty parent directories
清理空的父目录
rmdir tests/e2e 2>/dev/null || true
rmdir tests 2>/dev/null || true
undefinedrmdir tests/e2e 2>/dev/null || true
rmdir tests 2>/dev/null || true
undefinedArtifact Summary
产物汇总
| Artifact | Location | | |
|---|---|---|---|
| Final test report | | ✅ Keep | ✅ Keep |
| Test scripts | | ✅ Keep | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| anywhere | ❌ Delete | ❌ Delete |
| 产物 | 存储位置 | | |
|---|---|---|---|
| 最终测试报告 | | ✅ 保留 | ✅ 保留 |
| 测试脚本 | | ✅ 保留 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
| 任意位置 | ❌ 删除 | ❌ 删除 |
Why Keep Scripts by Default?
为什么默认保留脚本?
Feature A: /test --ci auth-flow
→ tests/e2e/auth-flow/ KEPT
Feature B: /test --ci checkout
→ tests/e2e/checkout/ KEPT
Future PR touches auth code:
→ npx playwright test runs BOTH
→ Catches if new code breaks auth ✅Safe by default - scripts accumulate for regression protection. Use only for minor, one-time verifications.
--cleanup功能A: /test --ci auth-flow
→ tests/e2e/auth-flow/ 保留
功能B: /test --ci checkout
→ tests/e2e/checkout/ 保留
后续PR修改了认证相关代码:
→ npx playwright test会同时运行两个测试用例
→ 及时发现新代码是否破坏了认证功能 ✅默认行为更安全 - 脚本会逐步积累用于回归防护,仅当进行小型一次性验证时使用参数。
--cleanupAuto Mode Behavior
自动模式行为
When task document has :
Automation: auto当任务文档包含时:
Automation: autoOn PASS
测试通过时
Use Task tool to spawn document agent with model: haiku:
[AUTO] Tests PASSED. Spawning /document with haiku model...Task({ subagent_type: "general-purpose", model: "haiku", prompt: "/document {ID}" })使用Task工具启动文档生成子代理,模型指定为haiku:
[AUTO] 测试通过,正在启动haiku模型执行/document命令...Task({ subagent_type: "general-purpose", model: "haiku", prompt: "/document {ID}" })On FAIL
测试不通过时
Use Task tool to spawn implement agent with model: opus (needs advanced reasoning to fix issues):
[AUTO] Tests FAILED. Spawning /implement with opus model for fixes...
Issues found:
1. {Issue summary}
2. {Issue summary}
Re-running implementation with fixes...Task({ subagent_type: "general-purpose", model: "opus", prompt: "/implement {ID} - Fix issues from test report: {summary}" })Note: The implement skill will receive the test report context and should focus on fixing the specific issues identified. After fixes, it will chain back to /test (with haiku).
IMPORTANT: For any task involving registration, login, magic links, or email verification:
- The test is NOT complete until email confirmation is verified via Mailinator
- See "Email-Based Authentication Testing" section for detailed steps
使用Task工具启动实现子代理,模型指定为opus(需要高级推理能力修复问题):
[AUTO] 测试不通过,正在启动opus模型执行/implement命令修复问题...
发现的问题:
1. {问题概要1}
2. {问题概要2}
正在重新执行实现流程修复问题...Task({ subagent_type: "general-purpose", model: "opus", prompt: "/implement {ID} - Fix issues from test report: {summary}" })注意: 实现技能会收到测试报告上下文,聚焦修复发现的特定问题,修复完成后会自动调用/test命令(使用haiku模型)。
重要提示: 任何涉及注册、登录、魔法链接、邮箱验证的任务:
- 必须通过Mailinator验证邮箱确认流程正常后,才能标记测试为通过
- 详细步骤见「基于邮箱的认证测试」章节
Pre-Testing Setup
测试前准备
1. Read the Task Document (Primary Context Source)
1. 读取任务文档(主要上下文来源)
docs/task/{ID}-{task-name}.mdIMPORTANT — Context Efficiency:
The task document contains all the context you need from the planning phase. Do NOT perform broad codebase exploration. Only read the specific files referenced in the task document.
Focus on:
- Requirements checklist
- Testing checklist (if provided)
- Expected behavior
- Files that were modified (listed in the task document)
docs/task/{ID}-{task-name}.md重要提示 - 上下文效率:
任务文档包含规划阶段的所有上下文,不要进行大范围的代码库探索,仅读取任务文档中引用的特定文件即可。
重点关注:
- 需求检查清单
- 测试检查清单(如果提供)
- 预期行为
- 被修改的文件(任务文档中会列出)
2. Understand the Implementation
2. 理解实现逻辑
Review only the files that were changed (as listed in the task document):
- What was created?
- What was modified?
- What are the entry points?
DO NOT scan the entire codebase or read unrelated files. The task document already provides the necessary context.
仅查看任务文档中列出的被修改文件:
- 创建了什么内容?
- 修改了什么内容?
- 入口点是什么?
不要扫描整个代码库或读取不相关的文件,任务文档已经提供了必要的上下文。
3. Identify Test Scenarios
3. 识别测试场景
Create a test plan covering:
- Happy path (main use case)
- Edge cases
- Error handling
- Cross-platform (if applicable)
制定测试计划覆盖以下场景:
- 正常路径(核心使用场景)
- 边界场景
- 错误处理
- 跨平台适配(如果适用)
4. Detect If Email Testing Is Required
4. 检测是否需要邮箱测试
CRITICAL: Scan the task document for these keywords:
- Registration / Sign up / Create account
- Magic Link / OTP / Email verification
- Email confirmation / Confirm email
- Password reset / Forgot password
- Account activation
If ANY of these keywords appear:
- MANDATORY - Use Mailinator for email testing (see "Email-Based Authentication Testing" section below)
- DO NOT mark the test as PASS without verifying:
- Email was received in Mailinator inbox
- Confirmation/verification link works
- Post-confirmation redirect is correct
- Include "Authentication Tests" section in test report
Example detection:
Task doc says: "Magic Link authentication as primary signup method"
→ This REQUIRES email testing via Mailinator
→ Test is NOT complete until email verification is confirmed重要提示: 扫描任务文档是否包含以下关键词:
- 注册 / Sign up / 创建账号
- 魔法链接 / OTP / 邮箱验证
- 邮箱确认 / Confirm email
- 密码重置 / 忘记密码
- 账号激活
如果出现任意上述关键词:
- 必须 使用Mailinator进行邮箱测试(见下方「基于邮箱的认证测试」章节)
- 未验证以下内容前不要标记测试为通过:
- 邮箱已收到邮件到Mailinator收件箱
- 确认/验证链接可用
- 确认后重定向逻辑正确
- 在测试报告中包含「认证测试」章节
检测示例:
任务文档描述:「魔法链接认证作为主要注册方式」
→ 必须通过Mailinator进行邮箱测试
→ 未验证邮箱确认流程正常前测试不算完成Testing with Playwright MCP
使用Playwright MCP进行测试
Available Tools
可用工具
Use the Playwright MCP tools for browser automation:
mcp__playwright__browser_navigate - Go to URL
mcp__playwright__browser_snapshot - Capture accessibility snapshot
mcp__playwright__browser_click - Click elements
mcp__playwright__browser_type - Type text
mcp__playwright__browser_fill_form - Fill form fields
mcp__playwright__browser_take_screenshot - Capture screenshot
mcp__playwright__browser_console_messages - Check console
mcp__playwright__browser_network_requests - Check network
mcp__playwright__browser_wait_for - Wait for conditions使用Playwright MCP工具实现浏览器自动化:
mcp__playwright__browser_navigate - 访问指定URL
mcp__playwright__browser_snapshot - 捕获可访问性快照
mcp__playwright__browser_click - 点击元素
mcp__playwright__browser_type - 输入文本
mcp__playwright__browser_fill_form - 填充表单字段
mcp__playwright__browser_take_screenshot - 捕获截图
mcp__playwright__browser_console_messages - 查看控制台信息
mcp__playwright__browser_network_requests - 查看网络请求
mcp__playwright__browser_wait_for - 等待指定条件Test Execution Pattern
测试执行模式
typescript
// 1. Navigate to the page
mcp__playwright__browser_navigate({ url: "http://localhost:3000/path" })
// 2. Take snapshot to understand page structure
mcp__playwright__browser_snapshot()
// 3. Interact with elements (use ref from snapshot)
mcp__playwright__browser_click({ ref: "button[Submit]", element: "Submit button" })
// 4. Verify results
mcp__playwright__browser_snapshot()
// 5. Check for errors
mcp__playwright__browser_console_messages({ level: "error" })typescript
// 1. 跳转到目标页面
mcp__playwright__browser_navigate({ url: "http://localhost:3000/path" })
// 2. 捕获快照了解页面结构
mcp__playwright__browser_snapshot()
// 3. 与元素交互(使用快照中的ref)
mcp__playwright__browser_click({ ref: "button[Submit]", element: "Submit button" })
// 4. 验证结果
mcp__playwright__browser_snapshot()
// 5. 检查错误
mcp__playwright__browser_console_messages({ level: "error" })Responsive Testing
响应式测试
For responsive web features, resize the viewport:
typescript
mcp__playwright__browser_resize({ width: 390, height: 844 }) // iPhone 14 Pro
mcp__playwright__browser_resize({ width: 768, height: 1024 }) // iPad测试响应式Web功能时,调整视口大小:
typescript
mcp__playwright__browser_resize({ width: 390, height: 844 }) // iPhone 14 Pro
mcp__playwright__browser_resize({ width: 768, height: 1024 }) // iPadTest Report Template
测试报告模板
Create report in :
docs/testing/{ID}-{task-name}.mdmarkdown
undefined在路径下创建报告:
docs/testing/{ID}-{task-name}.mdmarkdown
undefinedTest Report: {Task Name}
Test Report: {任务名称}
Task ID: {ID} Status: PASS | FAIL | PARTIAL Tested: {Date} Task Doc: link
任务ID: {ID} 状态: PASS | FAIL | PARTIAL 测试时间: {日期} 任务文档: link
Summary
概要
{1-2 sentence summary of test results}
{1-2句话总结测试结果}
Test Environment
测试环境
- Platform: Web
- Browser: Chromium (Playwright)
- Base URL: http://localhost:3000
- Viewport: {dimensions if relevant}
- 平台:Web
- 浏览器:Chromium (Playwright)
- 基础URL:http://localhost:3000
- 视口:{视口尺寸,如适用}
Test Results
测试结果
Requirement Tests
需求测试
| # | Requirement | Status | Notes |
|---|---|---|---|
| 1 | {Requirement from task doc} | PASS/FAIL | {Details} |
| 2 | {Requirement} | PASS/FAIL | {Details} |
| # | 需求 | 状态 | 备注 |
|---|---|---|---|
| 1 | {任务文档中的需求} | PASS/FAIL | {详情} |
| 2 | {需求} | PASS/FAIL | {详情} |
Functional Tests
功能测试
Test 1: {Test Name}
测试1:{测试名称}
Steps:
- Navigate to {page}
- Click {element}
- Verify {expected result}
Result: PASS/FAIL
Evidence: {Screenshot or description}
步骤:
- 跳转到{页面}
- 点击{元素}
- 验证{预期结果}
结果: PASS/FAIL
证据: {截图或描述}
Test 2: {Test Name}
测试2:{测试名称}
{Same format}
{相同格式}
Edge Cases
边界场景
| Case | Result | Notes |
|---|---|---|
| Empty state | PASS/FAIL | {Details} |
| Error handling | PASS/FAIL | {Details} |
| Loading state | PASS/FAIL | {Details} |
| 场景 | 结果 | 备注 |
|---|---|---|
| 空状态 | PASS/FAIL | {详情} |
| 错误处理 | PASS/FAIL | {详情} |
| 加载状态 | PASS/FAIL | {详情} |
Console Errors
控制台错误
{Any console errors found, or "None"}{发现的控制台错误,或「无」}Network Issues
网络问题
{Any failed requests, or "None"}{发现的失败请求,或「无」}Issues Found
发现的问题
Issue 1: {Title}
问题1:{标题}
Severity: Critical | Major | Minor
Description: {What's wrong}
Steps to Reproduce:
- Step 1
- Step 2 Expected: {What should happen} Actual: {What actually happens} Screenshot: {If applicable}
严重程度: Critical | Major | Minor
描述: {问题详情}
复现步骤:
- 步骤1
- 步骤2 预期结果: {应该出现的结果} 实际结果: {实际出现的结果} 截图: {如适用}
Issue 2: {Title}
问题2:{标题}
{Same format}
{相同格式}
Screenshots
截图
{Include relevant screenshots}
{包含相关截图}
Recommendations
建议
{Any suggestions for fixes or improvements}
{任何修复或优化建议}
Verdict
结论
PASS - All requirements met, ready for documentation
OR
FAIL - Issues found, needs fixes (see Issues section)
OR
PARTIAL - Core functionality works, minor issues noted
---PASS - 所有需求已满足,可准备生成文档
或
FAIL - 发现问题,需要修复(见问题章节)
或
PARTIAL - 核心功能正常,存在小问题
---Update TASKS.md
更新TASKS.md
If PASS
测试通过时
Move to "Approved" section (pending user approval):
markdown
undefined移动到「Approved」章节(等待用户审批):
markdown
undefinedTesting
Testing
| ID | Task | Task Doc | Test Report | Status |
|---|---|---|---|---|
| 1 | Quick Actions Redesign | 001-quick-actions.md | 001-quick-actions.md | PASS - Awaiting approval |
undefined| ID | 任务 | 任务文档 | 测试报告 | 状态 |
|---|---|---|---|---|
| 1 | 快捷操作重设计 | 001-quick-actions.md | 001-quick-actions.md | PASS - 等待审批 |
undefinedIf FAIL
测试不通过时
Keep in "Testing" with failure note:
markdown
undefined保留在「Testing」章节并标注失败:
markdown
undefinedTesting
Testing
| ID | Task | Task Doc | Test Report | Status |
|---|---|---|---|---|
| 1 | Quick Actions Redesign | 001-quick-actions.md | 001-quick-actions.md | FAIL - See report |
---| ID | 任务 | 任务文档 | 测试报告 | 状态 |
|---|---|---|---|---|
| 1 | 快捷操作重设计 | 001-quick-actions.md | 001-quick-actions.md | FAIL - 查看报告 |
---Handoff
交接流程
Check the task document for field.
Automation: auto检查任务文档的字段。
Automation: autoManual Mode
手动模式
On PASS
测试通过时
Testing complete: #{ID} - {Task Title}
Result: PASS
Test Report: docs/testing/{ID}-{task-name}.md
All requirements verified. Ready for your approval.
Next Steps (after approval):
/document {ID} # e.g., /document 1
/document {ID}-{task-name} # e.g., /document 001-auth-jwt测试完成:#{ID} - {任务标题}
结果:PASS
测试报告:docs/testing/{ID}-{task-name}.md
所有需求已验证,等待您的审批。
后续步骤(审批通过后):
/document {ID} # 例如:/document 1
/document {ID}-{task-name} # 例如:/document 001-auth-jwtOn FAIL
测试不通过时
Testing complete: #{ID} - {Task Title}
Result: FAIL
Test Report: docs/testing/{ID}-{task-name}.md
Issues found:
1. {Issue summary 1}
2. {Issue summary 2}
Next Steps (fix and re-test):
/implement {ID} # e.g., /implement 1
/implement {ID}-{task-name} # e.g., /implement 001-auth-jwt
Then re-run:
/test {ID}测试完成:#{ID} - {任务标题}
结果:FAIL
测试报告:docs/testing/{ID}-{task-name}.md
发现的问题:
1. {问题概要1}
2. {问题概要2}
后续步骤(修复后重新测试):
/implement {ID} # 例如:/implement 1
/implement {ID}-{task-name} # 例如:/implement 001-auth-jwt
修复完成后重新执行:
/test {ID}Auto Mode
自动模式
On PASS
测试通过时
Testing complete: #{ID} - {Task Title}
Result: PASS
Test Report: docs/testing/{ID}-{task-name}.md
[AUTO] Spawning /document with haiku model...Use Task tool:
Task({ subagent_type: "general-purpose", model: "haiku", prompt: "/document {ID}" })测试完成:#{ID} - {任务标题}
结果:PASS
测试报告:docs/testing/{ID}-{task-name}.md
[AUTO] 正在启动haiku模型执行/document命令...使用Task工具:
Task({ subagent_type: "general-purpose", model: "haiku", prompt: "/document {ID}" })On FAIL
测试不通过时
Testing complete: #{ID} - {Task Title}
Result: FAIL
Test Report: docs/testing/{ID}-{task-name}.md
Issues found:
1. {Issue summary 1}
2. {Issue summary 2}
[AUTO] Spawning /implement with opus model for fixes...Use Task tool:
Task({ subagent_type: "general-purpose", model: "opus", prompt: "/implement {ID} - Fix: {issue summaries}" })测试完成:#{ID} - {任务标题}
结果:FAIL
测试报告:docs/testing/{ID}-{task-name}.md
发现的问题:
1. {问题概要1}
2. {问题概要2}
[AUTO] 正在启动opus模型执行/implement命令修复问题...使用Task工具:
Task({ subagent_type: "general-purpose", model: "opus", prompt: "/implement {ID} - Fix: {issue summaries}" })Email-Based Authentication Testing
基于邮箱的认证测试
For testing account registration, email verification, password reset, and email notifications using temporary email services.
CRITICAL: Tests involving email verification, account activation, password reset, or any email-dependent flow MUST NOT be marked as PASS until the email verification is confirmed working. If email testing fails due to service limits, mark the test as BLOCKED and notify the user to take action.
用于测试账号注册、邮箱验证、密码重置、邮箱通知等场景,使用临时邮箱服务完成测试。
重要提示: 涉及邮箱验证、账号激活、密码重置或任何依赖邮箱的流程,必须验证邮箱确认流程正常后才能标记测试为通过。如果由于服务限制导致邮箱测试失败,标记测试为BLOCKED并通知用户处理。
Supported Email Services (Priority Order)
支持的邮箱服务(优先级排序)
| Priority | Service | Method | Domain | Best For |
|---|---|---|---|---|
| 1st | Mail.tm | API | Dynamic ( | Primary - high limits, API-based |
| 2nd | Mailinator | Browser | | Fallback - no signup required |
| 3rd | Guerrilla Mail | Browser | Dynamic | Fallback if others blocked |
| 4th | TempMail | Browser | Dynamic | Last resort |
Always start with Mail.tm. Only fall back to other services if Mail.tm returns rate limit errors (HTTP 429) or account creation fails.
| 优先级 | 服务 | 调用方式 | 域名 | 适用场景 |
|---|---|---|---|---|
| 1 | Mail.tm | API | 动态( | 首选 - 配额高,基于API |
| 2 | Mailinator | 浏览器 | | 备选 - 无需注册 |
| 3 | Guerrilla Mail | 浏览器 | 动态 | Mailinator被拦截时备选 |
| 4 | TempMail | 浏览器 | 动态 | 最后备选 |
始终优先使用Mail.tm,仅当Mail.tm返回速率限制错误(HTTP 429)或账号创建失败时,才回退到其他服务。
Email Testing Workflow
邮箱测试工作流
1. Create temporary email via Mail.tm API
2. Navigate to registration/action page
3. Fill form with temporary email
4. Poll Mail.tm API for incoming email
5. Extract verification link from email
6. Complete verification flow
7. Verify account is active
8. Include email test results in report1. 通过Mail.tm API创建临时邮箱
2. 跳转到注册/操作页面
3. 使用临时邮箱填充表单
4. 轮询Mail.tm API查看是否收到邮件
5. 从邮件中提取验证链接
6. 完成验证流程
7. 验证账号已激活
8. 在报告中包含邮箱测试结果Mail.tm API Reference (Primary Service)
Mail.tm API参考(首选服务)
Mail.tm provides a REST API for creating temporary emails and retrieving messages.
Base URL:
https://api.mail.tmMail.tm提供REST API用于创建临时邮箱和接收邮件。
基础URL:
https://api.mail.tmStep 1: Get Available Domain
步骤1:获取可用域名
bash
undefinedbash
undefinedGet list of available domains
获取可用域名列表
Response example:
响应示例:
{ "hydra:member": [{ "id": "...", "domain": "mail.tm" }] }
{ "hydra:member": [{ "id": "...", "domain": "mail.tm" }] }
undefinedundefinedStep 2: Create Temporary Account
步骤2:创建临时账号
bash
undefinedbash
undefinedCreate account with random address
使用随机地址创建账号
curl -X POST https://api.mail.tm/accounts
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
curl -X POST https://api.mail.tm/accounts
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
Response: { "id": "...", "address": "test-...@mail.tm" }
响应:{ "id": "...", "address": "test-...@mail.tm" }
undefinedundefinedStep 3: Get Authentication Token
步骤3:获取认证令牌
bash
undefinedbash
undefinedGet JWT token for API access
获取API访问的JWT令牌
curl -X POST https://api.mail.tm/token
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
curl -X POST https://api.mail.tm/token
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
-H "Content-Type: application/json"
-d '{ "address": "test-1706234567890@mail.tm", "password": "TestPassword123!" }'
Response: { "token": "eyJ..." }
响应:{ "token": "eyJ..." }
undefinedundefinedStep 4: Poll for Messages
步骤4:轮询查询邮件
bash
undefinedbash
undefinedCheck inbox (poll every 3-5 seconds)
检查收件箱(每3-5秒轮询一次)
curl https://api.mail.tm/messages
-H "Authorization: Bearer {token}"
-H "Authorization: Bearer {token}"
curl https://api.mail.tm/messages
-H "Authorization: Bearer {token}"
-H "Authorization: Bearer {token}"
Response: { "hydra:member": [{ "id": "...", "subject": "...", "from": {...} }] }
响应:{ "hydra:member": [{ "id": "...", "subject": "...", "from": {...} }] }
undefinedundefinedStep 5: Get Message Content
步骤5:获取邮件内容
bash
undefinedbash
undefinedGet full message with HTML content
获取包含HTML内容的完整邮件
curl https://api.mail.tm/messages/{messageId}
-H "Authorization: Bearer {token}"
-H "Authorization: Bearer {token}"
curl https://api.mail.tm/messages/{messageId}
-H "Authorization: Bearer {token}"
-H "Authorization: Bearer {token}"
Response includes: { "html": "<html>...", "text": "..." }
响应包含:{ "html": "<html>...", "text": "..." }
Extract verification link from html or text field
从html或text字段提取验证链接
---
---Step-by-Step: Account Registration Test
分步说明:账号注册测试
Step 1: Create Mail.tm Account via Bash
步骤1:通过Bash创建Mail.tm账号
bash
undefinedbash
undefinedGenerate unique email address
生成唯一邮箱地址
TIMESTAMP=$(date +%s)
RANDOM_STR=$(head /dev/urandom | tr -dc a-z0-9 | head -c 4)
TEST_EMAIL="test-${TIMESTAMP}-${RANDOM_STR}@mail.tm"
TEST_PASSWORD="TestPassword123!"
TIMESTAMP=$(date +%s)
RANDOM_STR=$(head /dev/urandom | tr -dc a-z0-9 | head -c 4)
TEST_EMAIL="test-${TIMESTAMP}-${RANDOM_STR}@mail.tm"
TEST_PASSWORD="TestPassword123!"
Get available domain (verify mail.tm is available)
获取可用域名(验证mail.tm可用)
curl -s https://api.mail.tm/domains | jq '.["hydra:member"][0].domain'
curl -s https://api.mail.tm/domains | jq '.["hydra:member"][0].domain'
Create the temporary email account
创建临时邮箱账号
curl -s -X POST https://api.mail.tm/accounts
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
curl -s -X POST https://api.mail.tm/accounts
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
Get authentication token
获取认证令牌
TOKEN=$(curl -s -X POST https://api.mail.tm/token
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
| jq -r '.token')
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
| jq -r '.token')
echo "Test email: ${TEST_EMAIL}"
echo "Token: ${TOKEN}"
undefinedTOKEN=$(curl -s -X POST https://api.mail.tm/token
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
| jq -r '.token')
-H "Content-Type: application/json"
-d "{"address": "${TEST_EMAIL}", "password": "${TEST_PASSWORD}"}"
| jq -r '.token')
echo "Test email: ${TEST_EMAIL}"
echo "Token: ${TOKEN}"
undefinedStep 2: Navigate to Registration Page
步骤2:跳转到注册页面
typescript
mcp__playwright__browser_navigate({ url: "http://localhost:3000/register" })
mcp__playwright__browser_snapshot()typescript
mcp__playwright__browser_navigate({ url: "http://localhost:3000/register" })
mcp__playwright__browser_snapshot()Step 3: Fill Registration Form
步骤3:填充注册表单
typescript
// Get element refs from snapshot, then fill form
// Use the TEST_EMAIL created in Step 1
mcp__playwright__browser_fill_form({
fields: [
{ name: "Email", type: "textbox", ref: "input[email]", value: TEST_EMAIL },
{ name: "Password", type: "textbox", ref: "input[password]", value: "TestPassword123!" },
{ name: "Confirm Password", type: "textbox", ref: "input[confirmPassword]", value: "TestPassword123!" }
]
})
mcp__playwright__browser_click({ ref: "button[Submit]", element: "Submit button" })typescript
// 从快照获取元素ref,然后填充表单
// 使用步骤1创建的TEST_EMAIL
mcp__playwright__browser_fill_form({
fields: [
{ name: "Email", type: "textbox", ref: "input[email]", value: TEST_EMAIL },
{ name: "Password", type: "textbox", ref: "input[password]", value: "TestPassword123!" },
{ name: "Confirm Password", type: "textbox", ref: "input[confirmPassword]", value: "TestPassword123!" }
]
})
mcp__playwright__browser_click({ ref: "button[Submit]", element: "Submit button" })Step 4: Poll Mail.tm for Verification Email
步骤4:轮询Mail.tm获取验证邮件
bash
undefinedbash
undefinedPoll for messages (repeat every 5 seconds, up to 60 seconds)
轮询查询邮件(每5秒一次,最多等待60秒)
for i in {1..12}; do
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
COUNT=$(echo $MESSAGES | jq '.["hydra:member"] | length')
if [ "$COUNT" -gt "0" ]; then
echo "Email received!"
MESSAGE_ID=$(echo $MESSAGES | jq -r '.["hydra:member"][0].id')
break
fi
echo "Waiting for email... attempt $i/12"
sleep 5
done
undefinedfor i in {1..12}; do
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
COUNT=$(echo $MESSAGES | jq '.["hydra:member"] | length')
if [ "$COUNT" -gt "0" ]; then
echo "Email received!"
MESSAGE_ID=$(echo $MESSAGES | jq -r '.["hydra:member"][0].id')
break
fi
echo "Waiting for email... attempt $i/12"
sleep 5
done
undefinedStep 5: Extract Verification Link
步骤5:提取验证链接
bash
undefinedbash
undefinedGet full message content
获取完整邮件内容
MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
Extract verification link from HTML content
从HTML内容提取验证链接
Adjust the grep pattern based on your auth provider
根据你的认证提供商调整grep规则
VERIFY_LINK=$(echo $MESSAGE | jq -r '.html' | grep -oP 'href="\K[^"]confirm[^"]' | head -1)
VERIFY_LINK=$(echo $MESSAGE | jq -r '.html' | grep -oP 'href="\K[^"]confirm[^"]' | head -1)
Or from text content
或者从文本内容提取
VERIFY_LINK=$(echo $MESSAGE | jq -r '.text' | grep -oP 'https?://[^\s]confirm[^\s]' | head -1)
echo "Verification link: ${VERIFY_LINK}"
undefinedVERIFY_LINK=$(echo $MESSAGE | jq -r '.text' | grep -oP 'https?://[^\s]confirm[^\s]' | head -1)
echo "Verification link: ${VERIFY_LINK}"
undefinedStep 6: Complete Verification
步骤6:完成验证
typescript
// Navigate to the verification link
mcp__playwright__browser_navigate({ url: VERIFY_LINK })
mcp__playwright__browser_snapshot()
// Should see success message or redirect to dashboardtypescript
// 跳转到验证链接
mcp__playwright__browser_navigate({ url: VERIFY_LINK })
mcp__playwright__browser_snapshot()
// 应该看到成功提示或跳转到仪表盘Password Reset Testing
密码重置测试
bash
undefinedbash
undefined1. Use the same Mail.tm account created earlier
1. 使用之前创建的同一个Mail.tm账号
2. Trigger password reset in the app
2. 在应用中触发密码重置
3. Poll for reset email
3. 轮询获取重置邮件
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
MESSAGE_ID=$(echo $MESSAGES | jq -r '.["hydra:member"][0].id')
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
MESSAGE_ID=$(echo $MESSAGES | jq -r '.["hydra:member"][0].id')
4. Extract reset link
4. 提取重置链接
MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
RESET_LINK=$(echo $MESSAGE | jq -r '.html' | grep -oP 'href="\K[^"]reset[^"]' | head -1)
---MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
RESET_LINK=$(echo $MESSAGE | jq -r '.html' | grep -oP 'href="\K[^"]reset[^"]' | head -1)
---Email Notification Testing
邮箱通知测试
For testing transactional emails (booking confirmations, notifications, etc.):
bash
undefined用于测试事务性邮件(预约确认、通知等):
bash
undefined1. Trigger the action that sends email (e.g., make a booking via Playwright)
1. 触发发送邮件的操作(例如通过Playwright创建预约)
2. Poll Mail.tm for notification (may take longer)
2. 轮询Mail.tm获取通知邮件(可能等待时间更长)
for i in {1..24}; do # Up to 2 minutes
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
Look for specific subject
NOTIFICATION=$(echo $MESSAGES | jq -r '.["hydra:member"][] | select(.subject | contains("Booking"))')
if [ -n "$NOTIFICATION" ]; then
echo "Notification received!"
break
fi
sleep 5
done
for i in {1..24}; do # 最多等待2分钟
MESSAGES=$(curl -s https://api.mail.tm/messages
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
查找特定主题的邮件
NOTIFICATION=$(echo $MESSAGES | jq -r '.["hydra:member"][] | select(.subject | contains("Booking"))')
if [ -n "$NOTIFICATION" ]; then
echo "Notification received!"
break
fi
sleep 5
done
3. Verify email content
3. 验证邮件内容
MESSAGE_ID=$(echo $NOTIFICATION | jq -r '.id')
MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
MESSAGE_ID=$(echo $NOTIFICATION | jq -r '.id')
MESSAGE=$(curl -s https://api.mail.tm/messages/${MESSAGE_ID}
-H "Authorization: Bearer ${TOKEN}")
-H "Authorization: Bearer ${TOKEN}")
Validate content
验证内容
echo $MESSAGE | jq '.html' | grep -q "booking details" && echo "Content valid"
---echo $MESSAGE | jq '.html' | grep -q "booking details" && echo "Content valid"
---Fallback: When Mail.tm Hits Rate Limits
备选方案:Mail.tm触发速率限制时
If Mail.tm returns HTTP 429 (Too Many Requests) or account creation fails:
如果Mail.tm返回HTTP 429(请求过多)或账号创建失败:
Fallback to Mailinator (Browser-based)
回退到Mailinator(基于浏览器)
typescript
// Generate Mailinator email (no account creation needed)
const testEmail = `test-${Date.now()}@mailinator.com`;
const inboxName = testEmail.split('@')[0];
// After triggering email, navigate to inbox
mcp__playwright__browser_navigate({
url: `https://www.mailinator.com/v4/public/inboxes.jsp?to=${inboxName}`
})
mcp__playwright__browser_wait_for({ time: 10 })
mcp__playwright__browser_snapshot()
// Click on email row and extract link
mcp__playwright__browser_click({ ref: "row[YourApp]", element: "Email from app" })
mcp__playwright__browser_snapshot()typescript
// 生成Mailinator邮箱(无需创建账号)
const testEmail = `test-${Date.now()}@mailinator.com`;
const inboxName = testEmail.split('@')[0];
// 触发邮件发送后,跳转到收件箱
mcp__playwright__browser_navigate({
url: `https://www.mailinator.com/v4/public/inboxes.jsp?to=${inboxName}`
})
mcp__playwright__browser_wait_for({ time: 10 })
mcp__playwright__browser_snapshot()
// 点击邮件行提取链接
mcp__playwright__browser_click({ ref: "row[YourApp]", element: "Email from app" })
mcp__playwright__browser_snapshot()Fallback to Guerrilla Mail (Browser-based)
回退到Guerrilla Mail(基于浏览器)
typescript
// Navigate to Guerrilla Mail
mcp__playwright__browser_navigate({ url: "https://www.guerrillamail.com/" })
mcp__playwright__browser_snapshot()
// Get the generated email address from the page
// Use this address for registration
// Check inbox on the same page for incoming emailstypescript
// 跳转到Guerrilla Mail
mcp__playwright__browser_navigate({ url: "https://www.guerrillamail.com/" })
mcp__playwright__browser_snapshot()
// 从页面获取生成的邮箱地址
// 使用该地址进行注册
// 在同一页面查看收件箱是否收到邮件Troubleshooting
问题排查
| Issue | Solution |
|---|---|
| Mail.tm 429 error | Switch to Mailinator fallback |
| Mail.tm account creation fails | Try different domain from /domains endpoint |
| Email not arriving (60s+) | Check spam, verify email was sent, try fallback |
| Mailinator rate limited | Switch to Guerrilla Mail |
| All services failing | Mark test as BLOCKED, notify user |
| Can't extract link | Check HTML/text parsing, adjust regex pattern |
| Supabase rate limiting | Wait 60s between tests, use different emails |
| 问题 | 解决方案 |
|---|---|
| Mail.tm返回429错误 | 切换到Mailinator备选方案 |
| Mail.tm账号创建失败 | 尝试从/domains接口获取其他域名 |
| 超过60秒未收到邮件 | 检查垃圾邮件,确认邮件已发送,尝试备选方案 |
| Mailinator触发速率限制 | 切换到Guerrilla Mail |
| 所有服务都不可用 | 标记测试为BLOCKED,通知用户 |
| 无法提取链接 | 检查HTML/文本解析逻辑,调整正则表达式 |
| Supabase触发速率限制 | 测试间隔等待60秒,使用不同邮箱 |
When to Mark Test as BLOCKED
何时标记测试为BLOCKED
Mark the test as BLOCKED (not FAIL) when:
- All email services are rate-limited
- Cannot create temporary email account
- Email never arrives after 2+ minutes across multiple services
markdown
**Result:** BLOCKED
**Reason:** Email service rate limits reached
**Action Required:** User must manually verify email flow or wait for rate limits to reset出现以下情况时标记测试为BLOCKED(不是FAIL):
- 所有邮箱服务都触发速率限制
- 无法创建临时邮箱账号
- 跨多个服务等待超过2分钟仍未收到邮件
markdown
**结果:** BLOCKED
**原因:** 邮箱服务触发速率限制
**需要操作:** 用户需手动验证邮箱流程或等待速率限制重置Test Report: Email Authentication Section
测试报告:邮箱认证章节
Add to test report when testing auth flows:
markdown
undefined测试认证流程时,在报告中添加以下内容:
markdown
undefinedAuthentication Tests
认证测试
| Test | Email Service | Email Used | Result | Notes |
|---|---|---|---|---|
| Registration | Mail.tm | test-xxx@mail.tm | PASS/FAIL/BLOCKED | {Details} |
| Email verification | Mail.tm | (same) | PASS/FAIL/BLOCKED | Link received in Xs |
| Password reset | Mail.tm | (same) | PASS/FAIL/BLOCKED | {Details} |
| Login after verify | - | (same) | PASS/FAIL | {Details} |
| 测试项 | 邮箱服务 | 使用的邮箱 | 结果 | 备注 |
|---|---|---|---|---|
| 注册 | Mail.tm | test-xxx@mail.tm | PASS/FAIL/BLOCKED | {详情} |
| 邮箱验证 | Mail.tm | (同上) | PASS/FAIL/BLOCKED | X秒收到链接 |
| 密码重置 | Mail.tm | (同上) | PASS/FAIL/BLOCKED | {详情} |
| 验证后登录 | - | (同上) | PASS/FAIL | {详情} |
Email Delivery
邮箱投递情况
| Email Type | Service Used | Received | Time | Content Valid |
|---|---|---|---|---|
| Verification | Mail.tm | Yes/No | Xs | Yes/No |
| Password Reset | Mail.tm | Yes/No | Xs | Yes/No |
| Booking Confirm | Mail.tm | Yes/No | Xs | Yes/No |
| 邮件类型 | 使用服务 | 是否收到 | 耗时 | 内容是否有效 |
|---|---|---|---|---|
| 验证邮件 | Mail.tm | 是/否 | X秒 | 是/否 |
| 密码重置邮件 | Mail.tm | 是/否 | X秒 | 是/否 |
| 预约确认邮件 | Mail.tm | 是/否 | X秒 | 是/否 |
Service Fallback Log (if applicable)
服务回退日志(如适用)
| Attempt | Service | Result | Error |
|---|---|---|---|
| 1 | Mail.tm | Failed | 429 Too Many Requests |
| 2 | Mailinator | Success | - |
---| 尝试次数 | 服务 | 结果 | 错误信息 |
|---|---|---|---|
| 1 | Mail.tm | 失败 | 429 Too Many Requests |
| 2 | Mailinator | 成功 | - |
---Manual Testing Guidance
手动测试指南
For features that can't be fully automated:
无法完全自动化的功能参考以下说明:
What to Test Manually
手动测试范围
- Complex user interactions
- Visual design accuracy
- Animation smoothness
- 复杂用户交互
- 视觉设计准确性
- 动画流畅度
Document Manual Tests
记录手动测试结果
Include in report:
markdown
undefined在报告中包含以下内容:
markdown
undefinedManual Testing Required
需要手动测试
| Test | Instructions | Expected Result |
|---|---|---|
| Visual accuracy | Compare to design | Matches mockup |
| Animation | Trigger X action | Smooth 60fps |
---| 测试项 | 操作说明 | 预期结果 |
|---|---|---|
| 视觉准确性 | 和设计稿对比 | 和原型完全匹配 |
| 动画 | 触发X操作 | 流畅60fps |
---Related Skills
相关技能
| Skill | When to Use |
|---|---|
| When tests fail, return to implement |
| After tests pass and user approves |
| 技能 | 适用场景 |
|---|---|
| 测试失败时返回实现阶段 |
| 测试通过且用户审批后生成文档 |
Recommended Plugins (Install Separately)
推荐插件(需单独安装)
These plugins must be installed separately. Once installed, they MUST be invoked — do not skip them:
| Plugin | Install From | When to Invoke |
|---|---|---|
| vercel-labs/agent-skills | React/Next.js debugging |
| supabase/agent-skills | Database-related test issues |
以下插件需单独安装,安装后必须调用,不要跳过:
| 插件 | 安装地址 | 调用时机 |
|---|---|---|
| vercel-labs/agent-skills | React/Next.js调试 |
| supabase/agent-skills | 数据库相关测试问题 |