veza/tests/e2e/audit/pixel-perfect/17-scroll-containers.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

112 lines
4.5 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { loginViaAPI, navigateTo } from '../helpers';
import { TEST_USERS, VIEWPORTS } from '../design-tokens';
test.describe('SCROLL — Les conteneurs scrollables fonctionnent', () => {
test.beforeEach(async ({ page }) => {
await loginViaAPI(page, TEST_USERS.listener.email, TEST_USERS.listener.password);
});
test('Header reste sticky/fixed au scroll', async ({ page }) => {
await navigateTo(page, '/dashboard');
// Scroller vers le bas
await page.evaluate(() => window.scrollTo(0, 500));
await page.waitForTimeout(300);
const headerState = await page.evaluate(() => {
const header = document.querySelector('header, [data-testid="app-header"], [role="banner"]');
if (!header) return null;
const rect = header.getBoundingClientRect();
const style = getComputedStyle(header);
return {
top: Math.round(rect.top),
position: style.position,
visible: rect.top >= -5 && rect.top < 100,
};
});
if (headerState) {
console.log(`[SCROLL] Header après scroll: position=${headerState.position}, top=${headerState.top}px, visible=${headerState.visible}`);
expect(headerState.visible,
`ÉLÉMENT: header | PAGE: /dashboard | MESURÉ: top=${headerState.top}px après scroll | ATTENDU: visible (top < 100px) | FIX TAILWIND: Ajouter sticky top-0 z-50 sur le header`
).toBe(true);
}
});
test('Sidebar reste fixed au scroll', async ({ page }) => {
await page.setViewportSize(VIEWPORTS.desktop);
await navigateTo(page, '/dashboard');
await page.evaluate(() => window.scrollTo(0, 500));
await page.waitForTimeout(300);
const sidebarState = await page.evaluate(() => {
const sidebar = document.querySelector('[data-testid="app-sidebar"]');
if (!sidebar) return null;
const rect = sidebar.getBoundingClientRect();
const style = getComputedStyle(sidebar);
return {
top: Math.round(rect.top),
position: style.position,
height: Math.round(rect.height),
visible: rect.height > 200,
};
});
if (sidebarState) {
console.log(`[SCROLL] Sidebar après scroll: position=${sidebarState.position}, top=${sidebarState.top}px`);
expect(sidebarState.visible,
`ÉLÉMENT: [data-testid="app-sidebar"] | PAGE: /dashboard | MESURÉ: height=${sidebarState.height}px après scroll | ATTENDU: visible (height > 200px) | FIX TAILWIND: Ajouter fixed ou sticky sur le sidebar`
).toBe(true);
}
});
test('Scroller tout en bas ne casse pas le layout', async ({ page }) => {
await navigateTo(page, '/discover');
// Scroller tout en bas
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForTimeout(500);
// Vérifier que rien n'est cassé
const layout = await page.evaluate(() => {
const body = document.body.textContent || '';
const hasError = /500|Internal Server Error|undefined|null/.test(body);
const viewportWidth = document.documentElement.clientWidth;
const scrollWidth = document.documentElement.scrollWidth;
return {
hasError,
horizontalOverflow: scrollWidth > viewportWidth + 5,
bodyLength: body.length,
};
});
expect(layout.hasError, 'Erreur visible après scroll tout en bas').toBe(false);
expect(layout.horizontalOverflow,
`Scroll horizontal apparu après scroll vertical. scrollWidth=${await page.evaluate(() => document.documentElement.scrollWidth)}px > viewport`
).toBe(false);
});
test('Sidebar scrollable si contenu dépasse', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 600 }); // Hauteur réduite pour forcer le scroll
await navigateTo(page, '/dashboard');
const sidebarScroll = await page.evaluate(() => {
const sidebar = document.querySelector('[data-testid="app-sidebar"]');
if (!sidebar) return null;
const nav = sidebar.querySelector('nav') || sidebar;
return {
scrollHeight: nav.scrollHeight,
clientHeight: nav.clientHeight,
isScrollable: nav.scrollHeight > nav.clientHeight + 10,
overflow: getComputedStyle(nav).overflowY,
};
});
if (sidebarScroll && sidebarScroll.isScrollable) {
console.log(`[SCROLL] Sidebar nav scrollable: ${sidebarScroll.scrollHeight}px content dans ${sidebarScroll.clientHeight}px container, overflow=${sidebarScroll.overflow}`);
expect(['auto', 'scroll', 'overlay']).toContain(sidebarScroll.overflow);
}
});
});