test(ui-e2e): re-issue deep-link navigation when auth bootstrap drops the page param

navigateToPage deep-links to /ui?page=<page> then proceeds once the network
settles, but a fresh load can race the auth bootstrap: the app momentarily
treats the session as anonymous, bounces through /ui/login, and returns to the
default Virtual Keys page with the ?page= query param dropped. The helper never
checked where it actually landed, so any single bounce left callers asserting
against the wrong page and timing out (mcpServers, modelHub, addModel).

Confirm the requested page is what rendered and re-issue the navigation when it
was clobbered; auth is warm by the second load so the param sticks. Migrated
path routes are left alone since they intentionally leave the legacy root.
This commit is contained in:
mateo-berri
2026-06-12 12:23:40 +00:00
parent 07fb284c85
commit 9692f01b68
@@ -6,8 +6,20 @@ import { Page as PlaywrightPage, expect } from "@playwright/test";
* Waits for the sidebar to be visible before returning.
*/
export async function navigateToPage(page: PlaywrightPage, pageEnum: Page): Promise<void> {
await page.goto(`/ui?page=${pageEnum}`);
await page.waitForLoadState("networkidle");
// A fresh deep-link can race the auth bootstrap: the app briefly treats the
// session as anonymous, bounces through /ui/login, and lands back on the
// default page with the ?page= param dropped. Re-issue the navigation until
// the requested page sticks (auth is warm by the second load) so callers never
// assert against the default page.
for (let attempt = 0; attempt < 3; attempt++) {
await page.goto(`/ui?page=${pageEnum}`);
await page.waitForLoadState("networkidle");
const url = new URL(page.url());
const onLegacyRoot = url.pathname.replace(/\/+$/, "").endsWith("/ui");
if (!onLegacyRoot || url.searchParams.get("page") === pageEnum) {
break;
}
}
// Dismiss the "Quick feedback" popup if it appears
await dismissFeedbackPopup(page);
}