From e2e-pipeline
Use when generating E2E test flows from plans, specs, or PRs, verifying flows in browser or CLI, running smoke tests across all mapped pages, or recording backend/API verification with asciinema. Supports browser UI flows, CLI-only flows (Execute external), and mixed flows. Triggers on "e2e flow", "generate flow", "create flow", "verify flow", "draft flow", "smoke test", "e2e smoke", "write a flow", "produce flow", "validate flow", "flow from plan", "cli flow", "backend e2e", "api test flow", "cli recording".
How this skill is triggered — by the user, by Claude, or both
Slash command
/e2e-pipeline:e2e-flowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate and verify E2E flows — browser UI, CLI commands, or API checkpoints. Combines autonomous flow generation (codebase analysis, no browser) with adaptive verification: browser flows use auto-repair, CLI-only flows use asciinema recording.
Generate and verify E2E flows — browser UI, CLI commands, or API checkpoints. Combines autonomous flow generation (codebase analysis, no browser) with adaptive verification: browser flows use auto-repair, CLI-only flows use asciinema recording.
/e2e-map → mapping.yaml (map UI elements)
/e2e-flow → flow.yaml + report (generate & verify)
/e2e-test → report.md (replay automated)
/e2e-walkthrough → flow.yaml (explore interactively)
/e2e-flow [--from <source>] [--smoke] [--verify-only] [--mapping <name>] [--issue ID] [--no-verify] [--no-video] [--no-pr] [--no-teams]
| Arg | Effect |
|---|---|
| (no args) | Generate from current conversation context |
--from <file> | Read a plan file, spec, or requirements doc |
--from pr <N> | Read PR diff via gh pr diff |
--smoke | Generate visit-all-pages flow from mapping |
--verify-only | Skip generation, verify an existing flow in browser |
--mapping <name> | Target a specific mapping (skip selection if only one) |
--issue ID | Include issue context in report header |
--no-verify | Generate flow only, skip browser verification |
--no-video | Skip video recording during verification |
--no-pr | Skip PR auto-detection, commit, and PR comment posting |
--no-teams | Force subagent mode even when Agent Teams is available |
PR mode is enabled by default. On invocation, auto-detect the current branch's PR:
gh pr view --json number,headRefName --jq '.number' 2>/dev/null
gh unavailable → PR mode silently skipped (no error).--no-pr → PR mode explicitly disabled regardless of PR existence.Read accumulated patterns to inform flow generation and verification:
Read → ${CLAUDE_PLUGIN_ROOT}/references/learned-patterns.md
Use loaded patterns to:
.claude/e2e/mappings/*.yamlapp, base_url, auth from the mapping. Set flow_mode: browser.--mapping → list them (show filename, app, base_url), ask user which to use. Set flow_mode: browser.--from file content) for CLI signals: shell commands (curl, psql, npm run, bun, script paths), API endpoint testing, database queries, migration scripts, Execute external mentionsflow_mode: cli-only. Inform user: "No mapping found. Detected CLI/backend intent — generating CLI-only flow (Execute external / Verify external steps only)."/e2e-map first."--smoke mode → stop: "Smoke mode requires a mapping. Run /e2e-map first." (smoke is inherently browser-based)From file (--from <file>):
From PR (--from pr N):
gh pr diff <N> + gh pr view <N> --json title,bodyFrom conversation (no args):
Smoke mode (--smoke): Skip source parsing. Mapping provides everything needed.
Verify-only (--verify-only):
.claude/e2e/flows/Execute external or Verify external → set flow_mode: cli-only (skip browser verifier, go to Phase 2.5 CLI recording). Otherwise → flow_mode: browser.For non-smoke, non-verify-only invocations, scan the codebase to build a context_summary for the flow-writer agent. See reference.md § Codebase Scan Strategy for exact patterns.
Summary: Identify routes → component files → form fields → API endpoints → external service integrations → assemble into context_summary text block. Also scan for external service integrations (PostHog, Langfuse, Sentry, webhooks) — see reference.md § External Service Discovery. Include matches in the context_summary under "External services detected".
Cap: Max 20 file reads during scan. Prioritize files matching affected pages.
Before dispatching agents, present what will happen:
Flow generation plan:
Source: <PR #940 / plan file / conversation>
Mapping: <app-name> (<N> pages, <M> elements)
Criteria: <N> acceptance items extracted
External: <N> service integrations detected
Estimated steps: ~<N>
Proceed? (y / adjust)
A PreToolUse hook blocks direct writes to .claude/e2e/flows/*.yaml. The /e2e-flow skill must create a sentinel file to authorize its agents (flow-writer, flow-verifier) to write flow YAML.
Protocol:
.claude/e2e/.flow-write-authorized (content: current unix timestamp) before dispatching the first flow-writing agent.claude/e2e/.flow-write-authorized after the last flow-writing agent returnsPer mode:
--no-verify: create before Phase 1 → delete after Phase 1--verify-only: create before Phase 2b → delete after Phase 2dThe sentinel has a 10-minute staleness timeout as safety net — enforced by the PreToolUse hook. If the sentinel's timestamp is older than 10 minutes, the hook treats it as absent (stale sentinel = no authorization). This covers skill crashes where the sentinel is never explicitly deleted.
Detection logic: see
references/agent-teams.md§ 1
--no-teams not set AND flow_mode: browser (CLI-only flows don't need Teams)--no-teams set OR flow_mode: cli-onlyShared protocol:
references/agent-teams.md§ 2-3
When Teams mode is active AND --no-verify is NOT set, spawn the verifier teammate BEFORE dispatching the writer. This overlaps browser startup with flow generation.
TeamCreate(team_name="e2e-flow", description="Flow generation + verification")
Agent(
team_name="e2e-flow",
name="verifier",
subagent_type="e2e-pipeline:e2e-flow-verifier",
prompt="TEAMS MODE. Pre-warm: open browser at <base_url> with auth profile <auth_profile>.
App: <app>. Report dir: <report_dir>.
After browser is ready, send BROWSER_READY and wait for VERIFY_FLOW command."
)
Verifier opens browser in parallel while the writer generates the flow. By the time the writer returns, the verifier's browser is already warm.
If TeamCreate or Agent spawn fails: see references/agent-teams.md § 4. Clean up partial state, fall back to subagent mode for Phase 2.
If --no-verify: skip verifier spawn (no browser needed).
After the flow-writer subagent returns, verify the pre-warmed verifier is still alive before proceeding to Phase 2:
~/.claude/teams/e2e-flow/config.json — verifier member still present?TeamDelete(), fall back to subagent mode for Phase 2BROWSER_READY during writer execution: proceed to Phase 2b directlyBROWSER_READY yet: wait up to 30s. No response → treat as crash (step 2)→ Create flow-write sentinel (see § Flow Write Authorization)
Dispatch e2e-pipeline:e2e-flow-writer (always as subagent — no browser, read-only, benefits from blocking return) with:
description: Extracted criteria or feature descriptionmapping_path: Absolute path to mapping YAML (omit if flow_mode: cli-only)context_summary: Assembled codebase scan resultsoutput_dir: .claude/e2e/flows/ absolute pathsource_text: Full plan/spec/PR diff text (if --from used)smoke_mode: true if --smokeflow_name: User-specified or auto-generatedcli_only: true if flow_mode: cli-onlySee reference.md § Agent Dispatch Patterns for exact dispatch message format.
On return: Read the generated flow YAML.
Post-generation validation:
flow_mode: browser: verify the flow's mapping: field matches the app value from the loaded mapping. If mismatch → treat as generation error (same cleanup path as invalid YAML below).flow_mode: cli-only: verify ALL steps use action: "Execute external" or action: "Verify external" only. If any step has a browser action (Click, Navigate, Type, etc.) → treat as generation error. A CLI-only flow with browser steps is invalid — the writer was given cli_only: true but produced mixed output.Present summary to user:
Flow generated: .claude/e2e/flows/<name>.yaml
Mode: <browser | cli-only>
Steps: N
Warnings: <count or "none">
Coverage: <notes>
{if browser} Proceeding to browser verification...
{if cli-only} Proceeding to CLI recording...
If --no-verify → delete flow-write sentinel → if PR mode active, commit flow (git add .claude/e2e/flows/<name>.yaml && git commit -m "test(e2e): add <flow-name> flow (unverified)") → skip to Phase 3 (no-verify path).
If flow-writer fails or returns invalid YAML:
TeamDelete() (see references/agent-teams.md § 2 Teardown)CLI-only flows (flow_mode: cli-only): Skip Phase 2a-2d entirely. Jump directly to Phase 2.5 (CLI recording). Browser verifier is not dispatched — there are no browser steps to verify.
agent-browser --version
curl -s -o /dev/null -w "%{http_code}" <base_url>
ls ~/.agent-browser/<app>/ 2>/dev/null
Dev server must be running. Auth profile should exist (run /e2e-map or /e2e-walkthrough first to create one).
Teams mode: pre-flight already passed during Phase 1 pre-warm. If verifier sent BROWSER_READY, skip pre-flight.
→ If --verify-only, create flow-write sentinel now (see § Flow Write Authorization)
Teams mode (verifier already spawned and browser ready):
Step 0 — Liveness re-check (before sending any command): Verify the verifier member still exists in ~/.claude/teams/e2e-flow/config.json. If the verifier disappeared between BROWSER_READY and now (e.g., crashed while idle), fall back to subagent mode immediately — do NOT send VERIFY_FLOW to a dead teammate.
Step 1 — Send VERIFY_FLOW:
SendMessage(
to="verifier",
message="VERIFY_FLOW\nflow_path: <path>\nmapping_path: <path>\nbase_url: <url>\nauth_profile: <path>\nrecord: <bool>",
summary="Verify flow: <flow-name>"
)
Step 2 — Wait for ROUND_1_STATUS (verifier sends after Round 1 completes):
Parse the status field: all_pass, has_corrections, has_unfixable. Also parse corrections count, unfixable count, and per-step details.
Step 3 — Present Round 1 summary to user:
Round 1 complete:
Status: <all_pass | has_corrections | has_unfixable>
Corrections: N (R repair, A adapt, E enrich)
Unfixable: N
{if corrections} Details: <top 3 corrections> {endif}
Step 4 — Decide and send guidance:
| Round 1 status | Guidance | Rationale |
|---|---|---|
all_pass (0 corrections, 0 unfixable) | SKIP_ROUND_2 | Round 1 is already clean evidence |
has_corrections (corrections > 0, unfixable == 0) | PROCEED_ROUND_2 | Need clean evidence without repair noise |
has_unfixable (unfixable > 0) | SKIP_ROUND_2 | Unfixable issues mean Round 2 would also fail at the same spots |
SendMessage(
to="verifier",
message="<PROCEED_ROUND_2 | SKIP_ROUND_2>",
summary="Round 2: <proceed | skip>"
)
Step 5 — Wait for VERIFICATION COMPLETE containing final results (report path, trace path, corrections, status).
Timeout/crash handling: If no ROUND_1_STATUS within 120s, or no VERIFICATION COMPLETE within 120s after sending guidance:
TeamDelete() to clean up the team--no-teams:
E2E Flow: <flow-name>
Status: ERROR (verifier crash/timeout)
Flow: .claude/e2e/flows/<name>.yaml (generated, unverified)
Suggestion: Re-run `/e2e-flow --verify-only <flow-name> --no-teams`
The generated flow YAML is kept on disk — it may be valid and only needs re-verification.For --verify-only with existing team: detect existing team (references/agent-teams.md § 2). If verifier alive → check if the new flow's base_url and auth_profile match the verifier's current session. If they differ, include base_url and auth_profile in the VERIFY_FLOW command so the verifier can close and reopen the browser (see references/agent-teams.md § 5 — Browser state isolation on reuse). If same → send VERIFY_FLOW directly (no browser restart). Sentinel: create flow-write sentinel BEFORE sending VERIFY_FLOW to the existing verifier (same as new-verifier path).
Subagent mode (original behavior):
Dispatch e2e-pipeline:e2e-flow-verifier with:
flow_path: Path to generated (or existing) flow YAMLmapping_path: Path to mapping YAMLauth_profile: ~/.agent-browser/<app>/base_url: From mappingapp: From mappingreport_dir: .claude/e2e/reports/<timestamp>/record: true (unless --no-video)See reference.md § Agent Dispatch Patterns for exact format.
After verifier returns, if trace_path is present:
Dispatch e2e-pipeline:e2e-trace-analyzer with:
trace_path: From verifier outputreport_dir: Same as verifierstep_log_path: From verifier output (if present)Merge verifier output + trace analysis:
If verifier applied corrections (flow_updated: true or mapping_updated: true), present a correction diff summary before the full report:
Verifier corrections:
Corrected N selectors, inserted M steps, enriched K assertions
Flow updated: .claude/e2e/flows/<name>.yaml
Mapping updated: .claude/e2e/mappings/<app>.yaml
After verifier and trace-analyzer return, dispatch media processing.
Detect flow type: Parse the flow YAML steps. If ALL steps use action: "Execute external" or action: "Verify external" (zero browser steps), this is a CLI-only flow.
Browser flow (has browser steps):
Agent(subagent_type="e2e-pipeline:e2e-media-processor"):
"Process media:
report_dir: <report_dir>
output_name: verification"
CLI-only flow (no browser steps):
command -v asciinema && command -v agg. If missing → warn, skip recording.Execute external command):
asciinema rec --cols 120 --rows 35 \
-c "<primary execute command>" "$REPORT_DIR/recording.cast"
Agent(subagent_type="e2e-pipeline:e2e-media-processor"):
"Process media:
report_dir: <report_dir>
cast_path: <report_dir>/recording.cast
output_name: verification"
Agent returns: gif_path, mp4_path, thumbnail_path. Use these in Phase 3 results.
→ Delete flow-write sentinel (all flow-writing agents have returned)
Teams mode: Teardown verifier — After media processing, shutdown the verifier teammate and delete team (references/agent-teams.md § 2). For --verify-only re-runs, keep verifier alive (user may re-verify).
Skip entirely when --no-pr is set or no PR was detected in the auto-detection step.
When PR mode is active (PR detected and --no-pr not set), commit the finalized flow YAML:
git add .claude/e2e/flows/<name>.yaml
git commit -m "test(e2e): add <flow-name> flow"
Timing matters: commit AFTER verification corrections are applied — the committed flow is the verified version, not the raw generation output. If verification updated the mapping too, include it:
git add .claude/e2e/flows/<name>.yaml .claude/e2e/mappings/<app>.yaml
git commit -m "test(e2e): add <flow-name> flow (verified)"
For --verify-only mode, only commit if the verifier made corrections (flow_updated: true):
git add .claude/e2e/flows/<name>.yaml
git commit -m "fix(e2e): update <flow-name> flow (re-verified)"
E2E Flow: <flow-name>
Status: <PASS ✅ | PARTIAL ⚠️ | FAIL ❌>
─────────────────────────────
Steps: N (M original + K inserted)
Corrections: N (R repair, A adapt, E enrich)
Unfixable: N
Checkpoints: N pass, M fail, K skip
Trace: N API failures, M console errors
─────────────────────────────
Flow: .claude/e2e/flows/<name>.yaml
Report: .claude/e2e/reports/<ts>/report.md
Video: .claude/e2e/reports/<ts>/verification.mp4
{if corrections}
Corrections applied:
- step-3: selector repair (add_btn → add_connection_button)
- step-3.1: [auto-inserted] confirmation dialog
{endif}
{if unfixable}
Unfixable issues:
- step-7: Element not found (export feature not implemented?)
{endif}
{if checkpoint_results}
Checkpoint results:
- trigger-sessions: PASS (cli: recce-cloud run ×3, exit 0)
- verify-posthog: SKIP (POSTHOG_API_KEY not set)
{endif}
When PR mode is active, post results to the PR. Ask user to confirm, then:
Upload media to draft release (private repos — raw.githubusercontent.com returns 403):
# Create a draft release for E2E assets (reuse if tag exists)
gh release create e2e-assets-<branch> --draft --title "E2E assets (<branch>)" --notes ""
# Upload screenshots and video
gh release upload e2e-assets-<branch> .claude/e2e/reports/<ts>/*.png .claude/e2e/reports/<ts>/*.mp4 --clobber
Asset URLs: https://github.com/<owner>/<repo>/releases/download/e2e-assets-<branch>/<filename>
Update pr-summary.md: Replace relative image paths with release asset URLs.
Post to PR: gh pr comment <N> --body-file .claude/e2e/reports/<ts>/pr-summary.md
Why draft release? GitHub CLI has no API for uploading images to PR comments (cli/cli#1895). Draft releases are the only CLI-friendly method that produces stable, repo-scoped URLs for images and videos. The draft release is visible in the Releases page but does not create a real release.
⚠️ Auth context matters: Draft release asset URLs require GitHub authentication. They work in PR comments (reader is logged in) but fail in Slack and other external services (unfurler has no auth → 403). For Slack announcements, link to the PR comment URL instead of embedding image URLs directly. See kc-pr-announce skill for the correct Slack media strategy.
After verification (normal path):
Next steps:
- `/e2e-test <flow-name>` — replay this flow automatically
- `/e2e-test <flow-name> --video` — replay with recording
- `/e2e-compile <flow-name>` — compile to standalone bash script for CI
{if corrections}
- `/e2e-flow --verify-only <flow-name>` — re-verify after fixing issues
{endif}
{if unfixable}
- `/e2e-map --page <page>` — re-scan pages with missing elements
{endif}
- `/e2e-walkthrough` — explore interactively
After --no-verify (generation only):
When Phase 2 is skipped, present the flow-writer output summary + next steps:
Flow generated: .claude/e2e/flows/<name>.yaml
Steps: N
Warnings: <count or "none">
Coverage: <notes>
Next steps:
- `/e2e-flow --verify-only <flow-name>` — verify in browser with auto-repair
- `/e2e-test <flow-name> --video` — replay with recording
- `/e2e-compile <flow-name>` — compile to standalone bash script
After presenting results, evaluate findings for skill-level knowledge capture.
Read → ${CLAUDE_PLUGIN_ROOT}/references/knowledge-capture.md
Scan generation + verification results for general patterns:
Auto-append to ${CLAUDE_PLUGIN_ROOT}/references/learned-patterns.md. Notify: "Appended pattern: [title]"
--no-verify with zero warnings → skip (generation-only, no feedback signal)| Mistake | Fix |
|---|---|
| Running verify without dev server | Pre-flight checks catch this — but verify base_url is accessible |
| Element names not matching mapping | Flow-writer validates against mapping. Manual edits can drift — re-run /e2e-flow |
| Smoke test on app with dynamic URLs | Smoke auto-skips pages with ${id} parameters. This is correct behavior, not a bug. |
| Skipping trace analysis | Always dispatch trace-analyzer after verifier — even on PASS. Silent API failures are invisible otherwise. |
| Re-dispatching verifier for minor fixes | Verifier does its own repair loop (2 rounds max). If it returns PARTIAL, the remaining issues are genuinely unfixable by automation. |
| Generating browser flow without mapping | Mapping must exist for browser steps. /e2e-map before /e2e-flow. CLI-only flows (all Execute/Verify external) do NOT need mapping. |
| Sending CLI-only flow to browser verifier | CLI-only flows skip Phase 2a-2d entirely. Go directly to Phase 2.5 CLI recording. |
| Adding browser steps to CLI-only flow | CLI-only mode generates ONLY Execute external / Verify external. If browser steps are needed, mapping is required — re-run with /e2e-map first. |
| Bypassing flow-writer for cross-boundary flows | Always dispatch flow-writer — it supports Execute external and Verify external steps for non-browser actions (CLI, API, analytics). Runner limits ≠ writer limits. Never hand-write flows to avoid the agent. |
| Duplicate D1 entry | Search learned-patterns.md before appending |
| Sending VERIFY_FLOW to dead verifier | Always re-check config.json for verifier presence immediately before sending VERIFY_FLOW — a verifier can crash between BROWSER_READY and the next command |
| Deleting unverified flow after crash | Keep the generated flow YAML — it may be valid. Suggest --verify-only --no-teams to re-verify. |
npx claudepluginhub iamcxa/kc-claude-plugins --plugin e2e-pipelineExecutes end-to-end user flow tests using Playwright MCP from tests/e2e-test-plan.md. Verifies multi-step journeys, state persistence, error handling in auth, business, and admin flows.
Generates page objects and test infrastructure for Playwright, Cypress, or Selenium E2E tests. Covers critical-path test implementation and flakiness remediation.
Verifies frontend changes against spec acceptance criteria using Playwright MCP for browser automation. Automates spec intake, dev server/auth checks, and test runs.