fix(router): sync route in navigate() — kill boot lobby-flash + offline e2e flake #210
Reference in New Issue
Block a user
Delete Branch "fix/boot-route-lag-e2e-flake"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Root-cause fix for the offline webkit/chromium e2e flake (owner-picked: fix the app root cause, not just the test).
Root cause
navigate()wrotelocation.hashand leftrouter.routeto the asynchashchange.bootstrapflipsapp.readyin the same tick right afternavigate('/login')on an unauthenticated cold start → one frame withapp.ready=true+ the stale route ('lobby', empty hash) → the lobby shell (tab bar + a doomedgames.list) briefly mounts under the login screen.enterLobbycould latch that transient tab-bar instead of clicking through login, then the Settings-tab click fought the tab detaching into the login slide (~7%, both engines).Diagnosed with a synchronous DOM/route probe: hash was
#/loginat 25 ms while the lobby (tabs=3, Ann) was still in the DOM; after the fix the boot goes splash → login directly (tabs=0).Fix
navigate()setsrouter.routesynchronously; the laterhashchangere-parses to the same value. Removes the prod boot lobby-flash + its spurious 401.offline.specenterLobby: wait-and-click the guest button (not a point-in-timecount()).router.specpins the sync-route property (RED on old code → 'login'; GREEN → 'settings') via a mock-only__routerseam (tree-shaken from prod).Verify
check 0 / unit 490 / build / bundle 114.3-115 / full e2e 200 (both engines) / offline+router stress 40x both engines 160/160 (was 6/80 failing).
navigate() wrote location.hash and left router.route to the asynchronous hashchange event. bootstrap flips app.ready in the same tick right after navigate('/login') on an unauthenticated cold start, so for one frame the app rendered with app.ready=true and the stale route ('lobby', from the empty hash) — briefly mounting the lobby shell (tab bar + a doomed games.list) under the new login screen before hashchange settled it. Update router.route synchronously inside navigate(); the later hashchange re-parses to the same value. This removes the boot lobby-flash (and its spurious games.list 401) and, as the root cause, the offline e2e flake: enterLobby could latch that transient lobby tab-bar instead of clicking through login, then the Settings-tab click at line 44 fought the tab detaching into the login slide (~7% of runs, both engines). Also: - offline.spec enterLobby: wait for the guest button and click it, instead of a point-in-time count() that a pre-login splash frame sampled as 0 (skipping the click and hanging / latching the transient). - New e2e router.spec pins the synchronous-route property (RED on the old code, which returned the previous route; GREEN now) via a mock-only __router seam. Verify: check 0 / unit 490 / build / bundle 114.3/115 / full e2e 200 / the offline+router stress at 40x on both engines 160/160 (was 6/80 failing).