You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.7 KiB
TypeScript
79 lines
2.7 KiB
TypeScript
/**
|
|
* 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 });
|
|
});
|
|
});
|