expect について
expectは、Git差分から対象を絞ってWeb変更をブラウザテストするスキルです。変更ファイルを影響するルートに対応付け、確認用のテスト計画を作成し、agent-browserで実行します。
主な機能
- 01Git差分に基づく範囲限定
- 02変更ファイルとルートの対応付け
- 03AIによるテスト計画の作成
- 04agent-browserでのブラウザテスト
- 05保存済みフローの再生
- 06結果と証拠のレポート
活用シーン
- 01UI変更後の影響ページのテスト
- 02ブランチ差分に関わるページの一括確認
- 03保存したログインフローの再実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill expectインストール後、Claude Code で/expectを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
jev-shadow.defaults.yamlflows/crud.mdlogin.mdnavigation.mdreferences/aria-diffing.mdci-integration.mdconfig-schema.mddiff-scanner.mdexecution.mdfingerprint.mdhuman-review.mdjev-shadow.mdreport.mdresearch.mdroute-map.mdrrweb-recording.mdsaved-flows.mdscope-strategy.mdtest-plan.mdrules/_sections.mdartifact-storage.mddiff-scope-boundaries.mdfingerprint-invalidation.mdno-parallel-browsers.mdtimeout-and-retry.mdscripts/coverage-context.shdiff-scan.shfingerprint.shinit.shjev_shadow.py詳細
Expect — 差分対応 AI ブラウザーテスト
Git の変更を分析し、対象を絞ったテスト計画を生成して、AI 駆動のブラウザー自動化で実行します。
注:
disableSkillShellExecutionが有効な場合(CC 2.1.91)、agent-browser のインストール確認は実行されません。インストールされていることを確認してください:npx agent-browser --version。
expect # Auto-detect changes, test affected pages
expect -m "test the checkout flow" # Specific instruction
expect --flow login # Replay a saved test flow
expect --target branch # Test all changes on current branch vs main
expect -y # Skip plan review, run immediately
基本方針: 変更された箇所だけをテストします。Git の差分に基づいて範囲を決定し、影響を受けていないページに時間を費やしません。
引数の解決
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
# Extract -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)
# Extract --target
t_match = re.search(r'--target\s+(unstaged|branch|commit)', raw)
if t_match:
TARGET = t_match.group(1)
# Extract --flow
f_match = re.search(r'--flow\s+(\S+)', raw)
if f_match:
FLOW = f_match.group(1)
# Extract -y
if '-y' in raw.split():
SKIP_REVIEW = True
ステップ 0:MCP プローブと前提条件の確認
# memory is alwaysLoad in .mcp.json (CC 2.1.121+, #1541) — probe below kept as fallback for older CC:
ToolSearch(query="select:mcp__memory__search_nodes")
# Verify agent-browser is available (Rust-native, no Playwright)
Bash("command -v agent-browser || npx agent-browser --version")
# If missing: "Install agent-browser: npm i -g agent-browser"
# Load agent-browser's version-matched workflow guide (ships with the CLI).
# NOT `skills get agent-browser` — that resolves but returns only the thin
# top-level router; `core --full` is the actual 2,800+ line command reference.
Bash("agent-browser skills get core --full")
重要:タスク管理
# 1. Create main task IMMEDIATELY
TaskCreate(
subject="Expect: test changed code",
description="Diff-aware browser testing pipeline",
activeForm="Running diff-aware browser tests"
)
# 2. Create subtasks for each pipeline phase
TaskCreate(subject="Check fingerprint (skip if unchanged)", activeForm="Checking fingerprint") # id=2
TaskCreate(subject="Scan git diff and classify changes", activeForm="Scanning diff") # id=3
TaskCreate(subject="Map changes to routes/URLs", activeForm="Mapping routes") # id=4
TaskCreate(subject="Generate AI test plan", activeForm="Generating test plan") # id=5
TaskCreate(subject="Execute tests via agent-browser", activeForm="Executing browser tests") # id=6
TaskCreate(subject="Compile test report", activeForm="Compiling report") # id=7
# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"]) # Diff scan needs fingerprint check
TaskUpdate(taskId="4", addBlockedBy=["3"]) # Route map needs diff results
TaskUpdate(taskId="5", addBlockedBy=["4"]) # Test plan needs route map
TaskUpdate(taskId="6", addBlockedBy=["5"]) # Execution needs test plan
TaskUpdate(taskId="7", addBlockedBy=["6"]) # Report needs execution results
# 4. Update status as you progress
TaskUpdate(taskId="2", status="in_progress") # When starting
TaskUpdate(taskId="2", status="completed") # When done — repeat for each subtask
パイプラインの概要
Git Diff → Route Map → Fingerprint Check → Test Plan → Execute → Report
| フェーズ | 内容 | 出力 | 参照先 |
|---|---|---|---|
| 1. フィンガープリント | 変更ファイルの SHA-256 ハッシュ | 前回の実行以降に変更がなければスキップ | references/fingerprint.md |
| 2. 差分スキャン | Git の差分を解析し、変更を分類 | ChangesFor データ(ファイル、コンポーネント、ルート) | references/diff-scanner.md |
| 3. ルートマップ | 変更ファイルを影響を受けるページ/URL に対応付け | 対象を絞ったページ一覧 | references/route-map.md |
| 4. テスト計画 | 差分とルートマップから AI テスト計画を生成 | 手順を含む Markdown テスト計画 | references/test-plan.md |
| 5. 実行 | agent-browser でテスト計画を実行 | 各手順の合否、スクリーンショット | references/execution.md |
| 6. レポート | 結果、成果物、終了コードを集約 | 構造化レポートと成果物 | references/report.md |
フェーズ 1:フィンガープリントの確認
現在の変更がすでにテスト済みかどうかを確認します。
Read(".expect/fingerprints.json") # Previous run hashes
# Compare SHA-256 of changed files against stored fingerprints
# If match: "No changes since last test run. Use --force to re-run."
# If no match or --force: continue to Phase 2
読み込み:Read("references/fingerprint.md")
フェーズ 2:差分スキャン
--target に基づいて Git の変更を分析します。
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("references/diff-scanner.md")
フェーズ 3:ルートマップ
.expect/config.yaml を使って、変更ファイルをテスト可能な URL に対応付けます。
# .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"]
ルートマップが存在しない場合は、Next.js App Router/Pages Router の規約から推測します。
読み込み:Read("references/route-map.md")
フェーズ 4:テスト計画の生成
現在の対象に応じた範囲設定戦略を使い、差分に対象を絞った AI テスト計画を作成します。
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)
"""
--flow が指定されている場合は、生成する代わりに .expect/flows/{slug}.yaml から保存済みのフローを読み込みます。
--y が指定されていない場合は、実行前に AskUserQuestion で計画をユーザーに提示し、確認を求めます。
読み込み:Read("references/test-plan.md")
フェーズ 5:実行
agent-browser クイックガイド
最低バージョンは
>= 0.31.1です(0.27.1 は本番ページで動作しないことが確認されています)。現在テスト済みのリリースは 0.38.1 です(upstream-version-testedを参照)。以下のコマンドは、この範囲の全バージョンで使用できます。0.30 以降では、agent-browser read(エージェントが読み取れるテキスト抽出)と、エージェントの実行間でブラウザーの状態を安定して分離するための--restore/--namespaceセッション復元ワークフローが追加されています。0.33.0 では、axe-core を組み込んだ監査機能agent-browser a11y [url]が追加されています(WCAG タグによるフィルタリング、セレクターの範囲指定、iframe を認識したテキスト/JSON 出力)。CLI コマンドと MCP ツールの両方で使用できます。0.34.0 では、共有 Chrome セッション向けにセッションとタブの永続的なバインドが追加されました。--pin-tabを指定するとバインドが厳密になり、外部からタブが閉じられた場合に安定したtab_goneエラーが返されます。0.35.0 では、SSL 検査プロキシ配下で信頼されたローカル CA を指定する--ca-cert <path>が追加されています(Linux のみ。--ignore-https-errorsに代わる、対象を限定した方法です)。0.35.1 では、下記の Diff 行が依存する動作が変更されています。diff snapshotは差分ごとに参照番号をリセットし、ページ遷移をまたいで参照を無効化するようになったため、ページ遷移前に取得した参照は再利用せず、再取得する必要があります。0.36.0 では、実験的な WebMCP ツールの検出機能(webmcp list/invoke/result/cancel、open時の簡潔な未検証カタログ概要)が追加されています。0.37.0 では、recordがアクティブなページを 30 fps でキャプチャし、新しいタブにもセッション設定を引き継ぐようになりました。0.38.0 では、snapshot --delta(最初にベースライン全体を取得し、その後はunchangedまたは簡潔な構造変更を返します)、screenshot --if-changed --threshold、同一ドキュメント内の DOM 変更後も維持される永続的な参照、ポインターの動きをより人間らしくする--human/--input-mode、auth login --no-navigateが追加されています。すべてのコマンドについては、references/upstream.mdとagent-browser skills get core --fullを参照してください。
| 領域 | コマンド | 備考 |
|---|---|---|
| スナップショット | agent-browser snapshot -i | @eN 参照を含む ARIA ツリーです。-C/--cursor は 0.22 で削除されました |
| スナップショットの差分 (0.38 以降) | agent-browser snapshot --delta | 最初にツリー全体を取得し、その後は unchanged または簡潔な構造差分を返します。参照は同一ドキュメント内の変更後も維持されます |
| セマンティックロケーター | agent-browser find role button click --name "Continue" | 構文:find <locator> <value> [action]。@eN 参照に代わる安定した方法です |
| 操作 | fill @e1 "..."、click @e2、press Enter、drag @e1 @e2、upload @e1 file.pdf | すべて ARIA 参照を使用します。--human を追加すると、瞬時に移動する代わりに、曲線を描くようにポインターを移動します |
| 待機 | wait --load networkidle、wait --text "Success"、wait --fn "window.ready" | イベント駆動で、固定時間のスリープは使用しません |
| ネットワーク | network route "*analytics*" --abort、network route "https://api/*" --body '{...}' | インターセプトとスタブ |
| 状態 | state save/load auth.json、--session-name <name> | 実行間で認証状態を保持します |
| 保管庫 | vault store github_pat、vault load github_pat | 暗号化された認証情報ストア |
| 差分 | diff snapshot、diff screenshot --baseline /tmp/x.png | 別々の実行間で ARIA とピクセルを比較します。同じページの実行内で変更前後を比較する場合は、snapshot --delta を優先してください |
| キャプチャ | screenshot --annotate、screenshot --if-changed --threshold <n> (0.38 以降)、pdf、record start/stop --fps <n> | --if-changed は、変更のないスクリーンショットの再エンコードを省略します。record のデフォルトは 30 fps です(0.37 以降) |
| ダッシュボード | agent-browser dashboard start (0.25 以降) | ブラウザー側のランタイムインスペクター(:4848) |
テスト計画を実行する
expect_task = Agent(
subagent_type="ork: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
)
# Stream agent-browser progress line-by-line instead of polling (CC 2.1.98+)
# Each stdout line from agent-browser arrives as a notification — useful for
# catching a failing step early rather than waiting for the full plan.
# Full pattern: Read("${CLAUDE_PLUGIN_ROOT}/skills/chain-patterns/references/monitor-patterns.md")
Monitor(pid=expect_task.agent_id)
# For long test plans (>3 min typical), notify on completion — requires
# Remote Control + "Push when Claude decides" config (CC 2.1.110+).
# Skip silently if the user doesn't have Remote Control enabled.
if test_plan_duration_estimate > 180:
PushNotification(
message=f"ork:expect complete — {passed}/{total} steps passed on {len(affected_urls)} pages",
status="proactive"
)
読み込み:Read("references/execution.md")
保存済みフロー
.expect/flows/ に保存されている、再利用可能なテスト手順です。
# .expect/flows/login.yaml
name: Login Flow
steps:
- navigate: /login
- fill: { selector: "#email", value: "[email protected]" }
- fill: { selector: "#password", value: "password123" }
- click: button[type="submit"]
- assert: { url: "/dashboard" }
- assert: { text: "Welcome back" }
次のコマンドで実行します:expect --flow login
フェーズ 6:レポート
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.png
読み込み:Read("references/report.md")
UI 編集後の自動トリガー(M125 #2)
開発スタックが起動中(dev)の場合、任意の .tsx、.jsx、.css、.scss ファイル(および app/**/page.tsx、pages/**/*.tsx などの Next.js ルートファイル)を保存すると、expect <route> を実行するよう促す通知が出ます。このフック(posttool/ui-change-detector)はデフォルトで有効で、次のように動作します。
devが起動していない場合(接続先の agent-browser セッションがない場合)は、何も表示せずにスキップします。- 連続保存による通知の乱発を防ぐため、ルートごとに30秒のクールダウンを適用します。
- セッションごとのオプトアウトとして
.claude/state/expect-skip.<sessionId>を使用します(任意の内容を書き込んでください)。 - 環境変数レベルのキルスイッチとして
ORK_EXPECT_AUTO=0を使用します。
ルートの解決方法:app/dashboard/page.tsx → /dashboard、pages/settings.tsx → /settings、コンポーネント/グローバルスタイルの編集 → /(ホームを代理として使用)。app/(marketing)/pricing/page.tsx などのルートグループは /pricing に変換されます。
ARIA スナップショットの記録(M125 #6)
テストに合格すると、posttool/expect/snapshot-recorder フックがキャプチャした ARIA ツリーを .claude/state/expect-snapshots/<route-slug>/<parent-commit>.json に保存します。その後の expect <route> --diff 実行では、同じルートの直近の過去スナップショットと比較します。これにより、ベースラインのスクリーンショットがなくても、構造上のリグレッション(ボタンの追加・削除、ラベルの変更、階層の変化など)が明らかになります。
スナップショットレコーダーを動作させるには、expect の実行出力に RUN_COMPLETED|passed、ROUTE|<route>、ARIA|<json-summary> のタグが含まれている必要があります。agent-browser を使ったフローでは、これらはすでに出力されます。
Jev ステップ判定(オプトイン、3つのモード)
ORK_EXPECT_JEV でモードを選択します。未設定または偽の値の場合はオフとなり、オフの場合はネットワーク通信が一切発生しません。shadow(互換性のため、真の値を持つ ORK_EXPECT_JEV_SHADOW でも選択可能)では、エージェントの選択と並行して各ステップで Jev リクエストを1回記録します。対話型 ARIA 要素から構築された、制限付きの合法アクション集合に対する Choice と、3つの verify Nouls が含まれ、確率と各ステップでの一致状況もレポートに記載されます。1 または act を設定すると、Jev の選択でステップを実行します。ただし、エラー、タイムアウト、空または不正な回答、あるいは act_confidence_floor を下回る信頼度の場合は、安全側に倒してエージェント自身の選択に切り替えます。調整可能な設定は .expect/config.yaml の jev_shadow: にあります。読み込み:Read("references/jev-shadow.md")
使用しないケース
- ユニットテスト — 代わりに
coverを使用してください - API のみの変更 — テスト対象となるブラウザー UI がありません
- 生成ファイル — ビルド成果物やロックファイルはスキップしてください
- ドキュメントのみの変更 — ドキュメントサイトのレンダリングを確認したい場合を除きます
品質基準
次のすべてを満たせば完了です。
- テスト計画の対象範囲は、選択した
--targetに対する git diff から導出されます。変更のないページが計画に含まれることはありません。 - 変更された各ファイルは、
.expect/config.yamlまたは推定された規則により、少なくとも1つのテスト対象ルートに対応付けられているか、API のみ、生成ファイル、またはドキュメントのみとして明示的に除外されています。 - フィンガープリントのチェックが最初に実行されます。前回の実行から差分がない場合は、再テストせずに実行をスキップします。
-yが渡されない限り、ブラウザー操作を実行する前に計画が提示され、レビューできる状態になります。- 実行した各ステップは、証拠(失敗時はスクリーンショット)とともに PASS または FAIL を報告し、レポートの合格・失敗件数は実際に実行したステップ数と一致します。
- いずれかのステップが失敗した場合、レポートの終了コードは 0 以外になります。
上限:合計30分以内、1ページあたり5分以内(時間がかかりすぎるページはスキップされます。references/test-plan.md を参照。デフォルト値は .expect/config.yaml で上書きできます)、executor のターンは50回(max_turns=50)、ork:expect-agent は逐次実行で1つのみ、ブラウザーの並列実行は禁止(rules/no-parallel-browsers.md)。制限時間の終了時またはいずれかの上限に達した時点の、先に到達した方で停止し、途中結果を報告します。
関連スキル
agent-browser— ブラウザー自動化エンジン(必須の依存関係)ork:cover— テストスイートの生成(ユニット/統合/E2E)ork:verify— 既存のテスト品質を評価testing-e2e— Playwright のパターンとベストプラクティス
参考資料
Read("references/<file>") を使用して、必要に応じて読み込みます。
| ファイル | 内容 |
|---|---|
fingerprint.md | SHA-256 ゲーティングロジック |
diff-scanner.md | Git diff の解析+3 段階の分類 |
route-map.md | ファイルから URL へのマッピング規則 |
test-plan.md | AI テスト計画生成用プロンプトテンプレート |
execution.md | agent-browser のオーケストレーションパターン |
report.md | レポート形式+成果物の保存 |
config-schema.md | .expect/config.yaml の完全なスキーマ |
aria-diffing.md | セマンティック差分検出のための ARIA スナップショット比較 |
scope-strategy.md | ターゲットモードごとのテスト深度戦略 |
saved-flows.md | Markdown+YAML フローフォーマット、適応型リプレイ |
rrweb-recording.md | rrweb DOM リプレイ統合 |
human-review.md | AskUserQuestion による計画レビューゲート |
ci-integration.md | GitHub Actions ワークフロー+プッシュ前フック |
research.md | millionco/expect のアーキテクチャ分析 |
jev-shadow.md | オプトインの Jev ステップ判定:ステップごとの制約付きアクション Choice+Nouls の検証。シャドーログ、act はフェイルクローズのフォールバックで駆動 |
バージョン: 1.0.0(2026 年 3 月)— 初期スキャフォールド、M99 マイルストーン