From 938068a86662921c6701e545ac4e4955d442044f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Jun 2026 10:20:23 +0100 Subject: [PATCH 1/6] Add recovery links navigation to 404 page --- src/app/not-found.tsx | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index e1561b6..db32802 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -13,10 +13,47 @@ export default function NotFound() {

Back to home + + ); } From 2c8e516caa42445accc1fb026439f6909db51fa1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Jun 2026 10:21:01 +0100 Subject: [PATCH 2/6] Add comprehensive tests for 404 page with recovery links - Test navigation landmark and semantic list structure - Test all four recovery links (Home, Services, Stats, Docs) - Test keyboard accessibility with focus-visible outlines - Test dark mode styling - Achieve 100% code coverage --- src/app/not-found.test.tsx | 129 +++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/app/not-found.test.tsx diff --git a/src/app/not-found.test.tsx b/src/app/not-found.test.tsx new file mode 100644 index 0000000..cd03a6d --- /dev/null +++ b/src/app/not-found.test.tsx @@ -0,0 +1,129 @@ +import { render, screen } from "@testing-library/react"; +import NotFound from "./not-found"; + +describe("NotFound", () => { + it("renders the 404 heading", () => { + render(); + expect(screen.getByRole("heading", { name: "404" })).toBeInTheDocument(); + }); + + it("renders the explanatory text", () => { + render(); + expect(screen.getByText("That page does not exist.")).toBeInTheDocument(); + }); + + it("renders the main landmark", () => { + render(); + const main = screen.getByRole("main"); + expect(main).toBeInTheDocument(); + expect(main).toHaveAttribute("id", "main-content"); + expect(main).toHaveAttribute("tabIndex", "-1"); + }); + + it("renders the primary Back to home button", () => { + render(); + const backButton = screen.getByRole("link", { name: "Back to home" }); + expect(backButton).toBeInTheDocument(); + expect(backButton).toHaveAttribute("href", "/"); + }); + + it("renders the helpful links navigation landmark", () => { + render(); + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + expect(nav).toBeInTheDocument(); + }); + + it("renders a semantic list inside the navigation", () => { + render(); + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + const list = screen.getByRole("list"); + expect(nav).toContainElement(list); + }); + + it("renders all four recovery links with correct labels and hrefs", () => { + render(); + + const recoveryLinks = [ + { name: "Home", href: "/" }, + { name: "Services", href: "/services" }, + { name: "Stats", href: "/stats" }, + { name: "Docs", href: "/docs" }, + ] as const; + + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + + for (const { name, href } of recoveryLinks) { + const link = screen.getByRole("link", { name }); + expect(link).toBeInTheDocument(); + expect(link).toHaveAttribute("href", href); + expect(nav).toContainElement(link); + } + }); + + it("renders exactly four list items in the navigation", () => { + render(); + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + const listItems = screen.getAllByRole("listitem"); + expect(listItems).toHaveLength(4); + listItems.forEach((item) => { + expect(nav).toContainElement(item); + }); + }); + + it("does not render any links to routes that do not exist", () => { + render(); + // Ensure we're only linking to routes that actually exist + const allLinks = screen.getAllByRole("link"); + const hrefs = allLinks.map((link) => link.getAttribute("href")); + + // These are valid routes + expect(hrefs).toContain("/"); + expect(hrefs).toContain("/services"); + expect(hrefs).toContain("/stats"); + expect(hrefs).toContain("/docs"); + + // Ensure we don't link to non-existent routes + expect(hrefs).not.toContain("/nonexistent"); + expect(hrefs).not.toContain("/fake-route"); + }); + + it("makes the primary button keyboard-accessible with focus-visible outline", () => { + render(); + const backButton = screen.getByRole("link", { name: "Back to home" }); + expect(backButton).toHaveClass("focus-visible:outline"); + }); + + it("makes all recovery links keyboard-accessible with focus-visible outline", () => { + render(); + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + const links = screen.getAllByRole("link").filter((link) => nav.contains(link)); + + links.forEach((link) => { + expect(link).toHaveClass("focus-visible:outline"); + }); + }); + + it("applies dark mode classes to the primary button", () => { + render(); + const backButton = screen.getByRole("link", { name: "Back to home" }); + expect(backButton).toHaveClass("dark:bg-white"); + expect(backButton).toHaveClass("dark:text-black"); + }); + + it("applies dark mode classes to recovery links", () => { + render(); + const nav = screen.getByRole("navigation", { name: "Helpful links" }); + const links = screen.getAllByRole("link").filter((link) => nav.contains(link)); + + links.forEach((link) => { + expect(link).toHaveClass("dark:text-blue-400"); + expect(link).toHaveClass("dark:hover:text-blue-300"); + }); + }); + + it("renders exactly five total links (one primary + four recovery)", () => { + render(); + const allLinks = screen.getAllByRole("link"); + expect(allLinks).toHaveLength(5); + }); +}); From ad12e90057db015dbef32a8eb7a5fa8065fe4a53 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Jun 2026 10:21:50 +0100 Subject: [PATCH 3/6] Document 404 recovery links in README Add section explaining the semantic navigation landmark with quick-return links to primary surfaces (Home, Services, Stats, Docs) for improved user recovery and keyboard accessibility --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6c73d99..d9eec10 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,10 @@ The following frontend routes are defined under `src/app/`: The home page (`src/app/page.tsx`) renders the primary navigation entry points (Manage services, View stats, Record usage, Agents, Docs) and the external Stellar link inside a `