import { test, expect } from '@playwright/test'; import { loginViaAPI, CONFIG, navigateTo, playFirstTrack } from './helpers'; /** * WORKFLOWS COMPLETS & EMPTY STATES * * Imported from `@playwright/test` rather than `@chromatic-com/ * playwright` because the latter installs an automatic post-test * `takeSnapshot` that races the in-flight /login navigation at the * end of the logout step, producing "Execution context was destroyed" * on every run. The test asserts behavior, not visuals — chromatic * snapshots add no value here. Visual tests live in dedicated * spec files that use the chromatic wrapper deliberately. */ test.describe('WORKFLOW — Parcours listener complet @critical @workflow', () => { test('Login → Discover → Play → Like → Playlist → Search → Follow → Logout', async ({ page }) => { test.setTimeout(120_000); // 1. Login await loginViaAPI(page, CONFIG.users.listener.email, CONFIG.users.listener.password); // Verify login succeeded expect(page.url()).not.toContain('/login'); // 2. Discover await navigateTo(page, '/discover'); const discoverContent = page.locator('text=/discover|découvrir|genre/i').first(); const hasDiscover = await discoverContent.isVisible({ timeout: 10_000 }).catch(() => false); if (!hasDiscover) { // Page loaded but may not have the expected text — check it didn't crash const body = await page.textContent('body') || ''; expect(body).not.toMatch(/500|Internal Server Error/); expect(body.length).toBeGreaterThan(50); } // 3. Play a track await playFirstTrack(page); await page.waitForTimeout(2000); // 4. Like (if heart button visible) const likeBtn = page.locator('button[aria-label*="Like"]').first() .or(page.locator('button').filter({ has: page.locator('[class*="Heart"]') }).first()); if (await likeBtn.isVisible({ timeout: 3000 }).catch(() => false)) { await likeBtn.click(); await page.waitForTimeout(500); } // 5. Navigate to playlists await navigateTo(page, '/playlists'); await page.waitForTimeout(1000); // 6. Search await navigateTo(page, '/search'); const searchInput = page.locator('[role="search"] input').first() .or(page.locator('input[type="search"]').first()); if (await searchInput.isVisible({ timeout: 5000 }).catch(() => false)) { await searchInput.fill('test'); await page.waitForTimeout(1000); } // 7. Navigate to social/follow await navigateTo(page, '/social'); await page.waitForTimeout(1000); // 8. Logout const userMenu = page.getByTestId('user-menu').or(page.locator('[data-testid="user-menu"]')); if (await userMenu.isVisible({ timeout: 5000 }).catch(() => false)) { await userMenu.click(); await page.waitForTimeout(500); // Sign out button in header dropdown (plain