import { test, expect } from '@playwright/test'; async function fetchLink(email: string, kind: 'invite' | 'verify-email' | 'reset-password' | 'accept-invite'): Promise { for (let i = 0; i < 30; i++) { const res = await fetch('http://localhost:8025/api/v1/messages?limit=30'); const data = await res.json() as { messages: { ID: string; To: { Address: string }[] }[] }; const msg = data.messages.find((m) => m.To.some((t) => t.Address === email)); if (msg) { const full = await (await fetch(`http://localhost:8025/api/v1/message/${msg.ID}`)).json() as { Text: string }; const pattern = new RegExp(`https?:\\/\\/[^\\s]+${kind}\\?token=[^\\s]+`); const m = full.Text.match(pattern); if (m) return m[0]; } await new Promise((r) => setTimeout(r, 250)); } throw new Error(`no ${kind} link for ${email}`); } test('admin invites user; user accepts and logs in', async ({ page }) => { const adminEmail = `admin+${Date.now()}@example.com`; const adminPw = 'secretpass'; await page.goto('/register'); await page.getByLabel(/Naam/).fill('Admin'); await page.getByLabel(/E-mailadres/).fill(adminEmail); await page.getByLabel(/Wachtwoord/).fill(adminPw); await page.getByRole('button', { name: /Account aanmaken/ }).click(); await expect(page.getByText(/bevestigingsmail/i)).toBeVisible(); await page.goto(await fetchLink(adminEmail, 'verify-email')); await expect(page.getByRole('link', { name: 'Naar inloggen' })).toBeVisible({ timeout: 10_000 }); await page.goto('/login'); await page.getByLabel(/E-mailadres/).fill(adminEmail); await page.getByLabel(/Wachtwoord/).fill(adminPw); await page.getByRole('button', { name: 'Inloggen' }).click(); // Cold Vite chunks can take a few seconds to compile on the first run. await expect(page.getByRole('button', { name: 'Account menu' })).toBeVisible({ timeout: 15_000 }); await page.goto('/admin/users'); const inviteeEmail = `invitee+${Date.now()}@example.com`; await page.getByPlaceholder(/naam@voorbeeld/).fill(inviteeEmail); await page.getByRole('button', { name: /Uitnodiging sturen/ }).click(); await expect(page.getByText(/Uitnodiging verstuurd/)).toBeVisible(); const inviteLink = await fetchLink(inviteeEmail, 'accept-invite'); // Logout admin via UI menu await page.getByRole('button', { name: 'Account menu' }).click(); await page.getByRole('button', { name: 'Uitloggen' }).click(); await page.goto(inviteLink); await page.getByLabel(/Naam/).fill('Newbie'); await page.getByLabel(/Wachtwoord/).fill('newuserpass'); await page.getByRole('button', { name: /Account aanmaken/ }).click(); await expect(page).toHaveURL(/\/$/); });