veza/tests/e2e/audit/pixel-perfect/07-borders-radius-shadows.spec.ts
senke 463ad5386b test: update e2e test suite and add audit tests
Refine auth, player, tracks, playlists, search, workflows, edge cases,
forms, responsive, network errors, error boundary, performance, visual
regression, cross-browser, profile, smoke, storybook, chat, and session
tests. Add audit test suite (accessibility, ethical, functional, design
tokens). Update test helpers and visual snapshots.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 16:06:26 +01:00

115 lines
4.8 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { loginViaAPI, navigateTo } from '../helpers';
import { TEST_USERS } from '../design-tokens';
test.describe('BORDURES, ARRONDIS & OMBRES — Cohérence visuelle', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
});
test('Dashboard — les cards ont des border-radius cohérents', async ({ page }) => {
await navigateTo(page, '/dashboard');
const cardRadii = await page.evaluate(() => {
const cards = document.querySelectorAll('[class*="card"], [class*="Card"], [role="article"]');
const radii: Array<{ selector: string; text: string; borderRadius: string }> = [];
cards.forEach(el => {
const style = getComputedStyle(el);
if (style.display === 'none') return;
const br = style.borderRadius;
if (br === '0px') return;
radii.push({
selector: el.getAttribute('data-testid') || (typeof el.className === 'string' ? el.className : '').split(' ').slice(0, 2).join('.'),
text: el.textContent?.trim().slice(0, 20) || '',
borderRadius: br,
});
});
return radii;
});
if (cardRadii.length < 2) return;
// Vérifier la cohérence : toutes les cards du même type devraient avoir le même radius
const uniqueRadii = [...new Set(cardRadii.map(c => c.borderRadius))];
if (uniqueRadii.length > 2) {
console.log(`[RADIUS] ${uniqueRadii.length} border-radius différents sur les cards du dashboard:`);
for (const card of cardRadii) {
console.log(` ${card.selector}: ${card.borderRadius}`);
}
console.log(` FIX: Uniformiser les cards avec rounded-lg (12px) ou rounded-xl (16px)`);
}
// Tolérance de 2 variantes (ex: rounded-lg pour les cards principales, rounded-xl pour les featured)
expect(uniqueRadii.length,
`Trop de border-radius différents (${uniqueRadii.length}) sur les cards: [${uniqueRadii.join(', ')}]. FIX: Uniformiser.`
).toBeLessThanOrEqual(3);
});
test('Boutons — border-radius cohérent par variante', async ({ page }) => {
await navigateTo(page, '/dashboard');
const buttonRadii = await page.evaluate(() => {
const buttons = document.querySelectorAll('button:not([hidden])');
const radii: Array<{ text: string; borderRadius: string; classes: string }> = [];
buttons.forEach(btn => {
const style = getComputedStyle(btn);
if (style.display === 'none' || style.visibility === 'hidden') return;
radii.push({
text: btn.textContent?.trim().slice(0, 20) || btn.getAttribute('aria-label') || '',
borderRadius: style.borderRadius,
classes: (typeof btn.className === 'string' ? btn.className : '').slice(0, 60),
});
});
return radii;
});
// Les boutons devraient utiliser des radius standard du design system
const validRadii = ['4px', '6px', '8px', '12px', '16px', '9999px', '0px'];
const invalidButtons = buttonRadii.filter(b => {
const allCorners = b.borderRadius.split(' ').map(v => v.trim());
return !allCorners.every(corner => validRadii.includes(corner));
});
if (invalidButtons.length > 0) {
console.log(`[RADIUS] Boutons avec border-radius non-standard:`);
for (const b of invalidButtons) {
console.log(` "${b.text}": ${b.borderRadius} — FIX: utiliser rounded-sm (4px), rounded-md (6px), rounded-lg (12px), ou rounded-full (9999px)`);
}
}
});
test('Inputs — tous les champs ont un border radius d\'au moins 6px', async ({ page }) => {
await navigateTo(page, '/settings');
const inputRadii = await page.evaluate(() => {
const inputs = document.querySelectorAll('input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea, select');
return Array.from(inputs)
.filter(el => getComputedStyle(el).display !== 'none')
.map(el => ({
type: (el as HTMLInputElement).type || el.tagName.toLowerCase(),
name: (el as HTMLInputElement).name || (el as HTMLInputElement).placeholder?.slice(0, 20) || '',
borderRadius: getComputedStyle(el).borderRadius,
}));
});
const tooSharp = inputRadii.filter(i => {
const px = parseFloat(i.borderRadius);
return !isNaN(px) && px < 6;
});
if (tooSharp.length > 0) {
console.log(`[RADIUS] Inputs avec radius < 6px (design system minimum: 6px / rounded-md):`);
for (const i of tooSharp) {
console.log(` input[type="${i.type}"] "${i.name}": ${i.borderRadius} — FIX: utiliser rounded-lg (12px)`);
}
}
expect(tooSharp.length,
`${tooSharp.length} inputs avec border-radius trop petit:\n${tooSharp.map(i => `input[type="${i.type}"] "${i.name}": ${i.borderRadius}`).join('\n')}`
).toBe(0);
});
});