import { expect, test } from './fixtures'; // The hash router must update its reactive `route` rune synchronously inside navigate(), not defer it // to the asynchronous `hashchange` event. Bootstrap flips `app.ready` in the same tick right after // `navigate('/login')` on an unauthenticated cold start; a route that trailed the hash for one frame // let App.svelte render the stale route (the empty-hash lobby) under the new login screen — a visible // lobby-shell flash plus a doomed games.list. It also made the offline e2e flaky: enterLobby could // latch that transient lobby tab-bar instead of clicking through the login screen. test('navigate updates the reactive route synchronously (no hashchange lag)', async ({ page }) => { await page.goto('/'); // The bundle has loaded and installed the mock __router seam once the login screen is up. await expect(page.getByRole('button', { name: /guest/i })).toBeVisible(); // Read the route in the SAME microtask as the navigate: the fix makes it the new route at once; // the pre-fix code returned the previous route (it waited for the async hashchange). const routeAfterNavigate = await page.evaluate(() => { const r = (window as unknown as { __router: { navigate(p: string): void; route(): string } }).__router; r.navigate('/settings'); return r.route(); }); expect(routeAfterNavigate).toBe('settings'); // The hash was written too, so a reload/back still resolves the same route. expect(new URL(page.url()).hash).toBe('#/settings'); });