expect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExpect — Diff-Aware AI Browser Testing
Expect — 感知Diff的AI浏览器测试
Analyze git changes, generate targeted test plans, and execute them via AI-driven browser automation.
bash
/ork:expect # Auto-detect changes, test affected pages
/ork:expect -m "test the checkout flow" # Specific instruction
/ork:expect --flow login # Replay a saved test flow
/ork:expect --target branch # Test all changes on current branch vs main
/ork:expect -y # Skip plan review, run immediatelyCore principle: Only test what changed. Git diff drives scope — no wasted cycles on unaffected pages.
分析git变更,生成针对性测试计划,并通过AI驱动的浏览器自动化执行测试。
bash
/ork:expect # 自动检测变更,测试受影响页面
/ork:expect -m "test the checkout flow" # 自定义测试指令
/ork:expect --flow login # 重放已保存的测试流程
/ork:expect --target branch # 对比main分支,测试当前分支的所有变更
/ork:expect -y # 跳过计划审核,立即执行核心理念:仅测试变更内容。Git diff决定测试范围,不会在未受影响的页面上浪费资源。
Argument Resolution
参数解析
python
ARGS = "[-m <instruction>] [--target unstaged|branch|commit] [--flow <slug>] [-y]"python
ARGS = "[-m <instruction>] [--target unstaged|branch|commit] [--flow <slug>] [-y]"Parse from full argument string
从完整参数字符串解析
import re
raw = "" # Full argument string from CC
INSTRUCTION = None
TARGET = "unstaged" # Default: test unstaged changes
FLOW = None
SKIP_REVIEW = False
import re
raw = "" # 来自CC的完整参数字符串
INSTRUCTION = None
TARGET = "unstaged" # 默认:测试未暂存的变更
FLOW = None
SKIP_REVIEW = False
Extract -m "instruction"
提取 -m "instruction"
m_match = re.search(r'-m\s+"'["']|-m\s+(\S+)', raw)
if m_match:
INSTRUCTION = m_match.group(1) or m_match.group(2)
m_match = re.search(r'-m\s+"'["']|-m\s+(\S+)', raw)
if m_match:
INSTRUCTION = m_match.group(1) or m_match.group(2)
Extract --target
提取 --target
t_match = re.search(r'--target\s+(unstaged|branch|commit)', raw)
if t_match:
TARGET = t_match.group(1)
t_match = re.search(r'--target\s+(unstaged|branch|commit)', raw)
if t_match:
TARGET = t_match.group(1)
Extract --flow
提取 --flow
f_match = re.search(r'--flow\s+(\S+)', raw)
if f_match:
FLOW = f_match.group(1)
f_match = re.search(r'--flow\s+(\S+)', raw)
if f_match:
FLOW = f_match.group(1)
Extract -y
提取 -y
if '-y' in raw.split():
SKIP_REVIEW = True
undefinedif '-y' in raw.split():
SKIP_REVIEW = True
undefinedSTEP 0: MCP Probe + Prerequisite Check
步骤0: MCP探测 + 前置检查
python
ToolSearch(query="select:mcp__memory__search_nodes")python
ToolSearch(query="select:mcp__memory__search_nodes")Verify agent-browser is available
验证agent-browser可用
Bash("command -v agent-browser || npx agent-browser --version")
Bash("command -v agent-browser || npx agent-browser --version")
If missing: "Install agent-browser: npm i -g @anthropic-ai/agent-browser"
若缺失:"安装agent-browser: npm i -g @anthropic-ai/agent-browser"
undefinedundefinedCRITICAL: Task Management
关键:任务管理
python
TaskCreate(
subject="Expect: test changed code",
description="Diff-aware browser testing pipeline",
activeForm="Running diff-aware browser tests"
)python
TaskCreate(
subject="Expect: test changed code",
description="Diff-aware browser testing pipeline",
activeForm="Running diff-aware browser tests"
)Pipeline Overview
流程概览
Git Diff → Route Map → Fingerprint Check → Test Plan → Execute → Report| Phase | What | Output | Reference |
|---|---|---|---|
| 1. Fingerprint | SHA-256 hash of changed files | Skip if unchanged since last run | |
| 2. Diff Scan | Parse git diff, classify changes | ChangesFor data (files, components, routes) | |
| 3. Route Map | Map changed files to affected pages/URLs | Scoped page list | |
| 4. Test Plan | Generate AI test plan from diff + route map | Markdown test plan with steps | |
| 5. Execute | Run test plan via agent-browser | Pass/fail per step, screenshots | |
| 6. Report | Aggregate results, artifacts, exit code | Structured report + artifacts | |
Git Diff → Route Map → Fingerprint Check → Test Plan → Execute → Report| 阶段 | 内容 | 输出 | 参考 |
|---|---|---|---|
| 1. 指纹校验 | 变更文件的SHA-256哈希 | 若自上次运行后无变更则跳过 | |
| 2. Diff扫描 | 解析git diff,分类变更 | ChangesFor数据(文件、组件、路由) | |
| 3. 路由映射 | 将变更文件关联到受影响页面/URL | 限定范围的页面列表 | |
| 4. 测试计划 | 基于diff和路由映射生成AI测试计划 | 带步骤的Markdown格式测试计划 | |
| 5. 执行 | 通过agent-browser运行测试计划 | 单步骤通过/失败结果、截图 | |
| 6. 报告 | 聚合结果、产物、退出码 | 结构化报告 + 产物文件 | |
Phase 1: Fingerprint Check
阶段1:指纹校验
Check if the current changes have already been tested:
python
Read(".expect/fingerprints.json") # Previous run hashes检查当前变更是否已经测试过:
python
Read(".expect/fingerprints.json") # 上次运行的哈希值Compare SHA-256 of changed files against stored fingerprints
对比变更文件的SHA-256和已存储的指纹
If match: "No changes since last test run. Use --force to re-run."
若匹配:"自上次测试运行后无变更。使用--force强制重新运行。"
If no match or --force: continue to Phase 2
若不匹配或传入--force:继续进入阶段2
Load: `Read("${CLAUDE_SKILL_DIR}/references/fingerprint.md")`
加载: `Read("${CLAUDE_SKILL_DIR}/references/fingerprint.md")`Phase 2: Diff Scan
阶段2:Diff扫描
Analyze git changes based on :
--targetpython
if TARGET == "unstaged":
diff = Bash("git diff")
files = Bash("git diff --name-only")
elif TARGET == "branch":
diff = Bash("git diff main...HEAD")
files = Bash("git diff main...HEAD --name-only")
elif TARGET == "commit":
diff = Bash("git diff HEAD~1")
files = Bash("git diff HEAD~1 --name-only")Classify each changed file into 3 levels:
- Direct — the file itself changed
- Imported — a file that imports the changed file
- Routed — the page/route that renders the changed component
Load:
Read("${CLAUDE_SKILL_DIR}/references/diff-scanner.md")基于参数分析git变更:
--targetpython
if TARGET == "unstaged":
diff = Bash("git diff")
files = Bash("git diff --name-only")
elif TARGET == "branch":
diff = Bash("git diff main...HEAD")
files = Bash("git diff main...HEAD --name-only")
elif TARGET == "commit":
diff = Bash("git diff HEAD~1")
files = Bash("git diff HEAD~1 --name-only")将每个变更文件分为3个层级:
- 直接变更 — 文件本身发生了修改
- 导入关联 — 导入了该变更文件的其他文件
- 路由关联 — 渲染该变更组件的页面/路由
加载:
Read("${CLAUDE_SKILL_DIR}/references/diff-scanner.md")Phase 3: Route Map
阶段3:路由映射
Map changed files to testable URLs using :
.expect/config.yamlyaml
undefined使用将变更文件映射到可测试的URL:
.expect/config.yamlyaml
undefined.expect/config.yaml
.expect/config.yaml
base_url: http://localhost:3000
route_map:
"src/components/Header.tsx": ["/", "/about", "/pricing"]
"src/app/auth/": ["/login", "/signup", "/forgot-password"]
"src/app/dashboard/": ["/dashboard"]
If no route map exists, infer from Next.js App Router / Pages Router conventions.
Load: `Read("${CLAUDE_SKILL_DIR}/references/route-map.md")`base_url: http://localhost:3000
route_map:
"src/components/Header.tsx": ["/", "/about", "/pricing"]
"src/app/auth/": ["/login", "/signup", "/forgot-password"]
"src/app/dashboard/": ["/dashboard"]
如果不存在路由映射,则基于Next.js App Router / Pages Router规范自动推断。
加载: `Read("${CLAUDE_SKILL_DIR}/references/route-map.md")`Phase 4: Test Plan Generation
阶段4:测试计划生成
Build an AI test plan scoped to the diff, using the scope strategy for the current target:
python
scope_strategy = get_scope_strategy(TARGET) # See references/scope-strategy.md
prompt = f"""
{scope_strategy}
Changes: {diff_summary}
Affected pages: {affected_urls}
Instruction: {INSTRUCTION or "Test that the changes work correctly"}
Generate a test plan with:
1. Page-level checks (loads, no console errors, correct content)
2. Interaction tests (forms, buttons, navigation affected by the diff)
3. Visual regression (compare ARIA snapshots if saved)
4. Accessibility (axe-core scan on affected pages)
"""If specified, load saved flow from instead of generating.
--flow.expect/flows/{slug}.yamlIf NOT , present plan to user via for review before executing.
--yAskUserQuestionLoad:
Read("${CLAUDE_SKILL_DIR}/references/test-plan.md")基于当前目标的范围策略,生成限定在diff范围内的AI测试计划:
python
scope_strategy = get_scope_strategy(TARGET) # 参考references/scope-strategy.md
prompt = f"""
{scope_strategy}
变更内容: {diff_summary}
受影响页面: {affected_urls}
指令: {INSTRUCTION or "测试变更功能正常运行"}
生成包含以下内容的测试计划:
1. 页面级检查(可正常加载、无控制台错误、内容正确)
2. 交互测试(受diff影响的表单、按钮、导航)
3. 视觉回归(如果已保存ARIA快照则进行对比)
4. 可访问性(在受影响页面运行axe-core扫描)
"""如果指定了,则从加载已保存的流程,不再生成新计划。
--flow.expect/flows/{slug}.yaml如果未传入,则通过将计划展示给用户审核后再执行。
--yAskUserQuestion加载:
Read("${CLAUDE_SKILL_DIR}/references/test-plan.md")Phase 5: Execution
阶段5:执行
Run the test plan via :
agent-browserpython
Agent(
subagent_type="expect-agent",
prompt=f"""Execute this test plan:
{test_plan}
For each step:
1. Navigate to the URL
2. Execute the test action
3. Take a screenshot on failure
4. Report PASS/FAIL with evidence
""",
run_in_background=True,
model="sonnet",
max_turns=50
)Load:
Read("${CLAUDE_SKILL_DIR}/references/execution.md")通过运行测试计划:
agent-browserpython
Agent(
subagent_type="expect-agent",
prompt=f"""执行该测试计划:
{test_plan}
每个步骤遵循以下规则:
1. 导航到对应URL
2. 执行测试动作
3. 失败时截图
4. 上报PASS/FAIL结果及佐证材料
""",
run_in_background=True,
model="sonnet",
max_turns=50
)加载:
Read("${CLAUDE_SKILL_DIR}/references/execution.md")Phase 6: Report
阶段6:报告
/ork:expect Report
═══════════════════════════════════════
Target: unstaged (3 files changed)
Pages tested: 4
Duration: 45s
Results:
✓ /login — form renders, submit works
✓ /signup — validation triggers on empty fields
✗ /dashboard — chart component crashes (TypeError)
✓ /settings — preferences save correctly
3 passed, 1 failed
Artifacts:
.expect/reports/2026-03-26T16-30-00.json
.expect/screenshots/dashboard-error.pngLoad:
Read("${CLAUDE_SKILL_DIR}/references/report.md")/ork:expect 报告
═══════════════════════════════════════
测试目标: unstaged (3个文件变更)
测试页面数: 4
耗时: 45s
结果:
✓ /login — 表单渲染正常,提交功能可用
✓ /signup — 空字段时可触发校验
✗ /dashboard — 图表组件崩溃(TypeError)
✓ /settings — 偏好设置可正常保存
3个通过,1个失败
产物:
.expect/reports/2026-03-26T16-30-00.json
.expect/screenshots/dashboard-error.png加载:
Read("${CLAUDE_SKILL_DIR}/references/report.md")Saved Flows
已保存流程
Reusable test sequences stored in :
.expect/flows/yaml
undefined存储在的可复用测试序列:
.expect/flows/yaml
undefined.expect/flows/login.yaml
.expect/flows/login.yaml
name: Login Flow
steps:
- navigate: /login
- fill: { selector: "#email", value: "test@example.com" }
- fill: { selector: "#password", value: "password123" }
- click: button[type="submit"]
- assert: { url: "/dashboard" }
- assert: { text: "Welcome back" }
Run with: `/ork:expect --flow login`name: 登录流程
steps:
- navigate: /login
- fill: { selector: "#email", value: "test@example.com" }
- fill: { selector: "#password", value: "password123" }
- click: button[type="submit"]
- assert: { url: "/dashboard" }
- assert: { text: "欢迎回来" }
运行命令: `/ork:expect --flow login`When NOT to Use
不适用场景
- Unit tests — use instead
/ork:cover - API-only changes — no browser UI to test
- Generated files — skip build artifacts, lock files
- Docs-only changes — unless you want to verify docs site rendering
- 单元测试 — 请使用
/ork:cover - 仅API变更 — 没有浏览器UI需要测试
- 生成的文件 — 跳过构建产物、锁文件
- 仅文档变更 — 除非你需要验证文档站点的渲染效果
Related Skills
相关技能
- — Browser automation engine (required dependency)
agent-browser - — Test suite generation (unit/integration/e2e)
ork:cover - — Grade existing test quality
ork:verify - — Playwright patterns and best practices
testing-e2e
- — 浏览器自动化引擎(必需依赖)
agent-browser - — 测试套件生成(单元/集成/e2e)
ork:cover - — 评估现有测试质量
ork:verify - — Playwright模式和最佳实践
testing-e2e
References
参考文件
Load on demand with :
Read("${CLAUDE_SKILL_DIR}/references/<file>")| File | Content |
|---|---|
| SHA-256 gating logic |
| Git diff parsing + 3-level classification |
| File-to-URL mapping conventions |
| AI test plan generation prompt templates |
| agent-browser orchestration patterns |
| Report format + artifact storage |
| .expect/config.yaml full schema |
| ARIA snapshot comparison for semantic diffing |
| Test depth strategy per target mode |
| Markdown+YAML flow format, adaptive replay |
| rrweb DOM replay integration |
| AskUserQuestion plan review gate |
| GitHub Actions workflow + pre-push hooks |
| millionco/expect architecture analysis |
Version: 1.0.0 (March 2026) — Initial scaffold, M99 milestone
按需使用加载:
Read("${CLAUDE_SKILL_DIR}/references/<file>")| 文件 | 内容 |
|---|---|
| SHA-256准入逻辑 |
| Git diff解析 + 3级分类规则 |
| 文件到URL的映射规范 |
| AI测试计划生成提示词模板 |
| agent-browser编排模式 |
| 报告格式 + 产物存储规则 |
| .expect/config.yaml完整 schema |
| 用于语义diff的ARIA快照对比 |
| 不同目标模式的测试深度策略 |
| Markdown+YAML流程格式、自适应重放 |
| rrweb DOM重放集成 |
| AskUserQuestion计划审核闸门 |
| GitHub Actions工作流 + pre-push钩子 |
| millionco/expect架构分析 |
版本:1.0.0(2026年3月)—— 初始框架,M99里程碑