import { test, expect } from '@playwright/test' import { resetDb } from './helpers/api' /** * Scénarios auth : login après signup, logout, refresh session, * redirection si non auth, validation des form errors signup/login. * * Le signup happy path est couvert ailleurs (signup.spec.ts) — ici on * se concentre sur les autres flows + edge cases. */ async function signupAndOnboard(page: import('@playwright/test').Page) { const email = `auth+${Date.now()}@rubis.test` const password = 'motdepasse-fort-123' await page.goto('/signup') await page.getByLabel(/Prénom \/ Nom/i).fill('Auth Test') await page.getByLabel(/Email professionnel/i).fill(email) await page.getByLabel(/Mot de passe/i).fill(password) await page.getByRole('button', { name: /créer mon compte/i }).click() await page.waitForURL(/\/onboarding\/compte/, { timeout: 10_000 }) await page.getByRole('button', { name: /continuer/i }).click() await page.waitForURL(/\/onboarding\/entreprise/) await page.getByLabel(/nom de l'entreprise/i).fill('Auth SARL') await page.getByRole('button', { name: /continuer/i }).click() await page.waitForURL(/\/onboarding\/signature/) await page.getByRole('button', { name: /terminer/i }).click() await page.waitForURL('/', { timeout: 10_000 }) return { email, password } } test.describe('Auth — signup validations', () => { test.beforeEach(async () => { await resetDb() }) test('refuse un email invalide (HTML5 validation)', async ({ page }) => { await page.goto('/signup') await page.getByLabel(/Prénom \/ Nom/i).fill('Test') await page.getByLabel(/Email professionnel/i).fill('pas-un-email') await page.getByLabel(/Mot de passe/i).fill('motdepasse-fort-123') await page.getByRole('button', { name: /créer mon compte/i }).click() // L'input email[required] devrait être marqué invalid par le navigateur. // On reste sur /signup (pas de navigation). await expect(page).toHaveURL(/\/signup/) }) test('refuse un email déjà pris (422 → toast erreur)', async ({ page }) => { const email = `taken+${Date.now()}@rubis.test` // 1er signup OK await page.goto('/signup') await page.getByLabel(/Prénom \/ Nom/i).fill('First') await page.getByLabel(/Email professionnel/i).fill(email) await page.getByLabel(/Mot de passe/i).fill('motdepasse-fort-123') await page.getByRole('button', { name: /créer mon compte/i }).click() await page.waitForURL(/\/onboarding/) // Tentative de re-signup avec le même email → toast erreur await page.goto('/signup') await page.getByLabel(/Prénom \/ Nom/i).fill('Second') await page.getByLabel(/Email professionnel/i).fill(email) await page.getByLabel(/Mot de passe/i).fill('motdepasse-fort-123') await page.getByRole('button', { name: /créer mon compte/i }).click() // Toast Sonner avec message "Un compte existe déjà avec cet email." await expect(page.getByText(/existe déjà avec cet email/i)).toBeVisible({ timeout: 5_000, }) await expect(page).toHaveURL(/\/signup/) }) }) test.describe('Auth — login', () => { test.beforeEach(async () => { await resetDb() }) test('login après signup → dashboard', async ({ page, context }) => { const { email, password } = await signupAndOnboard(page) // Clear cookies + open new context-like session pour forcer un re-login await context.clearCookies() await page.goto('/login') await page.getByLabel(/^Email$/i).fill(email) await page.getByLabel(/^Mot de passe$/i).fill(password) await page.getByRole('button', { name: /^se connecter$/i }).click() await expect(page).toHaveURL('/', { timeout: 10_000 }) await expect(page.getByText(/rubis.*gagnés/i)).toBeVisible({ timeout: 10_000 }) }) test('mauvais password → 401 + toast erreur, reste sur /login', async ({ page, }) => { const { email } = await signupAndOnboard(page) await page.goto('/login') await page.getByLabel(/^Email$/i).fill(email) await page.getByLabel(/^Mot de passe$/i).fill('mauvais-mot-de-passe') await page.getByRole('button', { name: /^se connecter$/i }).click() await expect( page.getByText(/email ou mot de passe incorrect/i), ).toBeVisible({ timeout: 5_000 }) await expect(page).toHaveURL(/\/login/) }) test('email inconnu → 401 + toast erreur', async ({ page }) => { await page.goto('/login') await page.getByLabel(/^Email$/i).fill('inconnu@nulle-part.test') await page.getByLabel(/^Mot de passe$/i).fill('peu-importe-fort-123') await page.getByRole('button', { name: /^se connecter$/i }).click() await expect( page.getByText(/email ou mot de passe incorrect/i), ).toBeVisible({ timeout: 5_000 }) }) }) test.describe('Auth — protection des routes', () => { test.beforeEach(async () => { await resetDb() }) test('accéder à / sans session → redirige sur /login', async ({ page, context }) => { await context.clearCookies() await page.goto('/') await expect(page).toHaveURL(/\/login/, { timeout: 5_000 }) }) test('accéder à /factures sans session → redirige sur /login', async ({ page, context, }) => { await context.clearCookies() await page.goto('/factures') await expect(page).toHaveURL(/\/login/, { timeout: 5_000 }) }) })