How it works
The explanation, with examples you can run.
Shared state and order
Two tests that share a module-level cart. Each is correct on its own; whether they pass depends on which runs first.
Press Run to see what your code prints, in order.
Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.
Under a test runner, the order changes when someone adds a file, when tests run in parallel, or when a runner shuffles. The fix is to create the cart inside each test (or in a beforeEach). The same goes for database rows, singletons, environment variables, and mocks that were never restored.
Guessing at time
A fixed sleep bets on how long something takes. Waiting for the condition doesn't need to guess:
Press Run to see what your code prints, in order.
Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.
Playwright's web-first assertions (await expect(locator).toHaveText(...)) and expect.poll() do this for you. In unit tests, fake timers remove real waiting altogether.
The usual suspects
| Cause | Symptom | Fix |
|---|---|---|
| Timing | Fails on slow machines or under load | Wait for conditions, never fixed sleeps |
| Shared state | Passes alone, fails in the suite | Fresh data per test, reset before not after |
| Order | Fails when files are added or shuffled | Same fix; run shuffled to prove it |
| Network and services | Fails when a sandbox API is slow or down | Double it, and keep it honest with contract tests |
| Clock and time zone | Fails at midnight, month end, DST | Inject the clock, pin the time zone |
| Resource leaks | Fails after N tests, "too many connections" | Close what you open; small pools fail fast |
| Concurrency in the product | Fails one run in fifty | Often a real race condition: fix the code |
Reproduce it first
Run the suspect many times and in different orders before changing anything: npx playwright test --repeat-each=20 path/to/spec.ts, Jest's --randomize, or Vitest's sequence.shuffle option. A failure you can reproduce in a minute can be fixed in an afternoon. Look hard at the last row of the table: sometimes the test is right and the product has the race.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.