mirror of
https://github.com/immich-app/immich.git
synced 2026-03-22 18:29:56 +03:00
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
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user