Skip to main content

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 fullyParallel breaks CI
  • --grep @checkout passes; full suite fails on "empty cart"
  • Developer comment: "run onboarding.spec before billing.spec"
  • test.describe.serial block 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 beforeAll seeds once; later specs depend on that seed
  • Shared storageState from 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 beforeEach keyed to runId
  • Playwright fixtures that return fresh entities per test
  • API Arrange before page.goto when 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

SignalAction
test.describe.serial added to fix flakeAudit shared state; add runId seeds
test.only + reorder changes outcomeTwo specs share Arrange
New spec breaks unrelated fileGlobal beforeAll or shared user
CI shard order differs from localHard-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-patternWhy it failsBetter approach
test.describe.serial for whole fileSlow; hides couplingPer-spec seed routes
Shared let userId across testsMutation between specsFixture returns fresh id
"Setup" spec not in CI grepDriftAPI seed in each spec's Arrange
beforeAll creates one orderParallel workers colliderunId per test
Document run order in READMEHumans forgetCode 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.

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.

Start free on TestChimp · Book a demo