import { clickNavigationLink, expect, revealNavigationLinks, test, } from "../helpers/serve-dist"; test("keeps canonical hrefs while creating exactly one or zero explicit history entries", async ({ page, distUrl, }) => { await page.goto(distUrl, { waitUntil: "domcontentloaded" }); const initialLength = await page.evaluate(() => history.length); await clickNavigationLink(page, "#start"); await expect(page).toHaveURL(`${distUrl}/`); expect(await page.evaluate(() => history.length)).toBe(initialLength); await expect(page.locator("#start-heading")).toBeFocused(); await clickNavigationLink(page, "#profile"); await expect(page).toHaveURL(`${distUrl}/#profile`); expect(await page.evaluate(() => history.length)).toBe(initialLength + 1); await expect(page.locator("#profile-heading")).toBeFocused(); await clickNavigationLink(page, "#profile"); expect(await page.evaluate(() => history.length)).toBe(initialLength + 1); await expect(page.locator("#profile-heading")).toBeFocused(); }); test("cancels pending explicit focus when wheel intent intervenes", async ({ page, distUrl, }, testInfo) => { test.skip( testInfo.project.name === "mobile-chromium", "Hidden-focus cancellation is covered once in desktop Chromium.", ); await page.goto(distUrl, { waitUntil: "domcontentloaded" }); const link = page.locator('nav a[href="#infrastructure"]'); await link.focus(); await page.evaluate(() => { const anchor = document.querySelector( 'nav a[href="#infrastructure"]', ); anchor?.addEventListener( "click", () => queueMicrotask(() => window.dispatchEvent(new WheelEvent("wheel", { deltaY: 40 })), ), { once: true }, ); }); await link.click(); await page.waitForTimeout(100); await expect(link).toBeFocused(); await expect(page.locator("#infrastructure-heading")).not.toBeFocused(); }); test("passive scrolling replaces a stable fragment without stealing focus", async ({ page, distUrl, }) => { await page.goto(distUrl, { waitUntil: "domcontentloaded" }); await revealNavigationLinks(page); const link = page.locator('nav a[href="#start"]'); await link.focus(); await page.evaluate(() => { window.dispatchEvent(new WheelEvent("wheel", { deltaY: 20 })); const heading = document.querySelector("#experience-heading"); if (heading === null) throw new Error("Missing experience heading"); const headingDocumentTop = heading.getBoundingClientRect().top + window.scrollY; // Place the heading just beyond the 35% activation line. Scroll offsets // are integer-rounded in Chromium, so exact boundary equality is brittle. window.scrollTo(0, headingDocumentTop - window.innerHeight * 0.34); }); await expect(page).toHaveURL(`${distUrl}/#experience`, { timeout: 2000 }); await expect(link).toBeFocused(); await expect(page.locator("#experience-heading")).not.toBeFocused(); }); test("back and forward restore sections without another history mutation or focus move", async ({ page, distUrl, }) => { await page.goto(distUrl, { waitUntil: "domcontentloaded" }); await clickNavigationLink(page, "#profile"); await clickNavigationLink(page, "#experience"); const historyLength = await page.evaluate(() => history.length); await expect(page.locator("#experience-heading")).toBeFocused(); await page.goBack(); await expect(page).toHaveURL(`${distUrl}/#profile`); await expect(page.locator("#profile")).toBeInViewport(); expect(await page.evaluate(() => history.length)).toBe(historyLength); await expect(page.locator("#profile-heading")).not.toBeFocused(); await page.goForward(); await expect(page).toHaveURL(`${distUrl}/#experience`); await expect(page.locator("#experience")).toBeInViewport(); expect(await page.evaluate(() => history.length)).toBe(historyLength); await expect(page.locator("#experience-heading")).not.toBeFocused(); }); test("direct initial fragments align without moving focus", async ({ page, distUrl, }) => { await page.goto(`${distUrl}/#toolkit`, { waitUntil: "domcontentloaded" }); await expect(page.locator("#toolkit")).toBeInViewport(); await expect(page.locator("#toolkit-heading")).not.toBeFocused(); });