- admin: add exact:true to tab button assertions to avoid strict-mode
violations from "Benutzer löschen" title buttons matching "Benutzer"
- admin: change tag-row locator from hasText regex on <li> to has: span
filter (more robust against whitespace differences); add waitForSelector
after tab click to ensure panel is rendered before hovering
- auth: replace page.request.get('/api/users/me') with a profile page
navigation — direct browser requests don't carry Basic Auth, only
server-side SvelteKit fetches do
- documents: use getByRole('heading') instead of getByText to avoid strict
mode violation when the title appears in both h1 and breadcrumb
- persons: same heading fix for person creation landing page
- profile: remove success-message assertion after password change; the
auth_token cookie still holds old credentials so use:enhance's update()
immediately gets a 401 and redirects to /login before the message renders
— test now asserts the redirect directly, then re-logs in
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
3.1 KiB
TypeScript
74 lines
3.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { login } from './helpers/auth';
|
|
|
|
/**
|
|
* These tests run WITHOUT the stored session so they can test the login flow itself.
|
|
* Playwright's storageState is only applied for the 'chromium' project, which depends
|
|
* on the 'setup' project. These tests use a fresh context via test.use({ storageState: undefined }).
|
|
*/
|
|
test.use({ storageState: { cookies: [], origins: [] } });
|
|
|
|
test.describe('Authentication', () => {
|
|
test('login page renders correctly', async ({ page }) => {
|
|
await page.goto('/login');
|
|
await expect(page.getByLabel('Benutzername')).toBeVisible();
|
|
await expect(page.getByLabel('Passwort')).toBeVisible();
|
|
await expect(page.getByRole('button', { name: 'Anmelden' })).toBeVisible();
|
|
await page.screenshot({ path: 'test-results/e2e/login-page.png' });
|
|
});
|
|
|
|
test('redirects unauthenticated users to /login', async ({ page }) => {
|
|
await page.goto('/');
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await page.screenshot({ path: 'test-results/e2e/auth-redirect.png' });
|
|
});
|
|
|
|
test('protected routes redirect to /login without session', async ({ page }) => {
|
|
for (const url of ['/documents/new', '/persons', '/conversations']) {
|
|
await page.goto(url);
|
|
await expect(page).toHaveURL(/\/login/);
|
|
}
|
|
});
|
|
|
|
test('shows an error for wrong credentials', async ({ page }) => {
|
|
await page.goto('/login');
|
|
await page.getByLabel('Benutzername').fill('nichtexistent');
|
|
await page.getByLabel('Passwort').fill('falschespasswort');
|
|
await page.getByRole('button', { name: 'Anmelden' }).click();
|
|
// Stays on login, shows error
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await expect(page.locator('.text-red-600')).toBeVisible();
|
|
await page.screenshot({ path: 'test-results/e2e/login-error.png' });
|
|
});
|
|
|
|
test('login with valid credentials redirects to home', async ({ page }) => {
|
|
await login(page);
|
|
await expect(page).toHaveURL('/');
|
|
await expect(page.getByPlaceholder('Suche in Titel, Inhalt, Ort...')).toBeVisible();
|
|
await page.screenshot({ path: 'test-results/e2e/login-success.png' });
|
|
});
|
|
|
|
test('login establishes a session that authenticates API calls', async ({ page }) => {
|
|
// Guards against regressions where the session cookie is set but broken.
|
|
// The profile page calls /api/users/me server-side — if auth works end-to-end,
|
|
// it loads without redirecting to /login.
|
|
await login(page);
|
|
await page.goto('/profile');
|
|
await expect(page).toHaveURL('/profile');
|
|
await expect(page.getByRole('heading', { name: /Mein Profil/i })).toBeVisible();
|
|
await page.screenshot({ path: 'test-results/e2e/auth-session-valid.png' });
|
|
});
|
|
|
|
test('logout clears the session and redirects to /login', async ({ page }) => {
|
|
await login(page);
|
|
// Logout is inside the user avatar dropdown — open it first
|
|
await page.locator('button[aria-haspopup="true"]').click();
|
|
await page.getByRole('button', { name: 'Abmelden' }).click();
|
|
await expect(page).toHaveURL(/\/login/);
|
|
// Confirm session is gone: navigating to / redirects back
|
|
await page.goto('/');
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await page.screenshot({ path: 'test-results/e2e/logout.png' });
|
|
});
|
|
});
|