From a5fa7f71d351642dfbbab50a8791dc81aa825dea Mon Sep 17 00:00:00 2001 From: Emeka-12 Date: Tue, 20 Oct 2026 19:23:27 +0100 Subject: [PATCH] =?UTF-8?q?fix(a11y):=20skip=20link=20CSS,=20audit=20refer?= =?UTF-8?q?ence,=20output=20region,=20focus=20indicators=20(#96=E2=80=93#9?= =?UTF-8?q?9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #96: Add .skip-link CSS rule so the existing skip-to-main-content link appears visually when focused (position absolute, slides into view on :focus) - #97: Add audit command reference section (id="audit-reference") with ready-to-run command, argument docs, and step-by-step guidance; add it to navSections so it is reachable from the main navigation - #98: Add :focus-visible outlines (2px solid --color-accent, offset 3px) to .button and .output button so all interactive states meet WCAG AA 3:1 UI component contrast requirement - #99: Wrap the generated command output in a role="region" named "Generated command output" with an aria-describedby pointer to a visually-hidden description so screen readers announce the region's purpose Tests added for #96 (skip-link class), #97 (section exists, nav link, command docs), and #99 (named region, describedby description). Co-Authored-By: Claude Sonnet 4.6 --- src/App.test.tsx | 46 ++++++++++++++++++++++++++++++++++ src/App.tsx | 65 +++++++++++++++++++++++++++++++++++++++++++++++- src/styles.css | 19 ++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/App.test.tsx b/src/App.test.tsx index 233669a..5b4e704 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -767,6 +767,52 @@ describe("Footer changelog link", () => { }); }); +// #96 — skip-to-main-content link visible on focus +describe("Skip-to-main-content link (#96)", () => { + it("carries the skip-link class so the CSS can show it on focus", () => { + render(); + const skipLink = screen.getByRole("link", { name: "Skip to main content" }); + expect(skipLink).toHaveClass("skip-link"); + }); +}); + +// #97 — audit command reference section +describe("Audit command reference (#97)", () => { + it("renders a focusable audit-reference section", () => { + render(); + expect(document.getElementById("audit-reference")).toHaveAttribute("tabindex", "-1"); + expect(screen.getByRole("heading", { name: /audit workflow, at a glance/i })).toBeInTheDocument(); + }); + + it("exposes the audit reference as a navigation link", () => { + render(); + const link = screen.getByRole("link", { name: "Audit reference" }); + expect(link).toHaveAttribute("href", "#audit-reference"); + }); + + it("documents the ready-to-run command and its arguments", () => { + render(); + expect(screen.getByLabelText("Audit command example")).toHaveTextContent("soroban-testkit audit"); + expect(screen.getAllByText("--strict").length).toBeGreaterThan(0); + }); +}); + +// #99 — accessible description for the generated command output +describe("Generated command output accessibility (#99)", () => { + it("wraps the output in a named region", () => { + render(); + expect(screen.getByRole("region", { name: "Generated command output" })).toBeInTheDocument(); + }); + + it("includes a visually-hidden description within the output region", () => { + render(); + const region = screen.getByRole("region", { name: "Generated command output" }); + const desc = document.getElementById(region.getAttribute("aria-describedby") ?? ""); + expect(desc).toBeInTheDocument(); + expect(desc?.textContent).toMatch(/copy this command/i); + }); +}); + // #116 — accessibility statement describe("Accessibility statement", () => { it("renders the accessibility link in the footer", () => { diff --git a/src/App.tsx b/src/App.tsx index 57186b5..641e391 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ const navSections = [ { id: "install", label: "Install" }, { id: "modules", label: "Modules" }, { id: "commands", label: "Commands" }, + { id: "audit-reference", label: "Audit reference" }, { id: "limits-reference", label: "Limits reference" }, ] as const; const navSectionIds = navSections.map((section) => section.id); @@ -1181,7 +1182,15 @@ export default function App() { )} -
+
+ + Copy this command to your terminal to run the selected workflow. + {highlightCommand(generated)}
@@ -1477,6 +1486,60 @@ export default function App() { )} +
+
+

Command reference

+

Audit workflow, at a glance.

+

+ Use soroban-testkit audit to scan contract sources for authentication + gaps, arithmetic pitfalls, and TTL misuse. The scan is read-only and runs entirely + offline. +

+
+
+
+

Ready-to-run command

+
{"soroban-testkit audit \\\n  ./src \\\n  --strict"}
+

+ Replace ./src with the path to your contract source directory. Omit{" "} + --strict to treat warnings as informational only. +

+
+
+

Arguments

+
+
+
path
+
+ Contract source directory. Defaults to{" "} + {localFileGuides.audit.defaultPath}. +
+
+
+
--strict
+
Treat warning-level findings as errors and exit non-zero.
+
+
+
+
+

Before you run it

+
    +
  1. Point the path at the directory that contains your *.rs source files.
  2. +
  3. Review auth and storage warnings first — they surface the most critical privilege issues.
  4. +
  5. Enable strict mode before release to make the audit gate your CI pipeline.
  6. +
+

+ {localFileGuides.audit.offlineGuarantee} +

+
+
+
+