fix(notification): remove role=link from view-all button — restores semantically honest button role
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 1m50s
CI / OCR Service Tests (pull_request) Successful in 18s
CI / Backend Unit Tests (pull_request) Successful in 4m12s
CI / fail2ban Regex (pull_request) Successful in 38s
CI / Compose Bucket Idempotency (pull_request) Failing after 10s
CI / Unit & Component Tests (push) Failing after 2m5s
CI / OCR Service Tests (push) Successful in 17s
CI / Backend Unit Tests (push) Successful in 4m14s
CI / fail2ban Regex (push) Successful in 39s
CI / Compose Bucket Idempotency (push) Failing after 12s
nightly / deploy-staging (push) Failing after 2m36s
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 1m50s
CI / OCR Service Tests (pull_request) Successful in 18s
CI / Backend Unit Tests (pull_request) Successful in 4m12s
CI / fail2ban Regex (pull_request) Successful in 38s
CI / Compose Bucket Idempotency (pull_request) Failing after 10s
CI / Unit & Component Tests (push) Failing after 2m5s
CI / OCR Service Tests (push) Successful in 17s
CI / Backend Unit Tests (push) Successful in 4m14s
CI / fail2ban Regex (push) Successful in 39s
CI / Compose Bucket Idempotency (push) Failing after 12s
nightly / deploy-staging (push) Failing after 2m36s
The role=link override on a <button> creates a WCAG 4.1.2 keyboard-contract
mismatch: ARIA role=link tells AT users "press Enter to activate (Space does
nothing)", but the native <button> responds to both Enter and Space. Removes
the override so the element is announced as "button" (accurate).
Test selectors updated from getByRole('link') to getByRole('button')
accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #552.
This commit is contained in:
@@ -135,7 +135,6 @@ function handleViewAll() {
|
||||
<div class="border-t border-line px-4 py-2">
|
||||
<button
|
||||
type="button"
|
||||
role="link"
|
||||
onclick={handleViewAll}
|
||||
class="min-h-[44px] px-1 text-xs font-medium text-ink-2 transition-colors hover:text-ink"
|
||||
>
|
||||
|
||||
@@ -159,7 +159,7 @@ describe('NotificationDropdown', () => {
|
||||
expect(onMarkAllRead).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('calls onClose when the view-all link is clicked', async () => {
|
||||
it('calls onClose when the view-all button is clicked', async () => {
|
||||
const onClose = vi.fn();
|
||||
render(NotificationDropdown, {
|
||||
props: {
|
||||
@@ -170,12 +170,12 @@ describe('NotificationDropdown', () => {
|
||||
}
|
||||
});
|
||||
|
||||
await page.getByRole('link', { name: /alle aktivitäten|view all/i }).click();
|
||||
await page.getByRole('button', { name: /alle aktivitäten|view all/i }).click();
|
||||
|
||||
expect(onClose).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('navigates to /aktivitaeten when the view-all link is clicked', async () => {
|
||||
it('navigates to /aktivitaeten when the view-all button is clicked', async () => {
|
||||
render(NotificationDropdown, {
|
||||
props: {
|
||||
notifications: [],
|
||||
@@ -185,7 +185,7 @@ describe('NotificationDropdown', () => {
|
||||
}
|
||||
});
|
||||
|
||||
await page.getByRole('link', { name: /alle aktivitäten|view all/i }).click();
|
||||
await page.getByRole('button', { name: /alle aktivitäten|view all/i }).click();
|
||||
|
||||
expect(goto).toHaveBeenCalledWith('/aktivitaeten');
|
||||
});
|
||||
@@ -203,7 +203,7 @@ describe('NotificationDropdown', () => {
|
||||
}
|
||||
});
|
||||
|
||||
await page.getByRole('link', { name: /alle aktivitäten|view all/i }).click();
|
||||
await page.getByRole('button', { name: /alle aktivitäten|view all/i }).click();
|
||||
|
||||
expect(callOrder).toEqual(['close', 'goto']);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user