Technical guide
Stateful End-to-End Testing
Make authentication, roles, data, flags, locale, clock, side effects, and cleanup explicit without creating order-dependent tests.
Stateful end-to-end testing verifies a complete product outcome while explicitly controlling the state that changes its behavior: authentication, actor, role, permissions, plan, data, flags, locale, timezone, theme, viewport, clock, external dependencies, side effects, and cleanup.
It should not mean allowing one test to inherit whatever the previous test left behind.
Isolation and state are complementary
Playwright creates isolated browser contexts for tests so cookies, local storage, and session storage do not leak between them. Its documentation explains that isolation improves reproducibility and prevents cascading failures (Playwright isolation).
Isolation provides a clean browser boundary. The test still needs deliberate application state. An isolated context does not decide which account exists, which role it has, which feature flags apply, whether the subscription is at capacity, or which server-side records must be created and cleaned up.
Stateful testing therefore combines:
- isolated execution;
- explicit state reconstruction;
- a meaningful outcome checkpoint;
- retained evidence and failure classification.
Define state as a contract
A State Capsule should describe every condition that can change the intended outcome.
| State dimension | Questions to answer |
|---|---|
| Actor | Which identity class is acting, and how is it provisioned? |
| Role and permissions | What may the actor read, change, approve, publish, or delete? |
| Plan and capacity | Which entitlements, limits, or billing states apply? |
| Data | Which deterministic entities must exist, and who owns cleanup? |
| Flags and experiments | Which product version or branch of behavior is expected? |
| Authentication | Which session or credential class is used, where is it valid, and when does it expire? |
| Locale and timezone | Which copy, formatting, direction, date, and time behavior changes? |
| Theme and viewport | Which visible layout and interaction conditions matter? |
| Clock | Is time fixed, bounded, or intentionally advancing? |
| Side effects | Which emails, payments, webhooks, files, or remote writes are permitted? |
The capsule stores policy and provenance, not plaintext secrets.
Treat authenticated state as sensitive
Playwright supports saving and reusing authenticated browser state, while warning that the state file can contain cookies and headers capable of impersonating the account (Playwright authentication).
Use these boundaries:
- keep state files out of source control;
- scope them to one environment and identity class;
- detect expiry and cross-environment reuse;
- separate public Journeys from credentialed state;
- use different accounts for parallel tests that mutate server-side state;
- retain metadata about the session without exposing reusable credentials;
- revoke or rotate state through the owning environment.
A state file is an input. It is not proof that the correct role, workspace, plan, or recipient executed.
Reconstruct server-side data independently
Order-dependent test suites often rely on an earlier test to create the account, project, order, or invitation needed by a later test. When the earlier test fails or workers run in parallel, the real dependency appears as flakiness.
Prefer one of these patterns:
- create isolated data through a supported API or fixture before the Journey;
- restore a known database or tenant snapshot;
- use unique per-Run identifiers and explicit cleanup;
- attach a seed recipe to the State Capsule;
- verify the seed consequence before the user path begins;
- keep destructive or externally visible side effects behind explicit authorization.
The test should be rerunnable without relying on execution order.
Model roles and multi-user behavior explicitly
Invitations, approvals, chat, support handoffs, and shared documents often require more than one actor. Playwright can use multiple browser contexts inside one scenario for independent sessions (BrowserContext).
The Journey contract should still identify:
- which actor performs each step;
- which workspace and role each context represents;
- which cross-actor event is expected;
- which actor or recipient state proves success;
- how sessions and data are isolated after the Run.
Do not treat a second browser page in the same session as a second user.
Control flags, experiments, and product variants
Feature flags can change route shape, copy, available actions, checkpoint semantics, or data migrations. Record the expected flag state in the State Capsule and retain the observed state with the Run.
If the same Journey must support both variants, use explicit contexts or branches. Do not allow the test to infer the variant from whichever interface appears and then declare both outcomes equivalent.
Make time deterministic where meaning depends on it
Trials, invitations, scheduled publishing, retention, timezones, and billing periods depend on time. A test that waits for real time or reads the uncontrolled system clock can pass and fail for reasons unrelated to the product change.
Declare whether the clock is:
- fixed at a known instant;
- advanced through an authorized test interface;
- bounded to a tolerance;
- observed but not controlled because an external provider owns it.
Record the actual time basis with the Observation.
Bound external side effects
Stateful Journeys can send email, create charges, fire webhooks, change remote records, or publish artifacts. Every side effect needs an explicit policy:
- allowed in this environment;
- replaced with a sandbox or verified local provider;
- observed but not executed;
- reversible and cleaned up;
- forbidden and expected to fail closed.
An unplanned real email or charge is not successful coverage.
Use user-visible assertions without losing outcome evidence
Playwright recommends testing user-visible behavior and provides auto-retrying web assertions that wait for expected interface state (Playwright best practices, assertions).
Use those assertions for visible interaction, then verify the complete outcome through the strongest supported evidence. The correct checkpoint may combine UI confirmation, product state, recipient identity, API result, or delivered artifact.
Avoid fixed sleeps when the product exposes a meaningful readiness or outcome signal.
Retry infrastructure, not meaning
Playwright can retry failed tests and reports whether a test passed initially, passed only on retry, or remained failed (Playwright retries).
Do not use retry count as failure classification. Before retrying, ask whether the evidence indicates:
- infrastructure instability;
- unreconstructed state;
- an expired or wrong session;
- a target-identification problem;
- an actual product or policy failure.
Only a bounded infrastructure class should retry automatically. A later pass must not erase the first Observation or make a real product failure disappear.
Separate target repair from outcome approval
Self-healing selectors can reduce maintenance when a product element moved without changing meaning. They can also target the wrong element and manufacture a green Run.
Layer target identity and retain the proposed repair. If ambiguity or product meaning changed, send the repair to Review. AI may propose the target; it may not approve its own repair or mutate the immutable Observation.
Classify failures with state evidence
When a stateful Journey fails, keep the distinction among:
- product failure;
- State Capsule reconstruction failure;
- target failure;
- runner or provider infrastructure failure;
- policy or side-effect violation;
- privacy retention failure;
- wrong actor, workspace, role, or recipient.
The classification determines repair ownership and whether retry is safe.
Example: subscription upgrade
State Capsule
- workspace owner;
- monthly Starter subscription;
- valid sandbox payment method;
- one feature flag enabled;
- USD locale and fixed renewal date;
- permission to create a sandbox billing change;
- webhook delivery to a controlled endpoint.
Outcome checkpoint
The workspace subscription, entitlement state, invoice preview, and intended account all reflect the selected upgrade, and the expected webhook references the same change.
Failure interpretation
- a declined sandbox card may be an expected product branch;
- a missing price ID is configuration or state;
- a provider timeout may be infrastructure;
- an upgrade applied to another workspace is a recipient or product failure;
- a real production charge violates policy.
Stateful Journey checklist
Before execution:
- Outcome and actor are explicit.
- Browser context is isolated.
- Server-side data has an independent seed and cleanup owner.
- Role, permissions, plan, and flags are declared.
- Authentication state is environment-scoped and protected.
- Locale, timezone, viewport, theme, and clock are deliberate.
- External side effects are sandboxed or forbidden.
- Checkpoints prove the intended consequence.
- Failure classes and retry policy are declared.
- Evidence retention and privacy treatment are known.
Connect state to the maintained Journey
Stateful E2E becomes durable when the State Capsule, Run, Observation, Decision, and downstream outputs resolve to the same immutable Journey Version.
Read Critical User Journey Testing, measure the inventory with Critical Journey Coverage, or explore Runs and verification.
Start with one release-critical Journey.
Define the outcome, declare its state, run it, inspect the evidence, and record the Decision before expanding coverage.