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>
101 lines
4.5 KiB
TypeScript
101 lines
4.5 KiB
TypeScript
import { test, expect } from '@chromatic-com/playwright';
|
|
import { loginViaAPI, navigateTo, CONFIG } from '../helpers';
|
|
import { TEST_USERS } from '../design-tokens';
|
|
|
|
test.describe('TOASTS AVANCÉS — Positionnement, style et timing', () => {
|
|
test('Les toasts apparaissent en haut à droite (pas au centre)', async ({ page }) => {
|
|
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
|
|
await navigateTo(page, '/settings');
|
|
|
|
// Provoquer un toast — chercher un bouton de sauvegarde ou action
|
|
const saveBtn = page.locator('button').filter({ hasText: /sauvegarder|save|enregistrer|mettre à jour|update/i }).first();
|
|
if (await saveBtn.isVisible({ timeout: 5_000 }).catch(() => false)) {
|
|
await saveBtn.click();
|
|
await page.waitForTimeout(2_000);
|
|
}
|
|
|
|
// Vérifier la position des toasts s'il y en a
|
|
const toastInfo = await page.evaluate(() => {
|
|
const toasts = document.querySelectorAll('[data-testid="toast-alert"], [role="alert"][class*="toast"], [class*="Toast"]');
|
|
if (toasts.length === 0) return null;
|
|
|
|
const first = toasts[0];
|
|
const rect = first.getBoundingClientRect();
|
|
const vw = window.innerWidth;
|
|
const vh = window.innerHeight;
|
|
|
|
return {
|
|
x: Math.round(rect.x),
|
|
y: Math.round(rect.y),
|
|
width: Math.round(rect.width),
|
|
isTopRight: rect.right > vw * 0.5 && rect.top < vh * 0.3,
|
|
isBottomRight: rect.right > vw * 0.5 && rect.bottom > vh * 0.7,
|
|
isCentered: rect.left > vw * 0.25 && rect.right < vw * 0.75,
|
|
};
|
|
});
|
|
|
|
if (toastInfo) {
|
|
console.log(`[TOAST] Position: x=${toastInfo.x}, y=${toastInfo.y}, w=${toastInfo.width}`);
|
|
console.log(` Top-right: ${toastInfo.isTopRight}, Bottom-right: ${toastInfo.isBottomRight}, Centered: ${toastInfo.isCentered}`);
|
|
}
|
|
});
|
|
|
|
test('Toast d\'erreur a le style vermillion (rouge)', 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('nonexistent@test.com');
|
|
await page.locator('input[type="password"]').fill('WrongPassword!');
|
|
await page.getByTestId('login-submit').click();
|
|
await page.waitForTimeout(3_000);
|
|
|
|
const toastStyle = await page.evaluate(() => {
|
|
const toast = document.querySelector('[data-testid="toast-alert"], [role="alert"]');
|
|
if (!toast) return null;
|
|
const style = getComputedStyle(toast);
|
|
const bg = style.backgroundColor;
|
|
const text = toast.textContent?.trim().slice(0, 50) || '';
|
|
|
|
// Parse RGB to check if it's reddish
|
|
const match = bg.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
let isReddish = false;
|
|
if (match) {
|
|
const [r, g, b] = [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])];
|
|
isReddish = r > g && r > b;
|
|
}
|
|
|
|
return { bg, text, isReddish, borderColor: style.borderColor };
|
|
});
|
|
|
|
if (toastStyle) {
|
|
console.log(`[TOAST STYLE] Error toast: bg=${toastStyle.bg}, text="${toastStyle.text}", isReddish=${toastStyle.isReddish}`);
|
|
}
|
|
});
|
|
|
|
test('Toasts n\'empêchent pas l\'interaction avec le reste de la page', async ({ page }) => {
|
|
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
|
|
await navigateTo(page, '/dashboard');
|
|
|
|
// S'il y a un toast, vérifier que les éléments derrière sont cliquables
|
|
const toast = page.getByTestId('toast-alert').first();
|
|
if (await toast.isVisible({ timeout: 3_000 }).catch(() => false)) {
|
|
const toastBox = await toast.boundingBox();
|
|
if (toastBox) {
|
|
// Vérifier le z-index du toast
|
|
const zIndex = await toast.evaluate(el => parseInt(getComputedStyle(el).zIndex) || 0);
|
|
console.log(`[TOAST] z-index: ${zIndex}, position: ${toastBox.x},${toastBox.y}`);
|
|
|
|
// Les toasts doivent avoir pointer-events: auto mais ne pas avoir pointer-events: none sur les éléments en dessous
|
|
const blocksClick = await page.evaluate((box) => {
|
|
const el = document.elementFromPoint(box.x + box.width / 2, box.y + box.height + 10);
|
|
return el ? getComputedStyle(el).pointerEvents : 'none';
|
|
}, toastBox);
|
|
|
|
expect(blocksClick, 'Les éléments sous le toast ne sont pas cliquables (pointer-events bloqué)').not.toBe('none');
|
|
}
|
|
}
|
|
});
|
|
});
|