import { act, fireEvent, render, screen } from "@testing-library/react"; import { resetHomeArrivalState, useHomeFragmentNavigation, } from "./useHomeFragmentNavigation"; function HomeNavigation() { const onLayoutReady = useHomeFragmentNavigation(); return ( <> Sobre Contato
); } const originalScrollIntoView = HTMLElement.prototype.scrollIntoView; beforeEach(() => { resetHomeArrivalState(); window.history.replaceState(null, "", "/"); HTMLElement.prototype.scrollIntoView = jest.fn(); }); afterEach(() => { jest.restoreAllMocks(); window.history.replaceState(null, "", "/"); if (originalScrollIntoView) { HTMLElement.prototype.scrollIntoView = originalScrollIntoView; } else { Reflect.deleteProperty(HTMLElement.prototype, "scrollIntoView"); } }); describe("home fragment navigation", () => { it("starts an unfragmented visit at the top after the home establishes layout", () => { let restoredPosition = 3200; jest .spyOn(window, "scrollTo") .mockImplementation((options: ScrollToOptions | number) => { if (typeof options === "object") restoredPosition = options.top ?? restoredPosition; }); render(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(restoredPosition).toBe(0); }); it("leaves a same-document return to the position the browser restores", () => { const scrollTo = jest .spyOn(window, "scrollTo") .mockImplementation(() => {}); const firstVisit = render(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); firstVisit.unmount(); expect(window.history.scrollRestoration).not.toBe("manual"); scrollTo.mockClear(); render(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(scrollTo).not.toHaveBeenCalled(); expect(window.history.scrollRestoration).not.toBe("manual"); }); it("does not reset the visitor's position after intentional scrolling during startup", () => { let position = 0; jest .spyOn(window, "scrollTo") .mockImplementation((options: ScrollToOptions | number) => { if (typeof options === "object") position = options.top ?? position; }); render(); position = 600; fireEvent.wheel(window, { deltaY: 600 }); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(position).toBe(600); }); it("waits for the home layout on fragment arrival, then never steals focus on refresh", () => { window.history.replaceState(null, "", "/#contact"); render(); const contact = screen.getByRole("region", { name: "Contato" }); expect(contact).not.toHaveFocus(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(contact).toHaveFocus(); screen.getByRole("button", { name: "Read biography" }).focus(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect( screen.getByRole("button", { name: "Read biography" }), ).toHaveFocus(); }); it("abandons a pending arrival when the visitor intentionally scrolls", () => { window.history.replaceState(null, "", "/#about"); render(); const message = screen.getByRole("button", { name: "Send message" }); message.focus(); fireEvent.wheel(window, { deltaY: 200 }); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(message).toHaveFocus(); }); it("keeps repeated same-fragment links native while moving focus to the destination", () => { window.history.replaceState(null, "", "/#about"); render(); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); const link = screen.getByRole("link", { name: "Sobre" }); link.focus(); expect(fireEvent.click(link)).toBe(true); expect(screen.getByRole("region", { name: "Sobre" })).toHaveFocus(); link.focus(); expect(fireEvent.click(link)).toBe(true); expect(screen.getByRole("region", { name: "Sobre" })).toHaveFocus(); link.focus(); fireEvent.click(link, { ctrlKey: true }); expect(link).toHaveFocus(); }); it("does not resurrect a stale fragment when the URL changes before readiness", () => { window.history.replaceState(null, "", "/#about"); render(); const message = screen.getByRole("button", { name: "Send message" }); message.focus(); act(() => { window.history.replaceState(null, "", "/#contact"); window.dispatchEvent(new HashChangeEvent("hashchange")); }); fireEvent.click( screen.getByRole("button", { name: "Establish layout" }), ); expect(message).toHaveFocus(); }); });