mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
feat(#76): bound primary-route fetches and local-first driver summary
Add shared apiFetch timeouts/abort/typed errors with in-flight dedupe, a RouteState UI for loading/empty/timeout/error+retry, and wire it through Weekend (Data Health), Championship, Driver Profile, Briefing, Live, and Race Hub. Driver summary is local-first with bounded optional OpenF1 enrichment so a hung remote call cannot block the profile. Spike note: parseSourceMode defaults to openf1; driver summary now treats omitted ?source= as auto so local season data is preferred. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
42
tests/route-resilience.spec.ts
Normal file
42
tests/route-resilience.spec.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Primary-route resilience (forced errors)', () => {
|
||||
test('Weekend leaves loading and shows retry after weekend-context failure', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route('**/api/v1/weekend-context', async (route) => {
|
||||
await new Promise((r) => setTimeout(r, 50))
|
||||
await route.fulfill({
|
||||
status: 503,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: 'forced weekend-context failure', stale: false }),
|
||||
})
|
||||
})
|
||||
|
||||
await page.goto('/')
|
||||
await expect(page.getByTestId('weekend-error')).toBeVisible({ timeout: 15_000 })
|
||||
await expect(page.getByRole('button', { name: 'Retry' })).toBeVisible()
|
||||
await expect(page.getByTestId('weekend-error')).not.toHaveText(/API 503|forced weekend-context/i)
|
||||
})
|
||||
|
||||
test('Driver Profile leaves loading and shows retry after summary timeout', async ({ page }) => {
|
||||
await page.route('**/api/v1/driver/summary**', async (route) => {
|
||||
// Hold the connection past the UI wait without fulfilling — the browser
|
||||
// abort/timeout path is covered in unit tests; here we force an HTTP error
|
||||
// so the shared RouteState recovery UI is exercised hermetically.
|
||||
await route.fulfill({
|
||||
status: 504,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify({ error: 'forced timeout', stale: false }),
|
||||
})
|
||||
})
|
||||
await page.route('**/api/v1/seasons', (route) =>
|
||||
route.fulfill({ contentType: 'application/json', body: JSON.stringify([2025]) }),
|
||||
)
|
||||
|
||||
await page.goto('/drivers/1?year=2025')
|
||||
await expect(page.getByTestId('driver-profile-error')).toBeVisible({ timeout: 15_000 })
|
||||
await expect(page.getByRole('button', { name: 'Retry' })).toBeVisible()
|
||||
await expect(page.getByTestId('driver-profile-error')).not.toHaveText(/API 504/i)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user