import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import LoginPage from './+page.svelte'; afterEach(cleanup); describe('login page', () => { it('renders the login form by default', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); await expect.element(page.getByRole('heading', { name: /^anmelden$/i })).toBeVisible(); await expect.element(page.getByLabelText(/e-mail-adresse/i)).toBeVisible(); await expect.element(page.getByLabelText(/passwort/i)).toBeVisible(); await expect.element(page.getByRole('button', { name: /^anmelden$/i })).toBeVisible(); }); it('shows the registered-success banner when data.registered is true', async () => { render(LoginPage, { props: { data: { registered: true }, form: undefined } }); await expect .element(page.getByText('Dein Konto wurde erfolgreich erstellt. Melde dich jetzt an.')) .toBeVisible(); }); it('hides the registered-success banner when data.registered is false', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); await expect.element(page.getByRole('status')).not.toBeInTheDocument(); }); it('shows the form error when form.error is set', async () => { render(LoginPage, { props: { data: { registered: false }, form: { error: 'Ungültige Anmeldedaten' } } }); await expect.element(page.getByText('Ungültige Anmeldedaten')).toBeVisible(); }); it('declares POST as the form method and routes to ?/login', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); const form = document.querySelector('form'); expect(form?.getAttribute('method')).toBe('POST'); expect(form?.getAttribute('action')).toBe('?/login'); }); it('exposes the email input as type=email and required', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); const email = document.querySelector('input[name="email"]') as HTMLInputElement; expect(email.type).toBe('email'); expect(email.required).toBe(true); expect(email.autocomplete).toBe('email'); }); it('exposes the password input as type=password and required', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); const pwd = document.querySelector('input[name="password"]') as HTMLInputElement; expect(pwd.type).toBe('password'); expect(pwd.required).toBe(true); expect(pwd.autocomplete).toBe('current-password'); }); it('renders the forgot-password link', async () => { render(LoginPage, { props: { data: { registered: false }, form: undefined } }); await expect .element(page.getByRole('link', { name: /passwort vergessen/i })) .toHaveAttribute('href', '/forgot-password'); }); it('shows rate-limit alert with clock icon when rateLimited is true', async () => { render(LoginPage, { props: { data: { registered: false }, form: { error: 'Zu viele Anmeldeversuche.', rateLimited: true } } }); await expect.element(page.getByRole('alert')).toBeVisible(); await expect.element(page.getByText('Zu viele Anmeldeversuche.')).toBeVisible(); }); });