Files
familienarchiv/frontend/src/lib/document/transcription/TranscriptionPanelHeader.svelte.test.ts
Marcel 9572b062f1 refactor(test): use getByRole instead of data-testid in TranscriptionPanelHeader test
Per Felix's review on issue #496, tests should query observable behaviour via
ARIA roles, not test-only data-testid attributes. Replaces every
'document.querySelector([data-testid=...])' with 'page.getByRole(...)'.
The disabled-button click test uses force: true so Playwright bypasses its
enabled-check — the behaviour under test is precisely that the click is
ignored.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00

121 lines
3.5 KiB
TypeScript

import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import TranscriptionPanelHeader from './TranscriptionPanelHeader.svelte';
afterEach(cleanup);
const baseProps = {
mode: 'read' as const,
hasBlocks: true,
blockCount: 3,
lastEditedAt: null,
onModeChange: () => {},
onClose: () => {}
};
describe('TranscriptionPanelHeader', () => {
it('renders the Lesen and Bearbeiten toggle buttons', async () => {
render(TranscriptionPanelHeader, baseProps);
await expect.element(page.getByRole('button', { name: /lesen/i })).toBeVisible();
await expect.element(page.getByRole('button', { name: /bearbeiten/i })).toBeVisible();
});
it('marks the Lesen button as aria-disabled when hasBlocks is false', async () => {
render(TranscriptionPanelHeader, {
...baseProps,
mode: 'edit',
hasBlocks: false,
blockCount: 0
});
await expect
.element(page.getByRole('button', { name: /lesen/i }))
.toHaveAttribute('aria-disabled', 'true');
});
it('calls onModeChange("edit") when the Bearbeiten button is clicked', async () => {
const onModeChange = vi.fn();
render(TranscriptionPanelHeader, { ...baseProps, onModeChange });
await page.getByRole('button', { name: /bearbeiten/i }).click();
expect(onModeChange).toHaveBeenCalledWith('edit');
});
it('does not call onModeChange when the disabled Lesen button is clicked', async () => {
const onModeChange = vi.fn();
render(TranscriptionPanelHeader, {
...baseProps,
mode: 'edit',
hasBlocks: false,
blockCount: 0,
onModeChange
});
await page.getByRole('button', { name: /lesen/i }).click({ force: true });
expect(onModeChange).not.toHaveBeenCalled();
});
it('calls onClose when the close button is clicked', async () => {
const onClose = vi.fn();
render(TranscriptionPanelHeader, { ...baseProps, onClose });
await page.getByRole('button', { name: /panel schließen/i }).click();
expect(onClose).toHaveBeenCalledOnce();
});
it('shows the singular section label when blockCount is 1', async () => {
render(TranscriptionPanelHeader, { ...baseProps, blockCount: 1 });
await expect.element(page.getByText('1 Abschnitt')).toBeVisible();
});
it('shows the plural section label when blockCount is greater than 1', async () => {
render(TranscriptionPanelHeader, { ...baseProps, blockCount: 5 });
await expect.element(page.getByText('5 Abschnitte')).toBeVisible();
});
it('shows "0 Abschnitte" when blockCount is 0', async () => {
render(TranscriptionPanelHeader, {
...baseProps,
hasBlocks: false,
blockCount: 0,
mode: 'edit'
});
await expect.element(page.getByText('0 Abschnitte')).toBeVisible();
});
it('renders the formatted last-edit date when lastEditedAt is provided', async () => {
render(TranscriptionPanelHeader, {
...baseProps,
lastEditedAt: '2026-04-07T10:00:00Z'
});
await expect.element(page.getByText(/2026/)).toBeVisible();
});
it('renders the help popover trigger', async () => {
render(TranscriptionPanelHeader, baseProps);
await expect
.element(page.getByRole('button', { name: /lese- und bearbeitungsmodus/i }))
.toBeVisible();
});
it('opens the help popover when the help trigger is clicked', async () => {
render(TranscriptionPanelHeader, baseProps);
await page.getByRole('button', { name: /lese- und bearbeitungsmodus/i }).click();
await expect
.element(page.getByRole('button', { name: /lese- und bearbeitungsmodus/i }))
.toHaveAttribute('aria-expanded', 'true');
});
});