Advanced

Retry flow

First attempt 500s, second attempt succeeds — UI must reach the success state without a manual reload.

User story

As a user with a flaky network, I want the UI to retry failed requests and recover automatically.

Acceptance criteria

  • First call returns 500
  • Second call returns 200
  • UI reaches success after the second call
  • Retry counter is observable in the test

Manual test steps

  1. 1.Counter-based mock: 500 then 200
  2. 2.Open /wallet
  3. 3.Assert success after retry

Expected result

After the second call, the success state appears without user action.

Possible bug risks

  • Infinite retry on permanent 500
  • Retry interval too aggressive (no jitter)
  • Retry counter resets per render, allowing accidental loops

Reference Playwright spec

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

test('retry recovers after first 500', async ({ page }) => {
  let attempt = 0;
  await page.route('**/api/ledger/balance', (route) => {
    attempt += 1;
    if (attempt === 1) {
      return route.fulfill({ status: 500, body: '{}' });
    }
    return route.fulfill({
      status: 200,
      body: JSON.stringify({ balance: 2840.55 }),
    });
  });

  await page.goto('https://lab.hakdogan.com/wallet');
  await expect(page.getByTestId('balance-display')).toContainText('$2,840.55');
});