feat: extend supply workbench demo and map navigation

This commit is contained in:
2026-09-23 13:19:30 +08:00
parent bebcf2a06c
commit 1752b9ef84
45 changed files with 2137 additions and 449 deletions
+111
View File
@@ -0,0 +1,111 @@
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);
});