import { test, expect } from '@playwright/test'; import { execSync } from 'child_process'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const baseUrl = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:4173'; const urlMatch = baseUrl.match(/:(\d+)$/); const PORT = urlMatch ? urlMatch[1] : '4173'; const ALPHA_URL = `http://ecole-alpha.classeo.local:${PORT}`; const ADMIN_EMAIL = 'e2e-creation-admin@example.com'; const ADMIN_PASSWORD = 'CreationTest123'; const UNIQUE_SUFFIX = Date.now(); const INVITED_EMAIL = `e2e-invited-prof-${UNIQUE_SUFFIX}@example.com`; test.describe('User Creation', () => { test.describe.configure({ mode: 'serial' }); test.beforeAll(async () => { const projectRoot = join(__dirname, '../..'); const composeFile = join(projectRoot, 'compose.yaml'); execSync( `docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${ADMIN_EMAIL} --password=${ADMIN_PASSWORD} --role=ROLE_ADMIN 2>&1`, { encoding: 'utf-8' } ); }); async function loginAsAdmin(page: import('@playwright/test').Page) { await page.goto(`${ALPHA_URL}/login`); await page.locator('#email').fill(ADMIN_EMAIL); await page.locator('#password').fill(ADMIN_PASSWORD); await Promise.all([ page.waitForURL(/\/dashboard/, { timeout: 10000 }), page.getByRole('button', { name: /se connecter/i }).click() ]); } test('admin can invite a user with roles array', async ({ page }) => { await loginAsAdmin(page); await page.goto(`${ALPHA_URL}/admin/users`); // Wait for users table or empty state to load await expect( page.locator('.users-table, .empty-state') ).toBeVisible({ timeout: 10000 }); // Click "Inviter un utilisateur" await page.getByRole('button', { name: /inviter un utilisateur/i }).first().click(); // Modal should appear await expect(page.locator('#modal-title')).toBeVisible(); await expect(page.locator('#modal-title')).toHaveText('Inviter un utilisateur'); // Fill in the form await page.locator('#user-firstname').fill('Marie'); await page.locator('#user-lastname').fill('Curie'); await page.locator('#user-email').fill(INVITED_EMAIL); // Select "Enseignant" role via checkbox (this sends roles[] without role singular) await page.locator('.role-checkbox-label', { hasText: 'Enseignant' }).click(); // Submit the form (target the modal's submit button specifically) const modal = page.locator('.modal'); await modal.getByRole('button', { name: "Envoyer l'invitation" }).click(); // Verify success message await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 }); await expect(page.locator('.alert-success')).toContainText(INVITED_EMAIL); // Verify the user appears in the table await expect(page.locator('.users-table')).toBeVisible({ timeout: 10000 }); const newUserRow = page.locator('tr', { has: page.locator(`text=${INVITED_EMAIL}`) }); await expect(newUserRow).toBeVisible(); await expect(newUserRow).toContainText('Marie'); await expect(newUserRow).toContainText('Curie'); await expect(newUserRow).toContainText('Enseignant'); await expect(newUserRow).toContainText('En attente'); }); });