Advanced

Race conditions

Two rapid filter changes must commit only the latest result — not the slower-arriving prior request.

User story

As a user typing quickly, I want only the most recent filter applied, even when slower responses arrive late.

Acceptance criteria

  • Latest request wins regardless of arrival order
  • Spinner reflects the latest in-flight request
  • Stale responses are ignored
  • No flicker between intermediate states

Manual test steps

  1. 1.Open /users
  2. 2.Type 'al' (slow response)
  3. 3.Quickly type 'ali' (fast response)
  4. 4.Assert table shows results for 'ali'

Expected result

Final table reflects the 'ali' filter even though the 'al' response arrives later.

Possible bug risks

  • Stale response overwrites fresh state
  • Spinner reflects a request that has already been superseded
  • Cancel-token leaks across pages

Reference Playwright spec

race-conditions.spec.ts
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { test, expect } from '@playwright/test';

test('latest filter wins under race', async ({ page }) => {
  let calls = 0;
  await page.route('**/api/users*', async (route) => {
    calls += 1;
    const url = new URL(route.request().url());
    const q = url.searchParams.get('q');
    await new Promise((r) => setTimeout(r, q?.length === 2 ? 1500 : 200));
    await route.fulfill({
      status: 200,
      body: JSON.stringify({ rows: [{ name: q + ' Match' }] }),
    });
  });

  await page.goto('https://lab.hakdogan.com/users');
  await page.getByLabel(/search users/i).pressSequentially('al');
  await page.getByLabel(/search users/i).pressSequentially('i');

  await expect(page.getByText(/ali Match/i)).toBeVisible();
  expect(calls).toBeGreaterThanOrEqual(2);
});