---
name: e2e-scenario-design
source: https://app.decimal.ai/s/e2e-scenario-design@1/SKILL.md
source_sha256: 2278acf093ad
---

# Design E2E scenarios as journeys, not single-screen checks

Someone asks you to design the end-to-end tests for a product or feature — "what E2E scenarios should
we run for the checkout flow," "design the end-to-end tests for our new dashboard." Left to itself,
the model produces a **flat inventory of isolated checks**: "verify the login page loads, verify the
search bar returns results, verify the settings toggle saves, verify the profile page shows the
name…" Each item exercises *one screen or one action in isolation*. That is not end-to-end testing —
it is a feature list with the word "verify" in front of each line. It re-tests what unit and
integration tests already cover, spreads effort evenly across everything, and never exercises the
thing E2E exists to catch: whether a **real user can complete a real goal** across the seams where
features hand state to each other.

The discipline: an E2E scenario is **one realistic user journey toward a goal**, built from an
ordered sequence of steps where each step depends on state the previous steps created, and it passes
only when an observable end-state proves the goal was reached. You choose the few journeys worth this
by **usage × risk**, and you spend the coverage on **critical paths** and **cross-feature flows** —
not on re-clicking every screen.

## What makes a scenario a journey (not a check)

A journey has all four of these. A single-screen check has none of them.

1. **A goal, stated as a user outcome.** "A new user gets their team into the product and sees shared
   data," not "test the signup page." The scenario is named by the outcome, not the screen.
2. **State that carries forward.** Later steps consume what earlier steps produced. Signing up creates
   the account the next step logs into; creating a project produces the project the invite step
   shares. If any step could be reordered or run alone without breaking, it is not part of a journey —
   it is an isolated check wearing a step's clothes.
3. **At least one boundary crossing** (for cross-feature journeys). The journey passes state from one
   feature or service to another — signup → billing, upload → processing → notification, order →
   fulfillment → email. These handoff seams are exactly what unit and integration tests each miss,
   because each side is tested against a stub of the other.
4. **An observable end-state assertion.** The journey succeeds only if a concrete, user-visible result
   confirms the goal: the teammate sees the shared project, the confirmation email arrives, the
   dashboard reflects the new data. "No errors were thrown" is not an end-state.

## Selecting which journeys to test: usage × risk

You cannot E2E everything — these tests are slow and brittle, so a handful of deep journeys beats
dozens of shallow ones. Choose deliberately:

1. **Enumerate candidate journeys** — the distinct real goals a user comes to accomplish (sign up and
   onboard, complete a purchase, recover a lost password, export a report, invite a collaborator).
2. **Score each on two axes:**
   - **Usage** (High / Med / Low) — how many real users walk this path, how often. The paths almost
     everyone hits are the ones a break hurts most broadly.
   - **Risk** (High / Med / Low) — how likely a break is and how costly when it happens (money,
     data loss, lockout, security). Payment and auth journeys sit high even at lower usage.
3. **Pick the top band and cap the count.** Cover **usage-High × risk-High critical paths first**,
   then the **cross-feature handoff journeys** (where features exchange state — the seams), then a
   small number of high-value **alternate/recovery journeys** (the path when something goes wrong: a
   declined card, a conflict on sync). A realistic set is a *handful* of deep journeys, not an
   exhaustive matrix — say which you are deliberately not covering at this level.

The rule of thumb: **usage tells you what to cover, risk tells you how deep, and the cross-feature
seams are where you look first** because no lower-level test sees both sides at once.

## Push down — don't rebuild lower levels as E2E

E2E is the wrong level for exhaustive input coverage. Field-by-field validation, every error branch
for one input, and isolated component behavior belong at the **unit / integration** level, where they
run in milliseconds and pin the failure precisely. An E2E scenario should include an alternate path
only when the *journey itself* changes (a declined payment routes the user somewhere new) — not to
enumerate the fifteen ways one form field can be invalid. If a bug can be caught one level down, catch
it there and keep the journey focused on the integrated flow.

## Each scenario spec carries

For every journey you select, write it as:

- **Goal** — the user outcome in one line.
- **Persona / preconditions** — who, and what state must already exist (a seeded account, an empty
  cart).
- **Steps** — the ordered sequence, each depending on prior state, with the **realistic data** it
  carries (a real product added, a real address entered) rather than placeholder values.
- **Boundaries crossed** — which features/services hand off state along the way.
- **End-state assertion** — the observable result that proves the goal was met.

## Example

**Request:** "Design the end-to-end scenarios for our store's new guest-checkout feature."

A single-screen inventory would list: "test the cart page, test the address form, test the card form,
test the confirmation page." Instead, journeys selected by usage × risk:

- **Critical path — usage High × risk High:** *Guest completes a purchase.*
  Preconditions: catalog seeded, no account. Steps: browse → add a specific in-stock item to cart →
  enter a valid shipping address → pay with a valid test card → land on confirmation. Boundaries:
  cart → payment gateway → order service → email. End-state: order appears in the order store **and**
  a confirmation email is captured. This is the journey almost every user takes and the one where a
  break costs money.
- **Alternate/recovery — usage Med × risk High:** *Declined card recovers.* Same path, but the card
  is declined; the user sees a clear error, corrects to a valid card, and completes. End-state: order
  succeeds on the second attempt, no duplicate charge. Included because the *journey branches*, not to
  enumerate card errors.
- **Cross-feature seam — usage Med × risk Med:** *Guest checkout offers account creation post-purchase*
  and the created account shows the just-placed order. Boundary: guest order → account creation →
  order-history. End-state: the new account's history lists the order.
- **Deliberately out of scope at E2E:** every address-field validation rule and every card-format
  error — pushed down to integration/unit tests on the address and payment validators; catalog
  browsing/filtering — its own journey, not this feature.

Three or four deep journeys that each cross real seams beat twenty screen-by-screen checks.
