End-to-end
The question: does the critical journey work through the real, assembled stack?
This is the only typology that exercises the system as a user meets it: the real browser, the real network, the real services, the real database, the real configuration. Everything below it tests a part in isolation and takes the composition on trust.
It is also the slowest, the flakiest, the most expensive to maintain, and the one that fails for reasons unrelated to the change. So the discipline is not writing them well — it is owning as few of them as possible, and being deliberate about which.
Why so few
Section titled “Why so few”An end-to-end test failure tells you something is wrong somewhere in a chain of ten components. Diagnosis is a bisection. Compare with a contract test failure, which names the field, the side and the change.
The costs compound in a specific order, and this is the sequence to recognise before you are in it:
- The suite grows because every new feature “should have an E2E test”.
- It takes 40 minutes, so it moves out of the merge path.
- Out of the merge path, failures accumulate before anyone looks.
- Some are real and some are timing. Nobody can tell which without investigating each.
- The team starts re-running the suite until it passes.
- The suite now costs money and provides no signal.
Step 5 is the death of a suite, and it is reached by growth rather than by neglect.
What earns a place
Section titled “What earns a place”A journey earns one when all four hold:
- It is critical — money, data, safety, or the reason the product exists.
- It crosses at least two components, so nothing below it could cover it.
- It is stable — the flow changes rarely, even if the pages do.
- Its failure would be missed by everything else.
For most products that is five to fifteen journeys. Sign up, log in, search, add to basket, check out, receive confirmation. Not “the profile page shows the correct city” — that is a component test.
Writing them so they survive
Section titled “Writing them so they survive”Test the journey, not the page. One test per user goal, end to end. Not one per screen.
Address by role and accessible name, or by an explicit test id — never by CSS
class or DOM position. getByRole('button', { name: 'Place order' }) survives a
restyle; .btn-primary:nth-child(2) does not. It also fails when the button
stops being reachable by an assistive technology, which is a defect worth
catching. See accessibility.
Never sleep. Wait for a condition — a request completing, an element
appearing, a state settling. Every sleep(2000) is a flake in waiting and a
second added to every run forever. See
determinism.
Own the data. Each test creates its account, its order, its state, through the API rather than the UI, and cleans up after itself. A suite that depends on “the demo user” is a suite that breaks when someone uses the demo user.
Do the setup through the API. Only the thing under test goes through the UI. Logging in through the login form in all fifteen tests means fifteen tests fail when login breaks, and it makes each of them slower for no additional signal.
Capture evidence on failure. Screenshot, DOM, console log, network log, and a trace. An E2E failure that cannot be diagnosed from its artefacts will be re-run, and re-running is step 5.
Where it runs
Section titled “Where it runs”Against a deployed release candidate, in an environment as production-like as you can afford. Not on a developer’s laptop with three services stubbed — that is a component test wearing a costume.
The environment is part of the test. Configuration differences, TLS termination, reverse-proxy rules and CDN behaviour are exactly the things this level is supposed to catch, and they only exist where the thing is actually deployed. See environments.
What it cannot catch
Section titled “What it cannot catch”Anything requiring volume, time or real data: the query that is fine with 50 rows and catastrophic with 5 million, the leak that surfaces after six hours, the account created under a schema from 2009. Those belong to performance and to production.
Tooling
Section titled “Tooling”See browser and mobile tooling for Playwright, its trace viewer, and the mobile equivalents.