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>
48 lines
2.4 KiB
TypeScript
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);
|
|
});
|
|
}
|
|
});
|