// @ts-check // Tests: MUX1–MUX5 — Map UX features: panel toggles, sort toggle, fullscreen button // Requires demo data: `make demo-load` before running. const { test, expect } = require('@playwright/test'); // ── MUX1: Trip stats panel toggles open and closed ────────────────────────── test('MUX1: trip stats panel opens and closes on button click', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); const statsBtn = page.locator('#trip-stats-toggle'); const statsBlock = page.locator('#trip-stats-block'); await expect(statsBtn).toBeVisible(); await expect(statsBlock).not.toHaveClass(/is-open/); await statsBtn.click(); await expect(statsBlock).toHaveClass(/is-open/); await expect(page.locator('.trip-stats-grid')).toBeVisible(); await statsBtn.click(); await expect(statsBlock).not.toHaveClass(/is-open/); }); // ── MUX2: Trip cycling panel toggles open and closed ──────────────────────── test('MUX2: trip cycling panel opens and closes on button click', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); const cyclingBtn = page.locator('#trip-cycling-toggle'); const cyclingBlock = page.locator('#trip-cycling-block'); await expect(cyclingBtn).toBeVisible(); await expect(cyclingBlock).not.toHaveClass(/is-open/); await cyclingBtn.click(); await expect(cyclingBlock).toHaveClass(/is-open/); await cyclingBtn.click(); await expect(cyclingBlock).not.toHaveClass(/is-open/); }); // ── MUX3: Trip page map has a fullscreen button in the DOM ──────────────────── test('MUX3: trip page map has a fullscreen toggle button', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); await expect(page.locator('#trip-map canvas.maplibregl-canvas')).toBeVisible({ timeout: 10000 }); const fsBtn = page.locator('#trip-map-fullscreen'); await expect(fsBtn).toBeAttached(); await expect(fsBtn).toHaveAttribute('aria-label', 'Expand map'); }); // ── MUX4: Trip feed sort toggle reverses entry order ───────────────────────── // The sort toggle moved onto the trip page (#trip-sort-toggle) when the standalone // /dailies feed view was retired. test('MUX4: trip feed sort toggle reverses the feed entry order', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); const sortBtn = page.locator('#trip-sort-toggle'); await expect(sortBtn).toBeVisible(); const firstBefore = await page.locator('[data-type]').first().getAttribute('id'); await sortBtn.click(); const firstAfter = await page.locator('[data-type]').first().getAttribute('id'); expect(firstAfter, 'Entry order reversed after sort').not.toBe(firstBefore); await sortBtn.click(); const firstRestored = await page.locator('[data-type]').first().getAttribute('id'); expect(firstRestored, 'Entry order restored after second toggle').toBe(firstBefore); }); // ── MUX5: Trip feed sort toggle reverses story card order ──────────────────── // Story cards live in the trip feed as [data-type="story"] (the /stories grid was retired). test('MUX5: trip feed sort toggle reverses the story card order', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); const sortBtn = page.locator('#trip-sort-toggle'); await expect(sortBtn).toBeVisible(); const firstBefore = await page.locator('[data-type="story"]').first().getAttribute('id'); await sortBtn.click(); const firstAfter = await page.locator('[data-type="story"]').first().getAttribute('id'); expect(firstAfter, 'Story order reversed after sort').not.toBe(firstBefore); await sortBtn.click(); const firstRestored = await page.locator('[data-type="story"]').first().getAttribute('id'); expect(firstRestored, 'Story order restored after second toggle').toBe(firstBefore); });