diff --git a/src/shared/components/Sidebar.tsx b/src/shared/components/Sidebar.tsx index ed2188055e..45e7af3231 100644 --- a/src/shared/components/Sidebar.tsx +++ b/src/shared/components/Sidebar.tsx @@ -431,6 +431,7 @@ export default function Sidebar({
diff --git a/tests/e2e/navigation.spec.ts b/tests/e2e/navigation.spec.ts index 0f23b14bff..76db5db458 100644 --- a/tests/e2e/navigation.spec.ts +++ b/tests/e2e/navigation.spec.ts @@ -1,4 +1,5 @@ import { test, expect } from "@playwright/test"; +import { gotoDashboardRoute } from "./helpers/dashboardAuth"; test.describe("Dashboard Navigation", () => { test("redirects unauthenticated user to /login", async ({ page }) => { @@ -10,6 +11,30 @@ test.describe("Dashboard Navigation", () => { expect(url).toMatch(/\/(login|dashboard)/); }); + test("does not prefetch dashboard routes and preserves client navigation", async ({ page }) => { + const speculativeRequests: string[] = []; + + page.on("request", (request) => { + const headers = request.headers(); + const isRscPrefetch = + headers.rsc === "1" && + (headers["next-router-prefetch"] === "1" || + headers.purpose?.toLowerCase().includes("prefetch") || + headers["sec-purpose"]?.toLowerCase().includes("prefetch")); + + if (isRscPrefetch) speculativeRequests.push(request.url()); + }); + + await gotoDashboardRoute(page, "/home"); + await expect(page.getByRole("link", { name: /providers/i }).first()).toBeVisible(); + await page.waitForTimeout(500); + + expect(speculativeRequests).toEqual([]); + + await page.getByRole("link", { name: /providers/i }).first().click(); + await expect(page).toHaveURL(/\/dashboard\/providers/); + }); + test("login page renders with form elements", async ({ page }) => { await page.goto("/login"); // Should show some form of authentication UI diff --git a/tests/unit/sidebar-prefetch-policy-8281.test.ts b/tests/unit/sidebar-prefetch-policy-8281.test.ts new file mode 100644 index 0000000000..02c170cc71 --- /dev/null +++ b/tests/unit/sidebar-prefetch-policy-8281.test.ts @@ -0,0 +1,17 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import test from "node:test"; + +const SIDEBAR = "src/shared/components/Sidebar.tsx"; + +test("#8281: dashboard navigation opts out of automatic route prefetch", async () => { + const source = await readFile(SIDEBAR, "utf8"); + + const internalLink = source.match(//); + assert.ok(internalLink, "expected the sidebar's internal navigation Link"); + assert.match(internalLink[0], /prefetch=\{false\}/); + + const logoLink = source.match(//); + assert.ok(logoLink, "expected the sidebar logo home Link"); + assert.match(logoLink[0], /prefetch=\{false\}/); +});