import { expect, test } from "@playwright/test"; test("top bar uses compact controls on narrow mobile viewports", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/", { waitUntil: "domcontentloaded" }); await expect(page.locator('meta[name="viewport"]')).toHaveAttribute( "content", /width=device-width/ ); await expect(page.getByRole("button", { name: "切换模拟方案" })).toBeHidden(); await expect(page.getByRole("button", { name: "切换地图 Dev Panel" })).toBeHidden(); const alertButton = page.getByRole("button", { name: /查看异常处置面板/ }); const userButton = page.getByRole("button", { name: "打开用户菜单" }); await expect(alertButton).toBeVisible(); await expect(userButton).toBeVisible(); const [alertBox, userBox] = await Promise.all([ alertButton.boundingBox(), userButton.boundingBox() ]); expect(alertBox).not.toBeNull(); expect(userBox).not.toBeNull(); expect(alertBox?.width).toBe(40); expect(alertBox?.height).toBe(40); expect(userBox?.width).toBe(alertBox?.width); expect(userBox?.height).toBe(alertBox?.height); const [alertStyles, userStyles] = await Promise.all([ alertButton.evaluate((element) => { const styles = getComputedStyle(element); return { backgroundColor: styles.backgroundColor, borderRadius: styles.borderRadius }; }), userButton.evaluate((element) => { const styles = getComputedStyle(element); return { backgroundColor: styles.backgroundColor, borderRadius: styles.borderRadius }; }) ]); expect(alertStyles).toEqual(userStyles); }); test("top bar keeps text horizontal at the desktop breakpoint", async ({ page }) => { await page.setViewportSize({ width: 1024, height: 844 }); await page.goto("/", { waitUntil: "domcontentloaded" }); const header = page.locator("header").first(); await expect(header).toBeVisible(); await expect.poll(async () => Math.round((await header.boundingBox())?.height ?? 0)).toBe(56); await expect.poll(async () => header.evaluate((element) => { return Array.from(element.querySelectorAll("span")) .filter((span) => { const style = getComputedStyle(span); const rect = span.getBoundingClientRect(); return style.display !== "none" && style.visibility !== "hidden" && rect.width > 0 && rect.height > 0; }) .map((span) => span.textContent?.trim()) .filter((text) => text === "任务浮条" || text === "工况任务" || text === "异常处置").length; })).toBe(0); });