// Load-aware timeouts and the one retry under load (tests/helpers/load.ts, testScope().concurrent in // tests/helpers/browser.ts): a timeout on a loaded machine runs once more; an assertion failure never does. import { describe, expect, test } from 'bun:test'; import { retryUnderLoad, WaitTimeout, withBudget } from './helpers/browser'; import { loadFactor, RETRY_MARK, scaled } from './helpers/load'; describe('load factor', () => { test('load รท cores from the larger of the 1- and 5-minute averages, between 1 and the cap', () => { expect(loadFactor({}, [5, 2, 1], 10)).toBe(1); expect(loadFactor({}, [30, 45, 50], 10)).toBe(4.5); expect(loadFactor({}, [577, 300, 100], 10)).toBe(5); expect(loadFactor({ STOREBOUND_LOAD_FACTOR: '3' }, [0, 0, 0], 10)).toBe(3); expect(loadFactor({ STOREBOUND_LOAD_FACTOR: '50' }, [0, 0, 0], 10)).toBe(5); expect(scaled(1000, 2.5)).toBe(2500); }); }); describe('one retry, only for a timeout under load', () => { const run = async (err: () => unknown, factor: number) => { const said: string[] = []; let n = 0; let failed: unknown = null; await retryUnderLoad('t', async () => { if (++n === 1) throw err(); }, () => factor, m => said.push(m)).catch(e => { failed = e; }); return { n, said, failed }; }; test('a wait timeout or a Playwright TimeoutError under load: retried once and reported', async () => { for (const err of [() => new WaitTimeout('timed out after 1 ms'), () => Object.assign(new Error('locator.click: Timeout 50ms exceeded'), { name: 'TimeoutError' })]) { const r = await run(err, 3); expect(r.n).toBe(2); expect(r.failed).toBeNull(); expect(r.said).toHaveLength(1); expect(r.said[0]!.startsWith(`${RETRY_MARK} t (load x3)`)).toBe(true); } }); test('an assertion failure is never retried, under any load', async () => { const r = await run(() => { try { expect(1).toBe(2); } catch (e) { return e; } }, 5); expect(r.n).toBe(1); expect(r.failed).not.toBeNull(); expect(r.said).toEqual([]); }); test('a timeout on a quiet machine (factor <= 2) is final', async () => { const r = await run(() => new WaitTimeout('timed out'), 2); expect(r.n).toBe(1); expect(r.failed).toBeInstanceOf(WaitTimeout); }); test('a second timeout fails the test (one retry only)', async () => { let n = 0; const e = await retryUnderLoad('t', async () => { n++; throw new WaitTimeout('again'); }, () => 4, () => {}).catch(x => x); expect(n).toBe(2); expect(e).toBeInstanceOf(WaitTimeout); }); test('the test budget: a run past it fails as a timeout, and the settle runs either way', async () => { let settled = 0; const e = await withBudget(() => Bun.sleep(200), 20, async () => { settled++; }).catch(x => x); expect(e).toBeInstanceOf(WaitTimeout); await withBudget(async () => {}, 1000, async () => { settled++; }); expect(settled).toBe(2); }); });