/** * RW-series: Desktop reading-width cap (Fase 9.2). * * RW-01 detail routes (/lists/[id], /tasks/[id], /notes/[id]) cap the * content column at max-w-2xl on >=md viewports — measured by the * main element's bounding box being narrower than a 1280px viewport. * RW-02 mobile viewports ( { await page.goto('/lists'); // Click any list card to get into a detail route. const card = page.getByRole('heading', { level: 3 }).or(page.getByRole('heading', { level: 2 })).first(); await expect(card).toBeVisible({ timeout: 10_000 }); await card.click(); await page.waitForURL(/\/lists\/[0-9a-f-]+\/?$/, { timeout: 10_000 }); const url = new URL(page.url()); const segments = url.pathname.split('/'); return segments[segments.indexOf('lists') + 1]; } test.describe('Reading width — desktop max-w-2xl cap', () => { test('RW-01: list detail page caps content at max-w-2xl on desktop', async ({ browser }) => { const ctx = await browser.newContext({ viewport: DESKTOP }); const page = await ctx.newPage(); await loginAs(page, USERS.ana); await firstListId(page); // The detail content should live inside an element whose width is // capped at max-w-2xl (672px). We assert the inner scroll container // reports a width <= 672 + slack for padding. const wrapper = page.locator('[data-testid="reading-column"]').first(); await expect(wrapper).toBeVisible({ timeout: 10_000 }); const box = await wrapper.boundingBox(); expect(box).not.toBeNull(); expect(box!.width).toBeLessThanOrEqual(READING_WIDTH + 4); await ctx.close(); }); test('RW-02: list detail page is full-width on mobile ( { const ctx = await browser.newContext({ viewport: MOBILE }); const page = await ctx.newPage(); await loginAs(page, USERS.ana); await firstListId(page); const wrapper = page.locator('[data-testid="reading-column"]').first(); await expect(wrapper).toBeVisible({ timeout: 10_000 }); const box = await wrapper.boundingBox(); expect(box).not.toBeNull(); // Mobile viewport is 390 — wrapper should fill it (allow some padding). expect(box!.width).toBeGreaterThan(380); await ctx.close(); }); test('RW-03: shopping session stays full-width on desktop (immersive)', async ({ browser }) => { const ctx = await browser.newContext({ viewport: DESKTOP }); const page = await ctx.newPage(); await loginAs(page, USERS.ana); const id = await firstListId(page); await page.goto(`/lists/${id}/session`); // The session view is allowed to occupy the full viewport. The // reading-column wrapper must NOT be present in this route. await expect(page.locator('[data-testid="reading-column"]')).toHaveCount(0); await ctx.close(); }); });