import { expect, test } from '@playwright/test' import { login, mockLearnerApi, overflowOffenders } from './mobile-fixtures' // Every learner surface on a phone viewport: nothing sticks out sideways and every page can be // left again. The measured truth in #14 was that the layouts already fit; this locks that in. test('every page fits the phone width and can be left again', async ({ page }) => { await mockLearnerApi(page) await login(page) const surfaces: { name: string; open: () => Promise; back: () => Promise }[] = [ { name: '书库', open: async () => { await expect(page.getByRole('heading', { name: '我的书库' })).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, { name: '导入', open: async () => { await page.getByRole('button', { name: '导入内容' }).click(); await expect(page.getByRole('heading', { name: '导入英文内容' })).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, { name: '书籍', open: async () => { await page.getByRole('link', { name: 'Fictional mobile book' }).click(); await expect(page.locator('.chapter-list')).toBeVisible() }, back: async () => { await page.getByRole('link', { name: '我的书库' }).first().click() }, }, { name: '阅读', open: async () => { await page.getByRole('link', { name: 'Fictional mobile book' }).click() await page.locator('.chapter-list a.chapter-name').first().click() await expect(page.locator('.reader-text')).toBeVisible() }, back: async () => { await page.locator('.breadcrumb').getByRole('link', { name: '我的书库' }).click() }, }, { name: '查词面板', open: async () => { await page.getByRole('link', { name: 'Fictional mobile book' }).click() await page.locator('.chapter-list a.chapter-name').first().click() await expect(page.locator('.reader-text')).toBeVisible() await page.locator('.reader-word').first().click() await expect(page.locator('.lookup-panel')).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, { name: '生词本', open: async () => { await page.locator('.site-header nav').getByRole('link', { name: '生词本' }).click(); await expect(page.getByRole('heading', { name: '生词本' })).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, { name: '复习', open: async () => { await page.locator('.site-header nav').getByRole('link', { name: '到期复习' }).click(); await expect(page.getByTestId('review-card')).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, { name: '进度', open: async () => { await page.locator('.site-header nav').getByRole('link', { name: '进度' }).click(); await expect(page.getByRole('heading', { name: '我的进度' })).toBeVisible() }, back: async () => { await page.locator('.site-header nav').getByRole('link', { name: '我的书库' }).click() }, }, ] for (const surface of surfaces) { await surface.open() expect(await overflowOffenders(page), `${surface.name} must not overflow sideways`).toEqual([]) const widths = await page.evaluate(() => ({ scroll: document.documentElement.scrollWidth, inner: window.innerWidth })) expect(widths.scroll, `${surface.name} must not scroll sideways`).toBeLessThanOrEqual(widths.inner) await page.screenshot({ path: `../.local/evidence/issue14-mobile-${surface.name}.png`, fullPage: true }) await surface.back() await expect(page.getByRole('heading', { name: '我的书库' })).toBeVisible() } }) test('the display control is reachable on a phone', async ({ page }) => { await mockLearnerApi(page) await login(page) const trigger = page.getByTestId('display-trigger') await expect(trigger).toBeVisible() const box = (await trigger.boundingBox())! // A finger needs a target of at least 38 pixels; the control is in the header on every page. expect(box.height).toBeGreaterThanOrEqual(36) await trigger.tap() await expect(page.getByRole('menu').getByText('主题')).toBeVisible() await page.getByRole('menu').getByText('深色', { exact: true }).tap() await expect(page.locator('html')).toHaveAttribute('data-theme', 'dark') await page.screenshot({ path: '../.local/evidence/issue14-mobile-dark.png' }) })