import { expect, test } from "@playwright/test"; import { mockAgentApi } from "./support/mock-agent-api"; import { mockWorkbenchContext } from "./support/mock-workbench-context"; for (const width of [1280, 375, 320]) { test(`map control hover borders have symmetric spacing at ${width}px`, async ({ page }, testInfo) => { await mockWorkbenchContext(page); await mockAgentApi(page); await page.route("**/city-model/manifest.json", (route) => route.fulfill({ status: 404 })); await page.setViewportSize({ width, height: 900 }); await page.goto("/", { waitUntil: "domcontentloaded" }); const zoomControls = page.getByRole("group", { name: "地图缩放", exact: true }); const toolbar = page.getByRole("navigation", { name: "地图工具", exact: true }); await expect(zoomControls).toBeVisible(); await expect(toolbar).toBeVisible(); await expect(zoomControls.getByRole("button").first()).toBeEnabled(); const surfaces = zoomControls.locator(".acrylic-control").or(toolbar); await expect(surfaces).toHaveCount(3); for (const surface of await surfaces.all()) { const buttons = surface.getByRole("button"); for (const button of await buttons.all()) { await button.hover(); const size = await button.boundingBox(); expect(size!.height).toBe(40); if (width >= 1024 || (await zoomControls.getByRole("button").and(button).count()) > 0) { expect(size!.width).toBe(40); } } // Check all four outer edges, including the final row's bottom spacing. const insets = await surface.evaluate((element) => { const bounds = element.getBoundingClientRect(); const buttons = [...element.querySelectorAll("button")].map((button) => button.getBoundingClientRect()); return { top: Math.min(...buttons.map((button) => button.top)) - bounds.top, bottom: bounds.bottom - Math.max(...buttons.map((button) => button.bottom)), left: Math.min(...buttons.map((button) => button.left)) - bounds.left, right: bounds.right - Math.max(...buttons.map((button) => button.right)) }; }); expect.soft(insets).toEqual({ top: 5, bottom: 5, left: 5, right: 5 }); } if (width < 1024) { const zoomBounds = await zoomControls.boundingBox(); const toolbarBounds = await toolbar.boundingBox(); expect(toolbarBounds!.height).toBe(50); expect(toolbarBounds!.y - (zoomBounds!.y + zoomBounds!.height)).toBe(8); } await zoomControls.getByRole("button", { name: "放大", exact: true }).hover(); await page.screenshot({ path: testInfo.outputPath("map-control-hover.png") }); }); }