CI / verify (push) Failing after 5m9s
Align the notebook browser with the physical LCD, refresh real project captures and navigation, simplify service content, and stabilize hero hydration.
104 lines
3.5 KiB
TypeScript
104 lines
3.5 KiB
TypeScript
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
import { useHomeFragmentNavigation } from "./useHomeFragmentNavigation";
|
|
|
|
function HomeNavigation() {
|
|
const onLayoutReady = useHomeFragmentNavigation();
|
|
return (
|
|
<>
|
|
<button type="button" onClick={onLayoutReady}>
|
|
Establish notebook layout
|
|
</button>
|
|
<a href="/#about">Sobre</a>
|
|
<a href="/#contact">Contato</a>
|
|
<section id="about" aria-label="Sobre">
|
|
<button type="button">Read biography</button>
|
|
</section>
|
|
<section id="contact" aria-label="Contato">
|
|
<button type="button">Send message</button>
|
|
</section>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const originalScrollIntoView = HTMLElement.prototype.scrollIntoView;
|
|
|
|
beforeEach(() => {
|
|
window.history.replaceState(null, "", "/");
|
|
HTMLElement.prototype.scrollIntoView = jest.fn();
|
|
});
|
|
|
|
afterEach(() => {
|
|
window.history.replaceState(null, "", "/");
|
|
if (originalScrollIntoView) {
|
|
HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
|
|
} else {
|
|
Reflect.deleteProperty(HTMLElement.prototype, "scrollIntoView");
|
|
}
|
|
});
|
|
|
|
describe("home fragment navigation", () => {
|
|
it("waits for the notebook layout on fragment arrival, then never steals focus on refresh", () => {
|
|
window.history.replaceState(null, "", "/#contact");
|
|
render(<HomeNavigation />);
|
|
const contact = screen.getByRole("region", { name: "Contato" });
|
|
expect(contact).not.toHaveFocus();
|
|
|
|
fireEvent.click(
|
|
screen.getByRole("button", { name: "Establish notebook layout" }),
|
|
);
|
|
expect(contact).toHaveFocus();
|
|
screen.getByRole("button", { name: "Read biography" }).focus();
|
|
fireEvent.click(
|
|
screen.getByRole("button", { name: "Establish notebook 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(<HomeNavigation />);
|
|
const message = screen.getByRole("button", { name: "Send message" });
|
|
message.focus();
|
|
fireEvent.wheel(window, { deltaY: 200 });
|
|
fireEvent.click(
|
|
screen.getByRole("button", { name: "Establish notebook layout" }),
|
|
);
|
|
expect(message).toHaveFocus();
|
|
});
|
|
|
|
it("keeps repeated same-fragment links native while moving focus to the destination", () => {
|
|
window.history.replaceState(null, "", "/#about");
|
|
render(<HomeNavigation />);
|
|
fireEvent.click(
|
|
screen.getByRole("button", { name: "Establish notebook 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(<HomeNavigation />);
|
|
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 notebook layout" }),
|
|
);
|
|
expect(message).toHaveFocus();
|
|
});
|
|
});
|