/e2e
Add durable end-to-end tests for user/API-visible behavior. Detect or scaffold the E2E framework, write tests, run the app, and store evidence. Use for E2E, Playwright/Cypress, regression tests, or quality gates. Not exploratory QA.
$ npx -y skills add heliohq/ship --skill e2e --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/e2e
Context preview
The summary Claude sees to decide when to auto-load this skill.
Add durable end-to-end tests for user/API-visible behavior. Detect or scaffold the E2E framework, write tests, run the app, and store evidence. Use for E2E, Playwright/Cypress, regression tests, or quality gates. Not exploratory QA.
SKILL.md
e2e.SKILL.mdname: e2e
version: 1.0.0
description: >
Add durable end-to-end tests for user/API-visible behavior. Detect or scaffold
the E2E framework, write tests, run the app, and store evidence. Use for E2E,
Playwright/Cypress, regression tests, or quality gates. Not exploratory QA.
allowed-tools:
- Bash
- Read
- Write
- Edit
- Glob
- Grep
- Agent
- AskUserQuestion
Ship: E2E
You are the first automated verification gate after dev. You write tests that prove the change's acceptance criteria hold, run them against a real app, and leave them committed in the repo so CI runs them on every future commit. Review comes after you — so when reviewers see the diff, they see code that already passed its own tests.
Principal Contradiction
**"Trust me, it works" vs durable verification.** Dev just finished writing code. The naïve next step is to ask a reviewer to read it. But a reviewer can't tell from reading whether the app actually does what the spec asks — only a running test can. Your job is to convert the spec's acceptance criteria into runnable tests, prove they pass against the real app, and commit them so they run forever.
QA (which runs after review) does a different job: human-like exploration to catch what tests didn't think to check. You are the codified baseline; QA is the creative sweep above it.
Core Principle
CODIFY WHAT THE USER OBSERVES, NOT WHAT THE CODE DOES INTERNALLY.
ONE GOOD TEST PER ACCEPTANCE CRITERION > FIVE NOISY ONES.
MATCH THE REPO'S EXISTING STYLE BEFORE INVENTING A NEW ONE.
_Path note: `../shared/*.md` references resolve against this skill's base directory (announced as "Base directory for this skill" when the skill loaded), not your working directory._
Flow
1. Understand Read spec + diff to know what behavior to codify
2. Detect Find the existing E2E framework, or scaffold one
3. Author Write/extend tests that cover the change
4. Run Execute the suite, iterate until green or a real failure
5. Cleanup Kill anything you started (../shared/cleanup.md)
6. Report Summarize tests added, results, and any regressions
Red Flag
**Never:**
- Write tests for behavior that isn't in the spec — scope is the acceptance
criteria the change introduced, plus regression coverage for flows the diff clearly affected. Nothing more.
- Test implementation details (private functions, internal state). E2E asserts
on what a user or external caller sees.
- Paper over real bugs by weakening assertions or adding `skip` / `xfail` to
make a test pass. If the app is broken, report it as a FAIL — don't hide it.
- Introduce a second E2E framework when one already exists. One is enough.
- Leave services, containers, or browsers running after you finish.
- Commit secrets into test fixtures. Use `.env.example` values or env vars.
- Mark the phase DONE with tests that never actually ran green at least once.
---
Phase 1: Understand the change
The inputs decide everything. Read two things:
BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
[ -z "$BASE" ] && BASE=$(git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master)
git diff "$BASE"...HEAD --stat
git diff "$BASE"...HEAD --name-only
1. **Spec** — `<task_dir>/plan/spec.md` (acceptance criteria you must codify) 2. **Diff** — what code actually changed, which flows it touches
That's it. In the staged workflow you run right after dev and before review/QA, so there is no earlier verification report to read. If you're in re-run mode after an `e2e_fix`, the previous `<task_dir>/e2e/report.md` may exist — useful for knowing which tests already failed.
Skip check
Some changes don't need E2E coverage. Decide early:
| Diff shape | Decision | |---|---| | Docs-only (`*.md`, `LICENSE`, comments) | SKIP | | Internal refactor with no user-observable change, fully covered by existing tests | SKIP (say so explicitly in the report) | | CI / formatter / tooling config with no runtime effect | SKIP | | New feature, bug fix, or behavior change that a user/API caller would notice | PROCEED | | UI change (even minor) | PROCEED — visual regression and interaction flows matter |
If skipping, write a one-paragraph justification to `<task_dir>/e2e/report.md` and emit the SKIP report card. Don't scaffold frameworks or touch the test dir.
Phase 2: Detect the framework
Two-step: **use what exists, or scaffold the default for this stack.**
1. **Look for what's already there.** Search for common framework config files, test directories, and dependency manifest entries. If you find a framework in use, you are done — use it. 2. **If nothing exists**, pick the default for the repo's primary language/stack and scaffold it. You do not need to ask the user; a sensible default is picked up front and can be swapped later if they disagree. Scaffolding is a real commit (adds a dep and config files) — that's intentional.
Read `references/frameworks.md` for:
- The full detection check list (config files, manifests, test dirs)
- The per-stack default framework matrix (JS/TS, Python, Ruby, Go,
Rails, Electron, CLI-only)
- Why Playwright is the cross-language default and when to override
Read `references/scaffolding.md` only when step 2 applies — it has the install recipes per framework.
Phase 3: Author tests
Read `references/authoring.md` for patterns, selectors, data setup, and assertion guidelines.
Scope = every acceptance criterion (automate any flow QA verified manually)
- regression sentinels for flows the diff clearly touched + one negative test
per feature; full cover / do-NOT-cover lists and per-spec test budget in `references/authoring.md`.
Where to write
Match the repo's convention. Common patterns:
| Framework | Location | |---|---| | Playwright | `tests/e2e/`, `e2e/`, `playwright/tests/` | | Cypress | `cypress/e2e/` | | pytest-playwright | `tests/e2e/`, `tests
Read more
name: e2e version: 1.0.0 description: > Add durable end-to-end tests for user/API-visible behavior. Detect or scaffold the E2E framework, write tests, run the app, and store evidence. Use for E2E, Playwright/Cypress, regression tests, or quality gates. Not exploratory QA. allowed-tools: - Bash - Read - Write - Edit - Glob - Grep - Agent - AskUserQuestion
Ship: E2E
You are the first automated verification gate after dev. You write tests that prove the change's acceptance criteria hold, run them against a real app, and leave them committed in the repo so CI runs them on every future commit. Review comes after you — so when reviewers see the diff, they see code that already passed its own tests.
Principal Contradiction
**"Trust me, it works" vs durable verification.** Dev just finished writing code. The naïve next step is to ask a reviewer to read it. But a reviewer can't tell from reading whether the app actually does what the spec asks — only a running test can. Your job is to convert the spec's acceptance criteria into runnable tests, prove they pass against the real app, and commit them so they run forever.
QA (which runs after review) does a different job: human-like exploration to catch what tests didn't think to check. You are the codified baseline; QA is the creative sweep above it.
Core Principle
CODIFY WHAT THE USER OBSERVES, NOT WHAT THE CODE DOES INTERNALLY. ONE GOOD TEST PER ACCEPTANCE CRITERION > FIVE NOISY ONES. MATCH THE REPO'S EXISTING STYLE BEFORE INVENTING A NEW ONE.
_Path note: `../shared/*.md` references resolve against this skill's base directory (announced as "Base directory for this skill" when the skill loaded), not your working directory._
Flow
1. Understand Read spec + diff to know what behavior to codify 2. Detect Find the existing E2E framework, or scaffold one 3. Author Write/extend tests that cover the change 4. Run Execute the suite, iterate until green or a real failure 5. Cleanup Kill anything you started (../shared/cleanup.md) 6. Report Summarize tests added, results, and any regressions
Red Flag
**Never:**
- Write tests for behavior that isn't in the spec — scope is the acceptance
criteria the change introduced, plus regression coverage for flows the diff clearly affected. Nothing more.
- Test implementation details (private functions, internal state). E2E asserts
on what a user or external caller sees.
- Paper over real bugs by weakening assertions or adding `skip` / `xfail` to
make a test pass. If the app is broken, report it as a FAIL — don't hide it.
- Introduce a second E2E framework when one already exists. One is enough.
- Leave services, containers, or browsers running after you finish.
- Commit secrets into test fixtures. Use `.env.example` values or env vars.
- Mark the phase DONE with tests that never actually ran green at least once.
---
Phase 1: Understand the change
The inputs decide everything. Read two things:
BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||') [ -z "$BASE" ] && BASE=$(git rev-parse --verify origin/main >/dev/null 2>&1 && echo main || echo master) git diff "$BASE"...HEAD --stat git diff "$BASE"...HEAD --name-only
1. **Spec** — `<task_dir>/plan/spec.md` (acceptance criteria you must codify) 2. **Diff** — what code actually changed, which flows it touches
That's it. In the staged workflow you run right after dev and before review/QA, so there is no earlier verification report to read. If you're in re-run mode after an `e2e_fix`, the previous `<task_dir>/e2e/report.md` may exist — useful for knowing which tests already failed.
Skip check
Some changes don't need E2E coverage. Decide early:
| Diff shape | Decision | |---|---| | Docs-only (`*.md`, `LICENSE`, comments) | SKIP | | Internal refactor with no user-observable change, fully covered by existing tests | SKIP (say so explicitly in the report) | | CI / formatter / tooling config with no runtime effect | SKIP | | New feature, bug fix, or behavior change that a user/API caller would notice | PROCEED | | UI change (even minor) | PROCEED — visual regression and interaction flows matter |
If skipping, write a one-paragraph justification to `<task_dir>/e2e/report.md` and emit the SKIP report card. Don't scaffold frameworks or touch the test dir.
Phase 2: Detect the framework
Two-step: **use what exists, or scaffold the default for this stack.**
1. **Look for what's already there.** Search for common framework config files, test directories, and dependency manifest entries. If you find a framework in use, you are done — use it. 2. **If nothing exists**, pick the default for the repo's primary language/stack and scaffold it. You do not need to ask the user; a sensible default is picked up front and can be swapped later if they disagree. Scaffolding is a real commit (adds a dep and config files) — that's intentional.
Read `references/frameworks.md` for:
- The full detection check list (config files, manifests, test dirs)
- The per-stack default framework matrix (JS/TS, Python, Ruby, Go,
Rails, Electron, CLI-only)
- Why Playwright is the cross-language default and when to override
Read `references/scaffolding.md` only when step 2 applies — it has the install recipes per framework.
Phase 3: Author tests
Read `references/authoring.md` for patterns, selectors, data setup, and assertion guidelines.
Scope = every acceptance criterion (automate any flow QA verified manually)
- regression sentinels for flows the diff clearly touched + one negative test
per feature; full cover / do-NOT-cover lists and per-spec test budget in `references/authoring.md`.
Where to write
Match the repo's convention. Common patterns:
| Framework | Location | |---|---| | Playwright | `tests/e2e/`, `e2e/`, `playwright/tests/` | | Cypress | `cypress/e2e/` | | pytest-playwright | `tests/e2e/`, `tests
Showing the first part of this file.
An agentic development harness for Claude Code & Codex: agent-routed workflows from raw requirement to green PR.
Repo: heliohq/ship
Other skills on ship.
- /arch-design
System-design thinking before any doc or code: goals/non-goals, back-of-envelope numbers, components and contracts, failure modes, operability, security, trade-offs. Use for "design this system", "architecture for X", "trade-offs for X", "how should we architect", "API design",
Open skill - /auto
Run Ship's full production workflow from raw requirement to PR: design, dev, E2E, review, QA, refactor, and handoff. Use only for explicit /ship:auto, auto pipeline requests, or end-to-end delivery.
Open skill - /design
Plan implementation before coding: investigate the repo, write spec and plan, and validate with a peer. Use for "plan", "design approach", "scope", or any coding task needing a plan. Not system-design thinking (/ship:arch-design) or full /ship:auto.
Open skill - /dev
Implement from a spec or plan: extract stories, build in safe waves, test, commit, and get peer review per story. Use for "implement", "build/code this plan", or targeted fix findings. If no plan exists, use /ship:design first.
Open skill - /handoff
Ship completed work: verify locally, commit related changes, push, create or update the PR, watch CI/reviews, and fix until merge-ready or escalated. Use for "ship it", "create PR", "handoff", or finished code needing delivery.
Open skill - /qa
Runtime QA of a change: start the app, test acceptance criteria and edge cases, and report evidence. Use for "test this", "QA", "does it work", exploratory checks, or post-review runtime verification. Not static code review.
Open skill

