import { expect, test } from "@playwright/test"; import { mockWorkbenchContext } from "./support/mock-workbench-context"; test("combined compass switches 2D and 3D with north reset first", async ({ page }) => { await mockWorkbenchContext(page); await page.route("**/city-model/manifest.json", (route) => route.fulfill({ status: 404 })); for (const viewport of [ { width: 1280, height: 800 }, { width: 375, height: 812 } ]) { await page.setViewportSize(viewport); await page.goto("/", { waitUntil: "domcontentloaded" }); const zoomControls = page.getByRole("group", { name: "地图缩放", exact: true }); const modeButton = zoomControls.locator("button[aria-pressed]"); const compass = modeButton.locator("[data-map-compass]"); await expect(zoomControls).toBeVisible(); await expect(zoomControls.getByRole("button", { name: "放大", exact: true })).toBeVisible(); await expect(zoomControls.getByRole("button", { name: "缩小", exact: true })).toBeVisible(); await expect( zoomControls.getByRole("button", { name: "切换到三维", exact: true }) ).toBeVisible(); await expect(modeButton).toHaveAttribute("aria-pressed", "false"); await expect(compass).toHaveAttribute("data-map-mode", "2d"); await expect .poll(() => page.evaluate(() => ({ dragRotate: window.__waterNetworkMap!.dragRotate.isEnabled(), touchPitch: window.__waterNetworkMap!.touchPitch.isEnabled() })) ) .toEqual({ dragRotate: false, touchPitch: false }); await modeButton.click(); await expect .poll(() => page.evaluate(() => window.__waterNetworkMap!.getPitch())) .toBe(viewport.width < 640 ? 45 : 50); await expect(modeButton).toHaveAttribute("aria-pressed", "true"); await expect(modeButton).toHaveAttribute("aria-label", "切换到二维"); await expect(compass).toHaveAttribute("data-map-mode", "3d"); await expect .poll(() => page.evaluate(() => ({ dragRotate: window.__waterNetworkMap!.dragRotate.isEnabled(), touchPitch: window.__waterNetworkMap!.touchPitch.isEnabled() })) ) .toEqual({ dragRotate: true, touchPitch: true }); await page.evaluate(() => window.__waterNetworkMap!.jumpTo({ bearing: 60 })); await expect(modeButton).toHaveAttribute("aria-label", "恢复北向"); await expect(compass).toHaveAttribute("data-bearing", "60.0"); await expect(compass.locator("svg")).toHaveAttribute( "style", /rotateX\([^)]*\) rotateZ\(-60deg\)/ ); await modeButton.click(); await expect.poll(() => page.evaluate(() => window.__waterNetworkMap!.getBearing())).toBe(0); await expect(modeButton).toHaveAttribute("aria-label", "切换到二维"); expect(await page.evaluate(() => window.__waterNetworkMap!.getPitch())).toBeGreaterThan(0); await modeButton.click(); await expect.poll(() => page.evaluate(() => window.__waterNetworkMap!.getPitch())).toBe(0); await expect(modeButton).toHaveAttribute("aria-pressed", "false"); await expect(modeButton).toHaveAttribute("aria-label", "切换到三维"); await expect(compass).toHaveAttribute("data-map-mode", "2d"); await expect( zoomControls.getByRole("button", { name: "缩放到全局", exact: true }) ).toBeVisible(); await expect(page.getByRole("button", { name: "调整视角", exact: true })).toHaveCount(0); await expect(page.getByRole("region", { name: "地图视角" })).toHaveCount(0); } }); test("3D navigation overrides the browser context menu for right-drag rotation", async ({ page }) => { await mockWorkbenchContext(page); await page.route("**/city-model/manifest.json", (route) => route.fulfill({ status: 404 })); await page.setViewportSize({ width: 1280, height: 800 }); await page.goto("/", { waitUntil: "domcontentloaded" }); const modeButton = page .getByRole("group", { name: "地图缩放", exact: true }) .locator("button[aria-pressed]"); await modeButton.click(); await expect.poll(() => page.evaluate(() => window.__waterNetworkMap!.getPitch())).toBe(50); const canvas = page.locator(".maplibregl-canvas"); const bounds = await canvas.boundingBox(); expect(bounds).not.toBeNull(); const startX = bounds!.x + bounds!.width / 2; const startY = bounds!.y + bounds!.height / 2; await page.mouse.move(startX, startY); await page.mouse.down({ button: "right" }); await page.mouse.move(startX + 80, startY, { steps: 4 }); await page.mouse.up({ button: "right" }); await expect .poll(() => page.evaluate(() => Math.abs(window.__waterNetworkMap!.getBearing()))) .toBeGreaterThan(10); expect( await canvas.evaluate((element) => element.dispatchEvent( new MouseEvent("contextmenu", { bubbles: true, cancelable: true, button: 2 }) ) ) ).toBe(false); });