[FIX] E2E: Séparer tests authentifiés/non authentifiés dans mvp-integration
- Créer groupe 'Unauthenticated tests' avec storageState vide - Créer groupe 'Authenticated tests' pour tests nécessitant auth - Corriger indentation des tests 1.1 à 1.5 - Test 1.6 utilise maintenant l'état authentifié du global-setup - Corrige erreurs où LoginPage redirigeait car déjà authentifié
This commit is contained in:
parent
bad24d11b1
commit
68839020ba
2 changed files with 142 additions and 122 deletions
|
|
@ -6,15 +6,23 @@
|
|||
"localStorage": [
|
||||
{
|
||||
"name": "veza_access_token",
|
||||
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc2OTUzNSwiaWF0IjoxNzY2NzY4NjM1LCJqdGkiOiJkMmJkYTQ2NC05N2ZiLTQ5NjAtYmU0MC1lNjk3NGM5Y2I5N2UifQ.Hj8-sN9JYmIGqFDe2Dv-hKSvb6DOShOb5GlsHFm-Ejs"
|
||||
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4Mzg0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiI0M2I4NmM4MC01MWZmLTQwOGEtODQwOS01YzM1NDFiNjdjMDEifQ.vP2LSYsNfZihCm5pbPXpTOYxYP0Y_HqYv4axgd-LT1U"
|
||||
},
|
||||
{
|
||||
"name": "i18nextLng",
|
||||
"value": "en"
|
||||
},
|
||||
{
|
||||
"name": "veza_refresh_token",
|
||||
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6IjMyZDJiOWI3LTNiYjQtNDVmYS1hMjk1LThiM2M1OGU1NTFhYiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM2MDYzNSwiaWF0IjoxNzY2NzY4NjM1LCJqdGkiOiI4NzRhNjQxZS0xYWZhLTRlZjctODFiYy04YWM3Nzc4OWQ3ODUifQ.B1yOlNC97XfQzKX63PTliH8Km1pzmhWMmCE4ss6ufn4"
|
||||
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6ImY5NWYzMWY2LWNiMTItNDRiOC1iMWE0LTZlZWVlZjVlZGY3YiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NDk0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiJiY2JlM2ExMS1mOGZjLTQ3YWUtOTdjZS05MjU4MTYzOTExOTgifQ.jXfWPxE1Orn7_BD1akRb84LUozkKUIPIV76xs39aJ2k"
|
||||
},
|
||||
{
|
||||
"name": "ui-storage",
|
||||
"value": "{\"state\":{\"theme\":\"system\",\"language\":\"en\",\"sidebarOpen\":true},\"version\":0}"
|
||||
},
|
||||
{
|
||||
"name": "auth-storage",
|
||||
"value": "{\"state\":{\"isAuthenticated\":true,\"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc2OTUzNSwiaWF0IjoxNzY2NzY4NjM1LCJqdGkiOiJkMmJkYTQ2NC05N2ZiLTQ5NjAtYmU0MC1lNjk3NGM5Y2I5N2UifQ.Hj8-sN9JYmIGqFDe2Dv-hKSvb6DOShOb5GlsHFm-Ejs\",\"refreshToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6IjMyZDJiOWI3LTNiYjQtNDVmYS1hMjk1LThiM2M1OGU1NTFhYiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM2MDYzNSwiaWF0IjoxNzY2NzY4NjM1LCJqdGkiOiI4NzRhNjQxZS0xYWZhLTRlZjctODFiYy04YWM3Nzc4OWQ3ODUifQ.B1yOlNC97XfQzKX63PTliH8Km1pzmhWMmCE4ss6ufn4\"}}"
|
||||
"value": "{\"state\":{\"isAuthenticated\":true,\"accessToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6ImUyZUB0ZXN0LmNvbSIsInVzZXJuYW1lIjoiZTJldXNlciIsInJvbGUiOiJ1c2VyIiwidG9rZW5fdmVyc2lvbiI6MCwidG9rZW5fdHlwZSI6ImFjY2VzcyIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2Njc4Mzg0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiI0M2I4NmM4MC01MWZmLTQwOGEtODQwOS01YzM1NDFiNjdjMDEifQ.vP2LSYsNfZihCm5pbPXpTOYxYP0Y_HqYv4axgd-LT1U\",\"refreshToken\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkM2U1ZjhmOC02MDcxLTRmZDQtYWVhMi05ZmZkMzU0YmVmZDkiLCJlbWFpbCI6IiIsInJvbGUiOiIiLCJ0b2tlbl92ZXJzaW9uIjowLCJpc19yZWZyZXNoIjp0cnVlLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInRva2VuX2ZhbWlseSI6ImY5NWYzMWY2LWNiMTItNDRiOC1iMWE0LTZlZWVlZjVlZGY3YiIsImlzcyI6InZlemEtYXBpIiwiYXVkIjpbInZlemEtYXBwIl0sImV4cCI6MTc2OTM3NDk0OSwiaWF0IjoxNzY2NzgyOTQ5LCJqdGkiOiJiY2JlM2ExMS1mOGZjLTQ3YWUtOTdjZS05MjU4MTYzOTExOTgifQ.jXfWPxE1Orn7_BD1akRb84LUozkKUIPIV76xs39aJ2k\"}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,136 +49,148 @@ test.describe('MVP Integration Tests - Exhaustifs', () => {
|
|||
let refreshToken: string | null = null;
|
||||
|
||||
test.describe('1. Authentication Flow', () => {
|
||||
|
||||
test('1.1 - Login page loads correctly', async ({ page }) => {
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`);
|
||||
// Tests that require unauthenticated state
|
||||
test.describe('Unauthenticated tests', () => {
|
||||
// Reset storage state to ensure we start unauthenticated
|
||||
test.use({ storageState: { cookies: [], origins: [] } });
|
||||
|
||||
// Vérifier que la page charge
|
||||
await expect(page).toHaveTitle(/login|connexion|veza/i);
|
||||
|
||||
// Vérifier les éléments du formulaire
|
||||
await expect(page.locator('input[type="email"], input[name="email"]')).toBeVisible();
|
||||
await expect(page.locator('input[type="password"]')).toBeVisible();
|
||||
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
||||
|
||||
// Pas d'erreurs console
|
||||
const errors: string[] = [];
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') errors.push(msg.text());
|
||||
test('1.1 - Login page loads correctly', async ({ page }) => {
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`);
|
||||
|
||||
// Vérifier que la page charge
|
||||
await expect(page).toHaveTitle(/login|connexion|veza/i);
|
||||
|
||||
// Vérifier les éléments du formulaire
|
||||
await expect(page.locator('input[type="email"], input[name="email"]')).toBeVisible();
|
||||
await expect(page.locator('input[type="password"]')).toBeVisible();
|
||||
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
||||
|
||||
// Pas d'erreurs console
|
||||
const errors: string[] = [];
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') errors.push(msg.text());
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
const realErrors = errors.filter(e =>
|
||||
!e.includes('favicon') &&
|
||||
!e.includes('ResizeObserver') &&
|
||||
!e.includes('net::ERR')
|
||||
);
|
||||
expect(realErrors).toHaveLength(0);
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
const realErrors = errors.filter(e =>
|
||||
!e.includes('favicon') &&
|
||||
!e.includes('ResizeObserver') &&
|
||||
!e.includes('net::ERR')
|
||||
);
|
||||
expect(realErrors).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('1.2 - Register page loads correctly', async ({ page }) => {
|
||||
test('1.2 - Register page loads correctly', async ({ page }) => {
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/register`);
|
||||
|
||||
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();
|
||||
|
||||
// Vérifier lien vers login
|
||||
const loginLink = page.locator('a[href*="login"], a:has-text("Login"), a:has-text("Connexion")');
|
||||
const loginLinkVisible = await loginLink.first().isVisible().catch(() => false);
|
||||
// Ne pas échouer si le lien n'est pas visible (peut être dans un menu)
|
||||
});
|
||||
|
||||
test('1.3 - Can register new user', async ({ page }) => {
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/register`);
|
||||
|
||||
// Remplir le formulaire
|
||||
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);
|
||||
|
||||
// Si champ confirmation
|
||||
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);
|
||||
}
|
||||
|
||||
// Submit
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Attendre redirection ou message succès
|
||||
await page.waitForURL(/\/(login|dashboard|home)/, { timeout: 15000 }).catch(() => {});
|
||||
|
||||
// Vérifier pas d'erreur visible
|
||||
const errorVisible = await page.locator('.error, [role="alert"]').isVisible().catch(() => false);
|
||||
if (errorVisible) {
|
||||
const errorText = await page.locator('.error, [role="alert"]').textContent();
|
||||
console.log('Registration error:', errorText);
|
||||
// Ne pas échouer immédiatement - peut être un message d'info
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur est créé (via API si nécessaire)
|
||||
// Pour l'instant, on considère que si on arrive ici sans erreur, c'est OK
|
||||
});
|
||||
|
||||
test('1.4 - Can login with registered user', async ({ page }) => {
|
||||
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"]');
|
||||
|
||||
// Attendre redirection vers dashboard
|
||||
await page.waitForURL(/\/(dashboard|home|app)/, { timeout: 15000 });
|
||||
|
||||
// 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();
|
||||
});
|
||||
|
||||
test('1.5 - Protected route redirects when not logged in', async ({ page }) => {
|
||||
// Clear any existing auth
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}`);
|
||||
await page.evaluate(() => {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
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();
|
||||
|
||||
// Vérifier lien vers login
|
||||
const loginLink = page.locator('a[href*="login"], a:has-text("Login"), a:has-text("Connexion")');
|
||||
const loginLinkVisible = await loginLink.first().isVisible().catch(() => false);
|
||||
// Ne pas échouer si le lien n'est pas visible (peut être dans un menu)
|
||||
});
|
||||
|
||||
// Try to access protected route
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/dashboard`);
|
||||
|
||||
// Should redirect to login
|
||||
await page.waitForURL(/\/login/, { timeout: 5000 }).catch(() => {});
|
||||
const currentUrl = page.url();
|
||||
expect(currentUrl).toContain('login');
|
||||
});
|
||||
|
||||
test('1.6 - Can logout', async ({ page }) => {
|
||||
// Login first
|
||||
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 });
|
||||
test('1.3 - Can register new user', async ({ page }) => {
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/register`);
|
||||
|
||||
// Click logout
|
||||
const logoutButton = page.locator('button:has-text("Logout"), button:has-text("Déconnexion"), [data-testid="logout"]');
|
||||
if (await logoutButton.isVisible().catch(() => false)) {
|
||||
await logoutButton.click();
|
||||
// Remplir le formulaire
|
||||
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);
|
||||
|
||||
// Si champ confirmation
|
||||
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);
|
||||
}
|
||||
|
||||
// Submit
|
||||
await page.click('button[type="submit"]');
|
||||
|
||||
// Attendre redirection ou message succès
|
||||
await page.waitForURL(/\/(login|dashboard|home)/, { timeout: 15000 }).catch(() => {});
|
||||
|
||||
// Vérifier pas d'erreur visible
|
||||
const errorVisible = await page.locator('.error, [role="alert"]').isVisible().catch(() => false);
|
||||
if (errorVisible) {
|
||||
const errorText = await page.locator('.error, [role="alert"]').textContent();
|
||||
console.log('Registration error:', errorText);
|
||||
// Ne pas échouer immédiatement - peut être un message d'info
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur est créé (via API si nécessaire)
|
||||
// Pour l'instant, on considère que si on arrive ici sans erreur, c'est OK
|
||||
});
|
||||
|
||||
test('1.4 - Can login with registered user', async ({ page }) => {
|
||||
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"]');
|
||||
|
||||
// Attendre redirection vers dashboard
|
||||
await page.waitForURL(/\/(dashboard|home|app)/, { timeout: 15000 });
|
||||
|
||||
// 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();
|
||||
});
|
||||
|
||||
test('1.5 - Protected route redirects when not logged in', async ({ page }) => {
|
||||
// Clear any existing auth
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}`);
|
||||
await page.evaluate(() => {
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
});
|
||||
|
||||
// Try to access protected route
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/dashboard`);
|
||||
|
||||
// Should redirect to login
|
||||
await page.waitForURL(/\/(login|home|\/)/, { timeout: 5000 });
|
||||
await page.waitForURL(/\/login/, { timeout: 5000 }).catch(() => {});
|
||||
const currentUrl = page.url();
|
||||
expect(currentUrl).toContain('login');
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that require authenticated state
|
||||
test.describe('Authenticated tests', () => {
|
||||
test('1.6 - Can logout', async ({ page }) => {
|
||||
// Login first (if not already authenticated from storageState)
|
||||
await page.goto(`${TEST_CONFIG.FRONTEND_URL}/dashboard`);
|
||||
const isOnDashboard = page.url().includes('/dashboard');
|
||||
if (!isOnDashboard) {
|
||||
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 });
|
||||
}
|
||||
|
||||
// Token should be cleared
|
||||
const token = await page.evaluate(() => localStorage.getItem('access_token'));
|
||||
expect(token).toBeFalsy();
|
||||
}
|
||||
// Click logout
|
||||
const logoutButton = page.locator('button:has-text("Logout"), button:has-text("Déconnexion"), [data-testid="logout"]');
|
||||
if (await logoutButton.isVisible().catch(() => false)) {
|
||||
await logoutButton.click();
|
||||
|
||||
// Should redirect to login
|
||||
await page.waitForURL(/\/(login|home|\/)/, { timeout: 5000 });
|
||||
|
||||
// Token should be cleared
|
||||
const token = await page.evaluate(() => localStorage.getItem('access_token'));
|
||||
expect(token).toBeFalsy();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue