From cf1a9ed3f526eb132d793a2fd6b6af05a76a9ef9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Mar 2026 19:24:05 +0000 Subject: [PATCH] fix: add catch-all API mock and socket.io block for base screenshots Base screenshots showed loading spinners or were missing entirely because: 1. Unmocked API calls (e.g. /api/people, /api/search/explore) hit the static preview server which returns HTML instead of JSON, preventing networkidle 2. Socket.io WebSocket connections never complete handshake, blocking networkidle Add a catch-all /api/** mock (registered first, so specific mocks take priority) that returns empty JSON for any unmocked endpoint. Block socket.io connections. Also add a networkidle timeout fallback in run-scenarios.ts so screenshots are still captured even if networkidle doesn't resolve within 15s. https://claude.ai/code/session_01XSTqDJXuR4jaLN7SGm3uES --- e2e/src/screenshots/run-scenarios.ts | 11 +++++++++-- e2e/src/ui/mock-network/base-network.ts | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/e2e/src/screenshots/run-scenarios.ts b/e2e/src/screenshots/run-scenarios.ts index d951309335..5525bb61d2 100644 --- a/e2e/src/screenshots/run-scenarios.ts +++ b/e2e/src/screenshots/run-scenarios.ts @@ -97,8 +97,15 @@ for (const scenario of allScenarios) { }); } - // Navigate to the page - await page.goto(scenario.url, { waitUntil: 'networkidle' }); + // Navigate to the page. Use networkidle so SvelteKit hydrates and API + // calls complete, but fall back to domcontentloaded if it times out + // (e.g. a persistent connection the catch-all mock didn't cover). + try { + await page.goto(scenario.url, { waitUntil: 'networkidle', timeout: 15_000 }); + } catch { + console.warn(`networkidle timed out for ${scenario.name}, falling back to current state`); + // Page has already navigated, just continue with what we have + } // Wait for specific selector if specified if (scenario.waitForSelector) { diff --git a/e2e/src/ui/mock-network/base-network.ts b/e2e/src/ui/mock-network/base-network.ts index f23202ca77..98a521c649 100644 --- a/e2e/src/ui/mock-network/base-network.ts +++ b/e2e/src/ui/mock-network/base-network.ts @@ -10,6 +10,27 @@ export const setupBaseMockApiRoutes = async (context: BrowserContext, adminUserI path: '/', }, ]); + + // Block socket.io connections — these are persistent WebSocket connections + // that prevent networkidle from resolving since there's no real server. + await context.route('**/api/socket.io**', async (route) => { + return route.abort('connectionrefused'); + }); + + // Catch-all for any /api/ endpoint not explicitly mocked below. + // Registered FIRST so specific routes (registered after) take priority + // (Playwright checks routes in reverse registration order). + // Without this, unmocked API calls hit the static preview server which + // either hangs or returns HTML, preventing networkidle and causing timeouts. + await context.route('**/api/**', async (route) => { + const method = route.request().method(); + return route.fulfill({ + status: 200, + contentType: 'application/json', + json: method === 'GET' ? [] : {}, + }); + }); + await context.route('**/api/users/me', async (route) => { return route.fulfill({ status: 200,