/** * E2E test: Registration flow. * * Validates the full magic-link registration process: * 1. Navigate to /register * 2. Fill and submit the form (Turnstile auto-passes with test site key) * 3. Extract magic link token from DB * 4. Navigate to verify URL * 5. Assert redirect to home with user email visible */ import { test, expect } from '@playwright/test'; import { createHash } from 'node:crypto'; import { createDbClient } from '../helpers/auth'; test.describe('Registration flow', () => { test('should register a new user and verify via magic link', async ({ page, }) => { const uniqueEmail = `e2e-reg-${Date.now()}@test.local`; // Step 1: Navigate to the registration page await page.goto('/register'); // Verify we see the registration form await expect( page.locator('h2', { hasText: 'Creer un compte' }), ).toBeVisible(); // Step 2: Fill in the email field await page.locator('#email').fill(uniqueEmail); // Optionally fill display name await page.locator('#displayName').fill('E2E Test User'); // Wait for Turnstile widget to auto-verify with the test site key. // The Cloudflare test key (1x00000000000000000000AA) always passes immediately. await page.waitForTimeout(3000); // Step 3: Submit the registration form await page.locator('button[type="submit"]').click(); // Wait for success message (form shows "check inbox" screen) await expect( page.getByText('Verifiez votre boite de reception'), ).toBeVisible({ timeout: 10_000 }); // Step 4: Create a known magic token in the DB for verification const knownRawToken = `e2e-reg-token-${Date.now()}`; const knownTokenHash = createHash('sha256') .update(knownRawToken) .digest('hex'); const expiresAt = new Date(Date.now() + 15 * 60 * 1000).toISOString(); const client = createDbClient(); await client.connect(); try { await client.query( `INSERT INTO magic_tokens (email, token_hash, expires_at, used) VALUES ($1, $2, $3, false)`, [uniqueEmail.toLowerCase(), knownTokenHash, expiresAt], ); } finally { await client.end(); } // Step 5: Navigate to the GET verify endpoint with the raw token. // This endpoint verifies the token, creates a session, sets the cookie, // and redirects to APP_URL. await page.goto(`/api/v1/auth/verify?token=${knownRawToken}`); // The verify endpoint redirects to the app URL. Wait for the home page. await page.waitForURL('**/', { timeout: 15_000 }); // Step 6: Assert the user email is visible in the navbar await expect(page.getByText(uniqueEmail)).toBeVisible({ timeout: 10_000 }); }); });