From 12498d2204c546b84f59958618bbd64b00075e72 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jul 2026 12:06:36 +0100 Subject: [PATCH 1/2] test(pages): enable complex shallow routing coverage --- examples/pages-router-complex/README.md | 7 +++---- .../client-routing.spec.ts | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/examples/pages-router-complex/README.md b/examples/pages-router-complex/README.md index f8ad880554..4612f9314a 100644 --- a/examples/pages-router-complex/README.md +++ b/examples/pages-router-complex/README.md @@ -98,12 +98,11 @@ PLAYWRIGHT_PROJECT=pages-router-complex pnpm run test:e2e degrades under it, so the `@atlas/*` alias is wired into both bundlers explicitly (webpack hook + Vite `resolve.alias`); tsconfig `paths` (without the removed `baseUrl`) stays authoritative for the type checker. -- **vinext dev (Cloudflare plugin): 59/73 specs pass; the 14 known gaps are +- **vinext dev (Cloudflare plugin): 62/73 specs pass; the 11 known gaps are marked `test.fixme` so the passing surface runs in CI.** Known gaps: `generateBuildId` is invoked at dev startup (Next.js only calls it at build - time — the e2e server exports `RELEASE_TAG` to compensate), shallow routing - + `router.events` (including a hydration knock-on that breaks page - interactivity), the `next/image` custom-loader/`fill` path, raw + time — the e2e server exports `RELEASE_TAG` to compensate), the `next/image` + custom-loader/`fill` path, raw `/_next/data` interception and the `/_next/image` 403 middleware branches, the `history.replaceState`-beside-the-router hybrid, the gallery scrub redirect, cacheable-404 surrogate headers, the `afterFiles` type-ahead diff --git a/tests/e2e/pages-router-complex/client-routing.spec.ts b/tests/e2e/pages-router-complex/client-routing.spec.ts index 8a83797920..8ec43e39de 100644 --- a/tests/e2e/pages-router-complex/client-routing.spec.ts +++ b/tests/e2e/pages-router-complex/client-routing.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from "@playwright/test"; +import { test, expect, type Page } from "@playwright/test"; type BeaconWindow = Window & { __ATLAS_BEACONS__?: { name: string; attributes: Record }[]; @@ -6,18 +6,26 @@ type BeaconWindow = Window & { __nav_marker__?: boolean; }; +const waitForHydration = (page: Page) => + expect(page.locator('[data-testid="helper-dock"]')).toBeVisible(); + /** * Client-side routing behaviours: shallow router.push with the internal * dynamic-route pattern, router.events subscriptions, and the trial-mark * reset hook built on next/compat/router. + * + * Next.js parity references: + * https://github.com/vercel/next.js/blob/canary/test/e2e/middleware-rewrites/test/index.test.ts + * https://github.com/vercel/next.js/blob/canary/test/e2e/basepath/router-events.test.ts */ test.describe("shallow routing and router events", () => { - test.fixme("changing sort shallow-navigates without re-running gSSP", async ({ page }) => { + test("changing sort shallow-navigates without re-running gSSP", async ({ page }) => { await page.goto("/gallery/skies/clips"); await expect(page.locator('[data-testid="gallery-wall"]')).toHaveAttribute( "data-sort", "featured", ); + await waitForHydration(page); // Plant a marker: a shallow transition must NOT be a full document load. await page.evaluate(() => { @@ -40,10 +48,11 @@ test.describe("shallow routing and router events", () => { expect(titles).toEqual([...titles].sort((a, b) => a.localeCompare(b))); }); - test.fixme("shallow transitions fire router events observed by the progress frame", async ({ + test("shallow transitions fire router events observed by the progress frame", async ({ page, }) => { await page.goto("/gallery/skies/clips"); + await waitForHydration(page); await expect(page.locator('[data-testid="route-progress"]')).toBeVisible(); await page.locator('[data-testid="wall-sort"]').selectOption("newest"); @@ -60,8 +69,9 @@ test.describe("shallow routing and router events", () => { expect(phases.indexOf("start")).toBeLessThan(phases.indexOf("complete")); }); - test.fixme("route changes reset the per-page trial marks", async ({ page }) => { + test("route changes reset the per-page trial marks", async ({ page }) => { await page.goto("/gallery/skies/clips"); + await waitForHydration(page); await page.evaluate(() => { (window as BeaconWindow).__ATLAS_TRIALS_ACTIVE__ = ["stale-flag"]; }); From 29c640ac62e416bee6e050162b7ee5cc15eccce7 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 31 Jul 2026 12:15:16 +0100 Subject: [PATCH 2/2] test(pages): verify shallow routing skips gSSP --- .../pages/[zone]/gallery/[...facets].page.tsx | 5 +++-- tests/e2e/pages-router-complex/client-routing.spec.ts | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/pages-router-complex/pages/[zone]/gallery/[...facets].page.tsx b/examples/pages-router-complex/pages/[zone]/gallery/[...facets].page.tsx index bd5d4ef627..b28ecfd950 100644 --- a/examples/pages-router-complex/pages/[zone]/gallery/[...facets].page.tsx +++ b/examples/pages-router-complex/pages/[zone]/gallery/[...facets].page.tsx @@ -43,7 +43,7 @@ export type GalleryWallProps = PageLiftedProps & { export type GalleryWallComponentProps = Omit< GalleryWallProps, - "lifted" | "graphSnapshot" | "edgeProbeData" + "graphSnapshot" | "edgeProbeData" >; const SORT_ORDERS = ["featured", "newest", "alpha"] as const; @@ -62,7 +62,7 @@ const orderAssets = (assets: AssetCard[], sort: SortOrder): AssetCard[] => { } }; -const GalleryWall = ({ wallPath, startPage }: GalleryWallComponentProps) => { +const GalleryWall = ({ wallPath, startPage, lifted }: GalleryWallComponentProps) => { const router = useRouter(); const leaf = wallPath.split("/").filter(Boolean)[1] ?? ""; const node = useGraphOp("nodeByTrail", { trail: leaf }); @@ -109,6 +109,7 @@ const GalleryWall = ({ wallPath, startPage }: GalleryWallComponentProps) => { data-start-page={startPage} data-sort={sort} data-from-snapshot={node.fromSnapshot} + data-rendered-at-ms={lifted.renderedAtMs} >

Wall: {node.data?.name ?? "…"}