From 3ffd9beca01258c2048ac704d599cc0d32e20813 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 9 May 2026 21:16:48 -0400 Subject: [PATCH] fix(web): preserve per-row aria-labels through RowActionsMenu + test fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI vitest run on 3f8a2c5 surfaced 17 failures across 5 test files; this commit addresses 15 that are this batch's responsibility. 1. RowActionsMenu now accepts ariaLabel on RowAction. Defaults to label. Admin pages (requests/quarantine/users) pass per-row aria-labels matching the pre-batch buttons ("Approve Geogaddi", "Resolve Roygbiv", "Make alice admin", etc.) so screen readers + tests find them. 2. PlayerBar.test.ts — anchored regex /^(play|pause)$/i so the new "Player options" overflow ⋮ doesn't also match /play|pause/i. 3. MobileNavDrawer.test.ts — added vi.mock for $app/state, $app/navigation, and $lib/auth/store.svelte (mirrors Shell.test.ts pattern). Without these, SvelteKit's notifiable_store helper isn't bootstrapped in vitest and the suite fails to load. The 2 remaining vitest failures are in /admin/integrations Save flow (putLidarrConfig spy not called). Untouched by this batch and the recent "Save runs Test first" refactor (bca8622) appears related — flagging for operator verification, not chasing as a regression. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../lib/components/MobileNavDrawer.test.ts | 20 ++++++++++++++++- web/src/lib/components/PlayerBar.test.ts | 4 +++- web/src/lib/components/RowActionsMenu.svelte | 6 +++++ web/src/routes/admin/quarantine/+page.svelte | 22 ++++++++++++++++--- web/src/routes/admin/requests/+page.svelte | 22 ++++++++++++++++--- web/src/routes/admin/users/+page.svelte | 6 +++++ 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/web/src/lib/components/MobileNavDrawer.test.ts b/web/src/lib/components/MobileNavDrawer.test.ts index c094d85b..a1e66b48 100644 --- a/web/src/lib/components/MobileNavDrawer.test.ts +++ b/web/src/lib/components/MobileNavDrawer.test.ts @@ -1,5 +1,23 @@ -import { describe, it, expect, beforeEach } from 'vitest'; +import { describe, it, expect, beforeEach, vi } from 'vitest'; import { render, screen } from '@testing-library/svelte'; + +// SvelteKit's $app/state and $app/navigation can't be imported in vitest +// without bootstrapping the runtime; stub them. Mirrors the pattern used +// by Shell.test.ts and other route tests. +vi.mock('$app/state', () => ({ + page: { url: new URL('http://localhost/') } +})); + +vi.mock('$app/navigation', () => ({ + goto: vi.fn() +})); + +// auth/store reads $app — stub the bits MobileNavDrawer touches. +vi.mock('$lib/auth/store.svelte', () => ({ + user: { value: { username: 'alice', is_admin: false } }, + logout: vi.fn().mockResolvedValue(undefined) +})); + import MobileNavDrawer from './MobileNavDrawer.svelte'; import { mobileNav, openMobileNav, closeMobileNav } from '$lib/stores/mobileNav.svelte'; diff --git a/web/src/lib/components/PlayerBar.test.ts b/web/src/lib/components/PlayerBar.test.ts index 859666ca..71c7f5cd 100644 --- a/web/src/lib/components/PlayerBar.test.ts +++ b/web/src/lib/components/PlayerBar.test.ts @@ -105,7 +105,9 @@ describe('PlayerBar', () => { test('play button click calls togglePlay', async () => { render(PlayerBar); - await fireEvent.click(screen.getByRole('button', { name: /play|pause/i })); + // Anchored regex — "Player options" (the new overflow ⋮) also matches + // /play|pause/i otherwise. + await fireEvent.click(screen.getByRole('button', { name: /^(play|pause)$/i })); expect(togglePlay).toHaveBeenCalledTimes(1); }); diff --git a/web/src/lib/components/RowActionsMenu.svelte b/web/src/lib/components/RowActionsMenu.svelte index 68886e2c..281a9a79 100644 --- a/web/src/lib/components/RowActionsMenu.svelte +++ b/web/src/lib/components/RowActionsMenu.svelte @@ -9,6 +9,10 @@ onclick: () => void; danger?: boolean; disabled?: boolean; + /** Override the accessible name (defaults to label). Use to disambiguate + identical labels across rows for screen readers + tests, e.g. + `Approve {row.title}`. */ + ariaLabel?: string; } @@ -46,6 +50,7 @@