E2E Tests Depend on Run Order
Short answer
When Spec B only passes after Spec A, you have coupling—not a Playwright bug. Each test must Arrange its own universe with seed routes and runId—never rely on execution order, test.describe.serial, or leftover rows from a "setup" spec.
Part of Common E2E testing gotchas.
Symptom
- Reordering files or enabling
fullyParallelbreaks CI --grep @checkoutpasses; full suite fails on "empty cart"- Developer comment: "run onboarding.spec before billing.spec"
test.describe.serialblock keeps growing
Root cause
Specs share implicit prerequisites:
- Spec A creates user; Spec B assumes user exists
- Spec A leaves cart items; Spec B expects empty state
- Global
beforeAllseeds once; later specs depend on that seed - Shared
storageStatefrom a prior login spec
Order dependency is the suite-level smell of world-state mutation—tests are coupled through data, not through declared fixtures.
Fix: independent Arrange every time
// Bad — Spec B depends on Spec A's user
test('registers user', async ({ page }) => { /* creates user@test.com */ });
test('upgrades plan', async ({ page }) => { /* assumes user@test.com exists */ });
// Good — each spec seeds what it needs
test('upgrades plan', async ({ page, request }) => {
const runId = `order-${Date.now()}`;
const { email } = await request.post('/api/test/seed-user', {
data: { runId, plan: 'free' },
}).then(r => r.json());
await page.goto(`/billing?run=${runId}`);
// Act: upgrade ...
const probe = await request.get(`/api/test/probe-subscription?runId=${runId}`).then(r => r.json());
expect(probe.plan).toBe('pro');
});
Ban "setup specs" that only run first
Replace with:
- Seed routes in
beforeEachkeyed torunId - Playwright fixtures that return fresh entities per test
- API Arrange before
page.gotowhen UI signup is not the subject
When serial is legitimate (rare)
test.describe.serial is acceptable only when:
- Testing a true singleton resource you cannot namespace
- Documented with ticket + plan to remove
Default: parallel-safe isolation. See Playwright test parallelization.
Detect order dependency early
| Signal | Action |
|---|---|
test.describe.serial added to fix flake | Audit shared state; add runId seeds |
test.only + reorder changes outcome | Two specs share Arrange |
| New spec breaks unrelated file | Global beforeAll or shared user |
| CI shard order differs from local | Hard-coded data or missing isolation |
Reproduce: npx playwright test --workers=4 and shuffle with --shard=1/2 in CI (GitHub Actions parallel).
Anti-patterns
| Anti-pattern | Why it fails | Better approach |
|---|---|---|
test.describe.serial for whole file | Slow; hides coupling | Per-spec seed routes |
Shared let userId across tests | Mutation between specs | Fixture returns fresh id |
| "Setup" spec not in CI grep | Drift | API seed in each spec's Arrange |
beforeAll creates one order | Parallel workers collide | runId per test |
| Document run order in README | Humans forget | Code enforces isolation |
TestChimp workflow
Markdown scenarios should state Arrange preconditions per story—not "requires Test 4." /testchimp test agents split coupled specs when PRs fail under parallel, using scenario context to add seed routes. /testchimp init scaffolds the fixture layer so new specs do not inherit order assumptions.
Related
- World-state mutation
- Parallel CI collisions
- Hardcoded test data
- Seed routes and probe Assert
- Playwright test dependencies
Frequently asked questions
Is test.describe.serial always wrong?
No—but it is overused to mask shared state. Use serial only for true singleton constraints with documentation; default to parallel-safe Arrange.
Can beforeAll ever be safe?
beforeAll that only reads immutable config is fine. beforeAll that creates DB rows shared by later tests is order coupling—move to per-test seed.
Our suite has a logical user journey across files—how?
Model journeys as one spec with multiple steps, or repeat Arrange in each spec via seed routes. Journey markdown can span steps; Playwright files should not depend on file sort order.
Does Playwright run tests in file order?
Not guaranteed under parallel or sharding. Never rely on filesystem order or test registration order for correctness.
How does this relate to world-state mutation?
Same root cause—shared mutable data. Order dependency appears when serial execution accidentally serializes access to that shared state.
Should we split coupled specs into one big test?
Prefer independent specs with shared fixtures over one 200-line test—better failure signals and parallel CI. Extract common Arrange to a fixture function.
Can TestChimp detect order-dependent suites?
Flaky parallel runs plus scenario-linked SmartTests surface coupling—/testchimp test on PRs refactors specs to seed per runId when agents read Arrange requirements from markdown plans.
file-level dependency vs test-level?
Playwright supports project dependencies for global setup artifacts (e.g. auth files). Do not use dependencies to pass mutable business entities between specs—seed per test instead.
Apply these patterns in your repo
Run `/testchimp init` to connect TestChimp to your repo, then `/testchimp test` on PRs to turn these patterns into maintained SmartTests. Use `/testchimp evolve` when you want to expand coverage as your app grows.