Hard Mode Flaky-UI Dojo
Hard Mode
Hard Mode · Waiting strategy

Flaky-UI Dojo

Five widgets engineered to break naive tests: random latency, a spinner that lies, DOM nodes that get replaced under your locator, debounced results, and an optimistic save that can roll back. If your spec needs waitForTimeout, the dojo has already won.

5Timing traps
300-1800msRandom latency
25%Rollback chance
1Stable mode switch
Fixed 400ms delays, no random failures, honest spinner. Use it to build the test, then switch it off and watch which assertions survive. Also on via ?stable=1.

Trap 1 · The lying spinner

The spinner can disappear before the rows render. Waiting for spinner-gone is not the same as waiting for data.

Trap 2 · Detach and re-attach

Every click destroys and rebuilds this card after a delay. A stored element handle goes stale; a locator re-resolves.

Trap 3 · Debounced search

Results update 500ms after the last keystroke. Assert the result count, not the keystroke.

8 results

Trap 4 · Optimistic rollback

The toggle flips instantly, then the fake server answers 700-1400ms later, and one time in four it says no and flips it back.

Not saved yet

Trap 5 · The late-enabled button

Ticking the box starts a background check; Submit enables 300-1500ms later. Click too early and nothing happens.

Drills

  1. Load orders and assert exactly 4 rows appear, without ever waiting on the spinner. Run it 10 times with stable mode off; it must pass 10/10.
  2. Click the counter 5 times and assert it reads 5. The naive version with a stored elementHandle throws; explain why yours does not.
  3. Type pune and assert the count reaches 1, then clear and assert it returns to 8, using only web-first assertions.
  4. Turn the optimistic toggle on and write an assertion that passes only when the save truly succeeded, and a second spec that handles the rollback path with expect().toPass().
  5. Accept the terms and submit, no waitForTimeout allowed: Playwright's actionability checks should carry the wait for you.