All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m20s
CI / OCR Service Tests (pull_request) Successful in 19s
CI / Backend Unit Tests (pull_request) Successful in 3m33s
CI / fail2ban Regex (pull_request) Successful in 44s
CI / Semgrep Security Scan (pull_request) Successful in 21s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m1s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Language selector', () => {
|
|
test('shows DE, EN, ES buttons in the header', async ({ page }) => {
|
|
await page.goto('/');
|
|
await expect(
|
|
page.getByRole('banner').getByRole('button', { name: 'DE', exact: true })
|
|
).toBeVisible();
|
|
await expect(
|
|
page.getByRole('banner').getByRole('button', { name: 'EN', exact: true })
|
|
).toBeVisible();
|
|
await expect(
|
|
page.getByRole('banner').getByRole('button', { name: 'ES', exact: true })
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('switching to EN translates the navigation', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForSelector('[data-hydrated]');
|
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
|
await expect(
|
|
page.getByRole('navigation').getByRole('link', { name: 'Documents' })
|
|
).toBeVisible();
|
|
await expect(page.getByRole('navigation').getByRole('link', { name: 'Persons' })).toBeVisible();
|
|
});
|
|
|
|
test('language choice persists after navigation', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForSelector('[data-hydrated]');
|
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
|
await page.goto('/persons');
|
|
await expect(
|
|
page.getByRole('navigation').getByRole('link', { name: 'Documents' })
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('switching back to DE restores German', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForSelector('[data-hydrated]');
|
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
|
await expect(
|
|
page.getByRole('navigation').getByRole('link', { name: 'Documents' })
|
|
).toBeVisible();
|
|
await page.getByRole('banner').getByRole('button', { name: 'DE', exact: true }).click();
|
|
// In headless Chromium, cookie deletion via document.cookie can be unreliable.
|
|
// Delete the PARAGLIDE_LOCALE cookie directly so the next navigation defaults to DE.
|
|
await page.context().clearCookies({ name: 'PARAGLIDE_LOCALE' });
|
|
await page.goto('/');
|
|
await page.waitForSelector('[data-hydrated]');
|
|
await expect(
|
|
page.getByRole('navigation').getByRole('link', { name: 'Dokumente' })
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('active language button is visually highlighted', async ({ page }) => {
|
|
await page.goto('/');
|
|
const deBtn = page.getByRole('banner').getByRole('button', { name: 'DE', exact: true });
|
|
await expect(deBtn).toHaveClass(/font-bold/);
|
|
});
|
|
});
|
|
|
|
test.describe('Mobile nav — i18n', () => {
|
|
test('hamburger button aria-label translates to EN on narrow viewport', async ({ browser }) => {
|
|
const context = await browser.newContext({
|
|
viewport: { width: 375, height: 812 },
|
|
storageState: 'e2e/.auth/user.json'
|
|
});
|
|
const page = await context.newPage();
|
|
await page.goto('/');
|
|
await page.waitForSelector('[data-hydrated]');
|
|
await page.getByRole('banner').getByRole('button', { name: 'EN', exact: true }).click();
|
|
|
|
await expect(page.getByRole('button', { name: 'Open menu' })).toBeVisible();
|
|
|
|
await context.close();
|
|
});
|
|
});
|