fix(ui): resolve 3 visual overlap bugs + fix e2e test base URLs

Visual fixes found by pixel-perfect audit tests:
- Sidebar: add pb-4 to nav to prevent Community/Settings overlap
- TrackCard: add pr-14 to action overlay to prevent play/more button overlap
- Layout: increase --main-offset-bottom to 9rem for player bar clearance

Test infra:
- Fix helpers.ts to prepend CONFIG.baseURL for @chromatic-com/playwright
  compatibility (page.goto needs absolute URLs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
senke 2026-03-25 02:53:47 +01:00
parent 6fad0ad68d
commit d177ead617
4 changed files with 10 additions and 8 deletions

View file

@ -213,7 +213,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ currentView }) => {
{/* Nav — Discord/Spotify: pill indicator, micro-animations, section dividers */}
<nav
className="flex-1 overflow-y-auto custom-scrollbar px-3 py-2"
className="flex-1 overflow-y-auto custom-scrollbar px-3 pt-2 pb-4"
role="navigation"
aria-label="Main navigation"
>

View file

@ -148,7 +148,7 @@ function TrackCardComponent({
{/* Gradient Overlay for Actions */}
{showActions && (
<div className="absolute inset-x-0 bottom-0 p-2 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-[var(--sumi-duration-normal)] flex justify-end gap-2">
<div className="absolute inset-x-0 bottom-0 p-2 pr-14 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-[var(--sumi-duration-normal)] flex justify-end gap-2">
<LikeButton
trackId={track.id}
initialLikeCount={likeCount}

View file

@ -309,7 +309,7 @@
/* App shell — header, main offsets and margins (sidebar-driven) */
--header-height: 4rem;
--main-offset-top: 5rem;
--main-offset-bottom: 7.5rem;
--main-offset-bottom: 9rem;
--mobile-bottom-nav-height: 4rem;
--main-margin-left-expanded: 18rem;
--main-margin-left-collapsed: 7rem;

View file

@ -67,7 +67,7 @@ export async function loginViaUI(
password: string,
options: { rememberMe?: boolean } = {},
): Promise<void> {
await page.goto('/login', { waitUntil: 'domcontentloaded' });
await page.goto(`${CONFIG.baseURL}/login`, { waitUntil: 'domcontentloaded' });
await page.waitForLoadState('networkidle').catch(() => {});
// Wait for the app to finish initializing (splash → login form)
await page.locator('main, [role="main"]').first().waitFor({
@ -141,10 +141,11 @@ export async function loginViaAPI(
): Promise<void> {
// Naviguer vers une page minimale pour initialiser le contexte navigateur (cookies, localStorage)
// about:blank ne permet pas localStorage, donc on utilise / avec un timeout court
await page.goto('/', { waitUntil: 'commit', timeout: CONFIG.timeouts.navigation });
const base = CONFIG.baseURL;
await page.goto(`${base}/`, { waitUntil: 'commit', timeout: CONFIG.timeouts.navigation });
// Appeler l'API login directement (bypass le rendu UI, juste un POST HTTP)
const response = await page.request.post('/api/v1/auth/login', {
const response = await page.request.post(`${base}/api/v1/auth/login`, {
data: { email, password, remember_me: false },
});
@ -168,7 +169,7 @@ export async function loginViaAPI(
}, token);
// Naviguer vers le dashboard — la SPA détecte isAuthenticated et affiche le layout authentifié
await page.goto('/dashboard', { waitUntil: 'domcontentloaded', timeout: 30_000 });
await page.goto(`${CONFIG.baseURL}/dashboard`, { waitUntil: 'domcontentloaded', timeout: 30_000 });
await page.waitForLoadState('networkidle').catch(() => {});
// Wait for the app to finish auth initialization
await page.waitForTimeout(1_000);
@ -186,7 +187,8 @@ export async function loginViaAPI(
* On attend donc qu'un élément `main` ou `[role="main"]` apparaisse.
*/
export async function navigateTo(page: Page, path: string): Promise<void> {
await page.goto(path, { waitUntil: 'domcontentloaded', timeout: 30_000 });
const url = path.startsWith('http') ? path : `${CONFIG.baseURL}${path}`;
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
await page.waitForLoadState('networkidle').catch(() => {});
// Wait for the app to finish initializing (loading splash → actual page)
await page.locator('main, [role="main"]').first().waitFor({