veza/tests/e2e/audit/pixel-perfect/16-loading-states.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

48 lines
2.4 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { loginViaAPI } from '../helpers';
import { TEST_USERS, ROUTES } from '../design-tokens';
test.describe('LOADING — Les états de chargement sont propres', () => {
for (const route of ROUTES.listener.slice(0, 8)) {
test(`${route.name} — pas de flash de contenu vide pendant le chargement`, async ({ page }) => {
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
// Ralentir les requêtes API de 400ms pour observer le loading state
await page.route('**/api/v1/**', async route => {
await new Promise(r => setTimeout(r, 400));
await route.continue();
});
await page.goto(route.path, { waitUntil: 'commit' });
// Pendant le chargement, capturer ce qui est visible
const loadingSnapshot = await page.evaluate(() => {
const hasLoader = !!document.querySelector(
'[class*="skeleton"], [class*="spinner"], [class*="loading"], [role="progressbar"], [class*="shimmer"], [class*="animate-pulse"], [class*="Loader"]'
);
const hasSplash = !!document.querySelector('[class*="splash"], [class*="Splash"]');
const mainText = document.querySelector('main, [role="main"]')?.textContent?.trim().length || 0;
return { hasLoader, hasSplash, mainTextLength: mainText };
}).catch(() => ({ hasLoader: false, hasSplash: false, mainTextLength: 0 }));
// Attendre que la page se charge complètement
await page.waitForLoadState('networkidle').catch(() => {});
await page.locator('main, [role="main"]').first().waitFor({ state: 'visible', timeout: 20_000 }).catch(() => {});
const finalSnapshot = await page.evaluate(() => {
const main = document.querySelector('main, [role="main"]');
return {
mainTextLength: main?.textContent?.trim().length || 0,
hasContent: (main?.textContent?.trim().length || 0) > 30,
};
});
console.log(`[LOADING] ${route.path}: loader=${loadingSnapshot.hasLoader}, splash=${loadingSnapshot.hasSplash}, final_content=${finalSnapshot.mainTextLength}chars`);
// La page doit avoir du contenu une fois chargée
expect(finalSnapshot.hasContent,
`${route.path} ne rend aucun contenu après chargement (${finalSnapshot.mainTextLength} chars). La page est possiblement cassée.`
).toBe(true);
});
}
});