test(app-shell): cover sidebar brand link to dashboard

Two new SSR tests in `app-shell.test.tsx`:

- Desktop sidebar's brand header is now a link, not a static <div>.
  Asserts the <aside> contains an <a href="/" aria-label="Go to
  dashboard"> at the top. The slice is scoped to the <aside> via a
  new `extractSidebar` helper so it can't accidentally match the
  mobile-header brand link.

- Mobile and desktop brand links carry distinct aria-labels
  ("Go home" vs "Go to dashboard"). On a wide window where the
  desktop sidebar is visible alongside the (sm:hidden) mobile
  header — which technically can't happen at any one breakpoint
  but is a useful invariant for screen readers in split-screen /
  zoom contexts — the two announcements stay distinguishable.

Total: 212 web tests passing (was 210).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
yiekheng 2026-05-10 12:55:39 +08:00
parent 551021a2c7
commit ce42a89af5

View File

@ -242,6 +242,35 @@ describe("AppShell — desktop sidebar (SSR)", () => {
// appear in the sidebar (we removed it from the mobile drawer). // appear in the sidebar (we removed it from the mobile drawer).
expect(html).toContain('data-testid="theme-toggle"'); expect(html).toContain('data-testid="theme-toggle"');
}); });
it("sidebar brand header is a link to / with a 'Go to dashboard' aria-label", () => {
pathnameMock.mockReturnValue("/accounts");
const html = renderToStaticMarkup(
<AppShell>
<div />
</AppShell>,
);
// Scope to the sidebar: it's the <aside> element. Pull just the
// <aside>...</aside> slice so this assertion can't accidentally
// match the mobile-header brand link (which has aria-label="Go home").
const sidebarSlice = extractSidebar(html);
expect(sidebarSlice).toMatch(
/<a\b[^>]*href="\/"[^>]*aria-label="Go to dashboard"|<a\b[^>]*aria-label="Go to dashboard"[^>]*href="\/"/,
);
});
it("mobile header brand link uses 'Go home' (separate copy from sidebar)", () => {
// Make sure the two brand-link aria-labels stay distinct so screen-
// reader users on a wide-window split-screen don't hear two
// identical announcements when both are visible.
const html = renderToStaticMarkup(
<AppShell>
<div />
</AppShell>,
);
expect(html).toContain('aria-label="Go home"');
expect(html).toContain('aria-label="Go to dashboard"');
});
}); });
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -265,3 +294,15 @@ function extractSheet(html: string): string {
if (open === -1) return ""; if (open === -1) return "";
return html.slice(open); return html.slice(open);
} }
/**
* Pull just the desktop <aside>...</aside> slice. The shell renders
* the sidebar first, then the mobile header, so the closing
* </aside> tag cleanly separates the two brand markup blocks.
*/
function extractSidebar(html: string): string {
const open = html.indexOf("<aside");
if (open === -1) return "";
const close = html.indexOf("</aside>", open);
return html.slice(open, close === -1 ? html.length : close + "</aside>".length);
}