Scenario design
Each journey drawn as a graph, and the path every Gherkin scenario walks on it. Kept as code in designs/, beside features/.
A test design maps every state a user, an order or a file can go through, and the transitions between them, before or beside the scenarios. Each scenario is then a path on the map. Plain grey transitions are walked by at least one scenario, dashed red ones by none: the gaps to discuss with the product owner. Clicking a scenario highlights its path in blue; Run runs it on the stack through the Gherkin runner.
Shapes: blue stadium, where a journey starts; hexagon, a check; white box, a state; green, a good outcome; red, a refusal or a failure.
Checkout, an order from placed to paid
The order workflow as a journey: the API checks the customer and accepts the order at once, then the worker runs one step per event. The red dashed transitions have no scenario yet: a payment the provider refuses, a worker that dies in the middle of a step and gets the event again.
flowchart TD
order(["Order sent by the storefront"]):::start
customer{{"Active customer and known product?"}}:::check
refused(["Refused 404 nothing written"]):::failure
accepted["Accepted 202 order pending"]:::state
stock{{"Enough stock? reserve_stock"}}:::check
cancelled(["Order cancelled no payment"]):::failure
invoice["Invoice issued"]:::state
payment{{"Payment captured?"}}:::check
paid(["Order paid"]):::outcome
payment_failed(["Payment failed order unpaid"]):::failure
redelivered["Worker restarted event delivered again"]:::state
order -->|"POST /api/orders"| customer
customer -->|"no"| refused
customer -->|"yes"| accepted
accepted -->|"reserve_stock event"| stock
stock -->|"no"| cancelled
stock -->|"yes then issue_invoice event"| invoice
invoice -->|"capture_payment event"| payment
payment -->|"yes"| paid
payment -->|"no"| payment_failed
invoice -->|"worker dies mid-step"| redelivered
redelivered -->|"same event again"| payment
linkStyle 0 stroke:#2563eb,stroke-width:4px
linkStyle 1 stroke:#64748b,stroke-width:1.5px
linkStyle 2 stroke:#2563eb,stroke-width:4px
linkStyle 3 stroke:#2563eb,stroke-width:4px
linkStyle 4 stroke:#64748b,stroke-width:1.5px
linkStyle 5 stroke:#2563eb,stroke-width:4px
linkStyle 6 stroke:#2563eb,stroke-width:4px
linkStyle 7 stroke:#2563eb,stroke-width:4px
linkStyle 8 stroke:#ef4444,stroke-width:1.5px,stroke-dasharray:5 4
linkStyle 9 stroke:#ef4444,stroke-width:1.5px,stroke-dasharray:5 4
linkStyle 10 stroke:#ef4444,stroke-width:1.5px,stroke-dasharray:5 4
classDef start fill:#dbeafe,stroke:#2563eb,color:#0f172a
classDef state fill:#ffffff,stroke:#94a3b8,color:#0f172a
classDef check fill:#fef3c7,stroke:#b45309,color:#0f172a
classDef outcome fill:#dcfce7,stroke:#15803d,color:#0f172a
classDef failure fill:#fee2e2,stroke:#b91c1c,color:#0f172aGaps: transitions no scenario walks
| From | Transition | To |
|---|---|---|
| Payment captured? | no | Payment failed order unpaid |
| Invoice issued | worker dies mid-step | Worker restarted event delivered again |
| Worker restarted event delivered again | same event again | Payment captured? |