diff --git a/apps/web/e2e/.auth/user.json b/apps/web/e2e/.auth/user.json index bc119cb3d..2a09b3bc3 100644 --- a/apps/web/e2e/.auth/user.json +++ b/apps/web/e2e/.auth/user.json @@ -6,7 +6,7 @@ "localStorage": [ { "name": "veza_access_token", - "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4Mzg0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiI0M2I4NmM4MC01MWZmLTQwOGEtODQwOS01YzM1NDFiNjdjMDEifQ.vP2LSYsNfZihCm5pbPXpTOYxYP0Y_HqYv4axgd-LT1U" + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4NDQ3OSwiaWF0IjoxNzY2NzgzNTc5LCJqdGkiOiJmOGIyNzk3ZS1lYjdhLTRlYjUtODA0OS04YzYzMTUwZWQwNGYifQ.KWQoJxvubPJjnCaMdWLbszmEoo7vxWjwlrAVpw3_B_Y" }, { "name": "i18nextLng", @@ -14,7 +14,7 @@ }, { "name": "veza_refresh_token", - "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6ImY5NWYzMWY2LWNiMTItNDRiOC1iMWE0LTZlZWVlZjVlZGY3YiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NDk0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiJiY2JlM2ExMS1mOGZjLTQ3YWUtOTdjZS05MjU4MTYzOTExOTgifQ.jXfWPxE1Orn7_BD1akRb84LUozkKUIPIV76xs39aJ2k" + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6IjZmMmEyMTRlLTEzNDUtNDZlMC04MWVkLWY4YzU3MDZmM2FhNCIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NTU3OSwiaWF0IjoxNzY2NzgzNTc5LCJqdGkiOiIwZmZkYjZmYS1kODk2LTQxZWItOWEzZC1mZjczZDlhODhjMjAifQ.kelw3VZXE3J-0d_I1sxC1IOhLfY42cEC6qtwyLYyERg" }, { "name": "ui-storage", @@ -22,7 +22,7 @@ }, { "name": "auth-storage", - "value": "{\"state\":{\"isAuthenticated\":true,\"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4Mzg0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiI0M2I4NmM4MC01MWZmLTQwOGEtODQwOS01YzM1NDFiNjdjMDEifQ.vP2LSYsNfZihCm5pbPXpTOYxYP0Y_HqYv4axgd-LT1U\",\"refreshToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6ImY5NWYzMWY2LWNiMTItNDRiOC1iMWE0LTZlZWVlZjVlZGY3YiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NDk0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiJiY2JlM2ExMS1mOGZjLTQ3YWUtOTdjZS05MjU4MTYzOTExOTgifQ.jXfWPxE1Orn7_BD1akRb84LUozkKUIPIV76xs39aJ2k\"}}" + "value": "{\"state\":{\"isAuthenticated\":true,\"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4NDQ3OSwiaWF0IjoxNzY2NzgzNTc5LCJqdGkiOiJmOGIyNzk3ZS1lYjdhLTRlYjUtODA0OS04YzYzMTUwZWQwNGYifQ.KWQoJxvubPJjnCaMdWLbszmEoo7vxWjwlrAVpw3_B_Y\",\"refreshToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6IjZmMmEyMTRlLTEzNDUtNDZlMC04MWVkLWY4YzU3MDZmM2FhNCIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NTU3OSwiaWF0IjoxNzY2NzgzNTc5LCJqdGkiOiIwZmZkYjZmYS1kODk2LTQxZWItOWEzZC1mZjczZDlhODhjMjAifQ.kelw3VZXE3J-0d_I1sxC1IOhLfY42cEC6qtwyLYyERg\"}}" } ] } diff --git a/apps/web/e2e/mvp-integration.spec.ts b/apps/web/e2e/mvp-integration.spec.ts index 3a462a4a1..59cced844 100644 --- a/apps/web/e2e/mvp-integration.spec.ts +++ b/apps/web/e2e/mvp-integration.spec.ts @@ -84,7 +84,8 @@ test.describe('MVP Integration Tests - Exhaustifs', () => { await expect(page.locator('input[type="email"], input[name="email"]')).toBeVisible(); await expect(page.locator('input[name="username"]')).toBeVisible(); - await expect(page.locator('input[type="password"]')).toBeVisible(); + // Use first password field to avoid strict mode violation (there are 2 password fields: password and password_confirm) + await expect(page.locator('input[type="password"]').first()).toBeVisible(); // Vérifier lien vers login const loginLink = page.locator('a[href*="login"], a:has-text("Login"), a:has-text("Connexion")'); @@ -127,23 +128,68 @@ test.describe('MVP Integration Tests - Exhaustifs', () => { test('1.4 - Can login with registered user', async ({ page }) => { await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`); + // Wait for form to be ready + await page.waitForSelector('input[type="email"], input[name="email"]', { timeout: 5000 }); + await page.fill('input[type="email"], input[name="email"]', TEST_USER.email); await page.fill('input[type="password"]', TEST_USER.password); + + // Wait a bit for form to be ready + await page.waitForTimeout(500); + + // Submit form await page.click('button[type="submit"]'); - // Attendre redirection vers dashboard - await page.waitForURL(/\/(dashboard|home|app)/, { timeout: 15000 }); + // Wait for either success (redirect) or error message + await Promise.race([ + page.waitForURL(/\/(dashboard|home|app)/, { timeout: 15000 }).catch(() => null), + page.waitForSelector('.error, [role="alert"], .alert', { timeout: 5000 }).catch(() => null), + ]); - // Vérifier que l'utilisateur est connecté - const loggedIn = await page.locator('[data-testid="user-menu"], .user-avatar, .logout-button, nav[role="navigation"]').isVisible().catch(() => false); - - // Vérifier localStorage - const token = await page.evaluate(() => - localStorage.getItem('access_token') || - localStorage.getItem('accessToken') || - localStorage.getItem('veza_access_token') - ); - expect(token || loggedIn).toBeTruthy(); + // Check if we're on dashboard (success) + const currentUrl = page.url(); + if (currentUrl.includes('/dashboard') || currentUrl.includes('/home') || currentUrl.includes('/app')) { + // Success - verify user is logged in + const loggedIn = await page.locator('[data-testid="user-menu"], .user-avatar, .logout-button, nav[role="navigation"]').isVisible().catch(() => false); + + // Vérifier localStorage + const token = await page.evaluate(() => + localStorage.getItem('access_token') || + localStorage.getItem('accessToken') || + localStorage.getItem('veza_access_token') + ); + expect(token || loggedIn).toBeTruthy(); + } else { + // Check for error message + const errorText = await page.locator('.error, [role="alert"], .alert').textContent().catch(() => ''); + console.log('Login error:', errorText); + + // If error says "Invalid credentials", the user might not exist yet + // This can happen if test 1.3 didn't complete successfully + if (errorText.includes('Invalid credentials') || errorText.includes('invalid')) { + // Try to register first, then login + console.log('User might not exist, trying to register first...'); + await page.goto(`${TEST_CONFIG.FRONTEND_URL}/register`); + await page.fill('input[type="email"], input[name="email"]', TEST_USER.email); + await page.fill('input[name="username"]', TEST_USER.username); + await page.fill('input[type="password"]', TEST_USER.password); + const confirmField = page.locator('input[name="password_confirmation"], input[name="confirmPassword"], input[name="passwordConfirm"]'); + if (await confirmField.isVisible().catch(() => false)) { + await confirmField.fill(TEST_USER.password); + } + await page.click('button[type="submit"]'); + await page.waitForURL(/\/(login|dashboard|home)/, { timeout: 15000 }).catch(() => {}); + + // Now try login again + await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`); + await page.fill('input[type="email"], input[name="email"]', TEST_USER.email); + await page.fill('input[type="password"]', TEST_USER.password); + await page.click('button[type="submit"]'); + await page.waitForURL(/\/(dashboard|home|app)/, { timeout: 15000 }); + } else { + throw new Error(`Login failed with error: ${errorText}`); + } + } }); test('1.5 - Protected route redirects when not logged in', async ({ page }) => {