fix(admin): locale-agnostic OcrHealthBar tests, focus rings on all OCR links
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m33s
CI / OCR Service Tests (push) Successful in 42s
CI / Backend Unit Tests (push) Failing after 2m45s
CI / Backend Unit Tests (pull_request) Failing after 2m44s
CI / Unit & Component Tests (pull_request) Failing after 2m43s
CI / OCR Service Tests (pull_request) Successful in 47s

OcrHealthBar spec used /online/i and /offline/i text matchers that would fail
in Spanish locale — replaced with CSS class assertions on role="img" dot.

Added focus-visible:ring-2/ring-brand-navy/rounded-sm to all links in OCR
admin pages (OcrModelsTable person+details, global history link, back-links
in global and personId detail pages) to satisfy WCAG 2.4.7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-18 09:23:39 +02:00
parent 269894a47a
commit 794000cbd1
5 changed files with 13 additions and 8 deletions

View File

@@ -34,7 +34,7 @@ const { trainingInfo } = $derived(data);
</h2>
<a
href="/admin/ocr/global"
class="text-xs font-medium text-brand-navy/60 transition-colors hover:text-brand-navy"
class="text-xs font-medium text-brand-navy/60 transition-colors hover:text-brand-navy focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>
{m.ocr_global_history_link()}
</a>

View File

@@ -1,6 +1,5 @@
import { afterEach, describe, it, expect } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import OcrHealthBar from './OcrHealthBar.svelte';
afterEach(cleanup);
@@ -8,11 +7,13 @@ afterEach(cleanup);
describe('OcrHealthBar', () => {
it('shows online status when OCR service is available', async () => {
render(OcrHealthBar, { ocrServiceAvailable: true });
await expect.element(page.getByText(/online/i)).toBeInTheDocument();
const dot = document.querySelector('[role="img"]');
expect(dot?.className).toContain('bg-green-500');
});
it('shows offline status when OCR service is unavailable', async () => {
render(OcrHealthBar, { ocrServiceAvailable: false });
await expect.element(page.getByText(/offline/i)).toBeInTheDocument();
const dot = document.querySelector('[role="img"]');
expect(dot?.className).toContain('bg-red-500');
});
});

View File

@@ -42,7 +42,10 @@ let {
{#each senderModels as model (model.id)}
<tr>
<td class="border-brand-sand/50 border-b py-3">
<a href="/admin/ocr/{model.personId}" class="text-brand-navy hover:underline">
<a
href="/admin/ocr/{model.personId}"
class="text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>
{personNames[model.personId] ?? model.personId}
</a>
</td>
@@ -58,7 +61,8 @@ let {
<td class="border-brand-sand/50 border-b py-3">
<a
href="/admin/ocr/{model.personId}"
class="font-medium text-brand-navy hover:underline">{m.ocr_table_details()}</a
class="font-medium text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>{m.ocr_table_details()}</a
>
</td>
</tr>

View File

@@ -11,7 +11,7 @@ const personName = $derived(data.history.personNames?.[params.personId] ?? 'Unkn
<div class="flex items-center gap-4">
<a
href="/admin/ocr"
class="group inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy"
class="group inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>
<svg
class="mr-2 h-4 w-4 transform transition-transform group-hover:-translate-x-1"

View File

@@ -10,7 +10,7 @@ let { data }: { data: PageData } = $props();
<div class="flex items-center gap-4">
<a
href="/admin/ocr"
class="group inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy"
class="group inline-flex items-center text-xs font-bold tracking-widest text-gray-500 uppercase transition-colors hover:text-brand-navy focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
>
<svg
class="mr-2 h-4 w-4 transform transition-transform group-hover:-translate-x-1"