import { expect, test } from "@playwright/test"; import { mockInvestigationPresentation } from "./support/mock-investigation-presentation"; test.beforeEach(async ({ page }) => { await mockInvestigationPresentation(page, []); await page.emulateMedia({ reducedMotion: "reduce" }); }); test("collapsed tasks leave the map below the visible panel interactive", async ({ page }, testInfo) => { await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "工况任务", exact: true }).click(); const panel = page.getByRole("region", { name: "工况任务", exact: true }); await expect(panel).toBeVisible(); const box = (await panel.boundingBox())!; const point = { x: box.x + box.width / 2, y: box.y + box.height + 24 }; expect(point.y).toBeLessThan(page.viewportSize()!.height - 20); await expect.poll(() => page.evaluate(({ x, y }) => document.elementFromPoint(x, y)?.classList.contains("maplibregl-canvas") ?? false, point)).toBe(true); await page.locator(".maplibregl-canvas").evaluate((canvas) => { canvas.addEventListener("pointerdown", () => canvas.setAttribute("data-map-clicked", "true"), { once: true }); }); await page.mouse.click(point.x, point.y); await expect(page.locator(".maplibregl-canvas")).toHaveAttribute("data-map-clicked", "true"); await testInfo.attach("collapsed-task-map-boundary", { body: await page.screenshot({ path: testInfo.outputPath("collapsed.png") }), contentType: "image/png" }); }); for (const viewport of [{ width: 1440, height: 900 }, { width: 1024, height: 640 }]) { test(`expanded tasks stay inside their map boundary at ${viewport.width}x${viewport.height}`, async ({ page }, testInfo) => { await page.setViewportSize(viewport); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "工况任务", exact: true }).click(); const panel = page.getByRole("region", { name: "工况任务", exact: true }); await panel.getByRole("button", { name: "展开工况任务" }).click(); const box = (await panel.boundingBox())!; const boundary = (await panel.locator("..").boundingBox())!; expect(box.y + box.height).toBeLessThanOrEqual(boundary.y + boundary.height + 1); const timeline = panel.getByTestId("scheduled-condition-timeline"); const scroll = timeline.locator(".scheduled-feed-scroll.flex-1"); const scrollBox = (await scroll.boundingBox())!; expect(scrollBox.height).toBeGreaterThan(80); expect(scrollBox.y + scrollBox.height).toBeLessThanOrEqual(box.y + box.height - 12); await scroll.evaluate((element) => { element.scrollTop = element.scrollHeight; }); await expect(scroll.locator("button[aria-pressed]").last()).toBeInViewport(); await testInfo.attach("expanded-task-map-boundary", { body: await page.screenshot({ path: testInfo.outputPath("expanded.png") }), contentType: "image/png" }); }); } test("Dev stays above overlapping business panels and its menus stay usable", async ({ page }, testInfo) => { await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: "切换地图 Dev Panel" }).click(); const dev = page.getByTestId("map-dev-panel"); await expect(dev).toBeVisible(); await page.getByRole("button", { name: "外围系统", exact: true }).click(); await expect(page.getByRole("complementary", { name: "外围系统", exact: true })).toBeVisible(); const heading = dev.getByRole("heading", { level: 2 }); const box = (await heading.boundingBox())!; await expect.poll(() => page.evaluate(({ x, y }) => Boolean(document.elementFromPoint(x, y)?.closest('[data-testid="map-dev-panel"]')), { x: box.x + box.width / 2, y: box.y + box.height / 2 })).toBe(true); await dev.getByRole("tab", { name: "地图调试", exact: true }).click(); await dev.getByRole("combobox", { name: "业务源", exact: true }).click(); await page.getByRole("option", { name: "管线", exact: true }).click(); await expect(dev.getByRole("combobox", { name: "业务源", exact: true })).toContainText("管线"); await testInfo.attach("dev-above-business-panels", { body: await page.screenshot({ path: testInfo.outputPath("dev.png") }), contentType: "image/png" }); }); for (const mobile of [false, true]) { test(`opening peripheral systems suspends and restores ${mobile ? "mobile" : "desktop"} tasks`, async ({ page }) => { if (mobile) await page.setViewportSize({ width: 375, height: 812 }); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.getByRole("button", { name: mobile ? "打开工况任务" : "工况任务", exact: true }).click(); const panel = page.getByRole("region", { name: "工况任务", exact: true }); await panel.getByRole("button", { name: "展开工况任务" }).click(); await expect(panel).toBeVisible(); await page.getByRole("button", { name: "外围系统", exact: true }).click(); const peripheral = page.getByRole("complementary", { name: "外围系统", exact: true }); await expect(peripheral).toBeVisible(); await expect(panel).toBeHidden(); if (!mobile) { await expect(page.getByRole("button", { name: "工况任务", exact: true })).toHaveAttribute("aria-pressed", "false"); } await peripheral.getByRole("button", { name: "关闭外围系统", exact: true }).click(); await expect(panel).toBeVisible(); await expect(panel.getByRole("button", { name: "收起工况任务" })).toHaveAttribute("aria-expanded", "true"); }); }