Fix 11 page.goto() calls in 6 test files that used relative URLs without baseURL (incompatible with @chromatic-com/playwright). Functional audit: 44/50 pass (6 test-level issues, not app bugs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
4.9 KiB
TypeScript
97 lines
4.9 KiB
TypeScript
import { test, expect } from '@chromatic-com/playwright';
|
||
import { loginViaAPI, loginViaUI, navigateTo, waitForToast, CONFIG } from '../helpers';
|
||
import { TEST_USERS } from '../design-tokens';
|
||
|
||
test.describe('TOASTS & NOTIFICATIONS — Apparaissent, disparaissent, ne cachent rien', () => {
|
||
test('Login réussi — un toast ou redirection se produit', async ({ page }) => {
|
||
await loginViaUI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
|
||
|
||
// Soit un toast de succès apparaît, soit on est redirigé
|
||
const redirected = page.url().includes('/dashboard') || page.url().includes('/feed');
|
||
const toast = page.getByTestId('toast-alert').first();
|
||
const toastVisible = await toast.isVisible({ timeout: 3_000 }).catch(() => false);
|
||
|
||
expect(redirected || toastVisible, 'Ni redirection ni toast après login').toBe(true);
|
||
|
||
if (toastVisible) {
|
||
// Vérifier que le toast ne cache pas de bouton important
|
||
const toastBox = await toast.boundingBox();
|
||
if (toastBox) {
|
||
console.log(`[TOAST] Position: x=${toastBox.x} y=${toastBox.y} w=${toastBox.width} h=${toastBox.height}`);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('Login échoué — un toast d\'erreur ou message d\'erreur apparaît', async ({ page }) => {
|
||
await page.goto(CONFIG.baseURL + '/login', { waitUntil: 'domcontentloaded' });
|
||
await page.waitForLoadState('networkidle').catch(() => {});
|
||
await page.locator('main, [role="main"]').first().waitFor({ state: 'visible', timeout: 15_000 }).catch(() => {});
|
||
|
||
const email = page.locator('input[type="email"]');
|
||
await email.waitFor({ state: 'visible', timeout: 10_000 });
|
||
await email.fill('wrong@wrong.com');
|
||
await page.locator('input[type="password"]').fill('WrongPassword123!');
|
||
await page.getByTestId('login-submit').click();
|
||
await page.waitForTimeout(3_000);
|
||
|
||
// Un message d'erreur doit être visible (toast ou inline)
|
||
const errorToast = page.getByTestId('toast-alert').first();
|
||
const inlineError = page.locator('[role="alert"], [class*="error"], [class*="destructive"]').first();
|
||
const toastVisible = await errorToast.isVisible().catch(() => false);
|
||
const inlineVisible = await inlineError.isVisible().catch(() => false);
|
||
|
||
console.log(`[TOAST] Error toast visible: ${toastVisible}, inline error visible: ${inlineVisible}`);
|
||
expect(toastVisible || inlineVisible, 'Aucun feedback d\'erreur après login échoué').toBe(true);
|
||
});
|
||
|
||
test('Toast — ne bloque pas les boutons du header ou sidebar', async ({ page }) => {
|
||
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
|
||
await navigateTo(page, '/dashboard');
|
||
|
||
// Essayer de provoquer un toast (par exemple, action qui échoue)
|
||
// Pour l'instant, vérifier que s'il y a un toast, il est dans un coin non-bloquant
|
||
const toast = page.getByTestId('toast-alert').first();
|
||
if (await toast.isVisible({ timeout: 3_000 }).catch(() => false)) {
|
||
const toastBox = await toast.boundingBox();
|
||
const sidebar = page.locator('[data-testid="app-sidebar"]');
|
||
const sidebarBox = await sidebar.boundingBox().catch(() => null);
|
||
|
||
if (toastBox && sidebarBox) {
|
||
const overlapX = Math.max(0, Math.min(toastBox.x + toastBox.width, sidebarBox.x + sidebarBox.width) - Math.max(toastBox.x, sidebarBox.x));
|
||
const overlapY = Math.max(0, Math.min(toastBox.y + toastBox.height, sidebarBox.y + sidebarBox.height) - Math.max(toastBox.y, sidebarBox.y));
|
||
|
||
if (overlapX > 0 && overlapY > 0) {
|
||
console.log(`[TOAST] Le toast recouvre le sidebar de ${overlapX}×${overlapY}px`);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
test('Toast — disparaît automatiquement après ~4 secondes', async ({ page }) => {
|
||
// Ce test nécessite qu'un toast soit affiché — on peut le provoquer via login
|
||
await page.goto(CONFIG.baseURL + '/login', { waitUntil: 'domcontentloaded' });
|
||
await page.waitForLoadState('networkidle').catch(() => {});
|
||
await page.locator('main, [role="main"]').first().waitFor({ state: 'visible', timeout: 15_000 }).catch(() => {});
|
||
|
||
// Login invalide pour provoquer un toast d'erreur
|
||
const email = page.locator('input[type="email"]');
|
||
await email.waitFor({ state: 'visible', timeout: 10_000 });
|
||
await email.fill('nonexistent@test.com');
|
||
await page.locator('input[type="password"]').fill('WrongPass123!');
|
||
await page.getByTestId('login-submit').click();
|
||
|
||
const toast = page.getByTestId('toast-alert').first();
|
||
const appeared = await toast.isVisible({ timeout: 5_000 }).catch(() => false);
|
||
|
||
if (appeared) {
|
||
console.log('[TOAST] Toast d\'erreur apparu — vérification auto-dismiss...');
|
||
|
||
// Attendre qu'il disparaisse (typiquement 4s)
|
||
await toast.waitFor({ state: 'hidden', timeout: 8_000 }).catch(() => {});
|
||
const stillVisible = await toast.isVisible().catch(() => false);
|
||
|
||
console.log(`[TOAST] Encore visible après 8s: ${stillVisible}`);
|
||
// Ce n'est pas bloquant si le toast reste (peut avoir un bouton close)
|
||
}
|
||
});
|
||
});
|