feat: add project-aware agent workspace
This commit is contained in:
@@ -10,7 +10,15 @@ const headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Head
|
||||
|
||||
async function setup(page: Page) {
|
||||
await page.emulateMedia({ reducedMotion: "reduce" });
|
||||
await mockWorkbenchContext(page);
|
||||
await mockWorkbenchContext(page, undefined, {
|
||||
metadata: {
|
||||
project_id: TEST_PROJECT_ID, name: "奉贤演示项目", code: "tjwater_v2",
|
||||
gs_workspace: "tjwater_next", status: "active", project_role: "member",
|
||||
map_config: { place_search: { enabled: true, provider: "tianditu", admin_code: "310120", region: "奉贤区" } }
|
||||
},
|
||||
accessContext: { user_id: "operator", username: "operator", system_role: "user", is_system_admin: false,
|
||||
project_id: TEST_PROJECT_ID, project_role: "member", permissions: ["webgis.view"] }
|
||||
});
|
||||
await mockAgentApi(page);
|
||||
}
|
||||
|
||||
@@ -229,3 +237,91 @@ test("place search reports errors and distinguishes an empty Fengxian search", a
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBe(320);
|
||||
await page.screenshot({ path: test.info().outputPath("place-empty-320.png") });
|
||||
});
|
||||
|
||||
async function exposedMapPoint(page: Page) {
|
||||
return page.locator(".maplibregl-canvas").evaluate((canvas) => {
|
||||
const bounds = canvas.getBoundingClientRect();
|
||||
for (const yFraction of [0.3, 0.35, 0.25, 0.45, 0.65]) {
|
||||
for (const xFraction of [0.5, 0.3, 0.65, 0.15]) {
|
||||
const x = bounds.left + bounds.width * xFraction;
|
||||
const y = bounds.top + bounds.height * yFraction;
|
||||
if (document.elementFromPoint(x, y) === canvas) return { x: bounds.width * xFraction, y: bounds.height * yFraction };
|
||||
}
|
||||
}
|
||||
throw new Error("No exposed map point available");
|
||||
});
|
||||
}
|
||||
|
||||
for (const width of [1280, 320]) {
|
||||
test(`map point lookup shows address without moving the camera at ${width}px`, async ({ page }, testInfo) => {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
await setup(page);
|
||||
let lastPoint: { longitude: number; latitude: number } | null = null;
|
||||
let pointLookups = 0;
|
||||
await page.route("**/api/v1/reverse-geocoding-requests", async (route) => {
|
||||
if (route.request().method() === "OPTIONS") { await route.fulfill({ status: 204, headers }); return; }
|
||||
expect(route.request().headers()["x-project-id"]).toBe(TEST_PROJECT_ID);
|
||||
pointLookups += 1;
|
||||
lastPoint = route.request().postDataJSON();
|
||||
await route.fulfill({ headers, json: {
|
||||
...first, id: "map-point", name: "南桥镇", address: "上海市奉贤区南桥镇南桥路", ...lastPoint,
|
||||
category: "附近地名"
|
||||
} });
|
||||
});
|
||||
const panel = await openSearch(page);
|
||||
const picker = panel.getByRole("button", { name: "从地图取点查找地名" });
|
||||
await picker.click();
|
||||
await expect(picker).toHaveAttribute("aria-pressed", "true");
|
||||
await expect(panel.getByRole("status")).toContainText("点击地图查询地名");
|
||||
const canvas = page.locator(".maplibregl-canvas");
|
||||
await expect(canvas).toHaveCSS("cursor", "crosshair");
|
||||
const before = await page.evaluate(() => ({ center: window.__waterNetworkMap!.getCenter().toArray(), zoom: window.__waterNetworkMap!.getZoom() }));
|
||||
await canvas.click({ position: await exposedMapPoint(page) });
|
||||
const selected = panel.getByRole("region", { name: "定位结果" });
|
||||
await expect(selected).toContainText("上海市奉贤区南桥镇南桥路");
|
||||
expect(lastPoint).not.toBeNull();
|
||||
const visibleCoordinates = await selected.getByLabel("经纬度坐标").locator("dd").evaluate((element) => {
|
||||
const scrollArea = element.closest(".overflow-y-auto")!;
|
||||
return element.getBoundingClientRect().bottom <= scrollArea.getBoundingClientRect().bottom;
|
||||
});
|
||||
expect(visibleCoordinates).toBe(true);
|
||||
await expect(page.locator('[data-geocoding-marker="true"]')).toHaveCount(1);
|
||||
const after = await page.evaluate(() => ({ center: window.__waterNetworkMap!.getCenter().toArray(), zoom: window.__waterNetworkMap!.getZoom() }));
|
||||
expect(after).toEqual(before);
|
||||
await expect(panel.getByRole("button", { name: "更换位置" })).toHaveCount(0);
|
||||
await panel.screenshot({ path: testInfo.outputPath(`map-point-${width}.png`), animations: "disabled" });
|
||||
await expect(picker).toHaveAttribute("aria-pressed", "false");
|
||||
await expect(canvas).not.toHaveCSS("cursor", "crosshair");
|
||||
await expect(selected).toBeVisible();
|
||||
await canvas.click({ position: await exposedMapPoint(page) });
|
||||
expect(pointLookups).toBe(1);
|
||||
await selected.getByRole("button", { name: "清除结果" }).click();
|
||||
await expect(page.locator('[data-geocoding-marker="true"]')).toHaveCount(0);
|
||||
});
|
||||
}
|
||||
|
||||
test("map point lookup recovers from an out of scope point and stops when closing", async ({ page }) => {
|
||||
await setup(page);
|
||||
let calls = 0;
|
||||
await page.route("**/api/v1/reverse-geocoding-requests", async (route) => {
|
||||
if (route.request().method() === "OPTIONS") { await route.fulfill({ status: 204, headers }); return; }
|
||||
calls += 1;
|
||||
await route.fulfill({ headers, status: calls === 1 ? 422 : 200, json: calls === 1
|
||||
? { detail: "取点位置不在当前项目的地名搜索范围内(奉贤区)" }
|
||||
: { ...first, ...route.request().postDataJSON(), id: "map-retry" } });
|
||||
});
|
||||
const panel = await openSearch(page);
|
||||
await panel.getByRole("button", { name: "从地图取点查找地名" }).click();
|
||||
const canvas = page.locator(".maplibregl-canvas");
|
||||
await canvas.click({ position: { x: 450, y: 170 } });
|
||||
await expect(panel.getByRole("alert")).toContainText("不在当前项目");
|
||||
await expect(panel.getByRole("button", { name: "从地图取点查找地名" })).toHaveAttribute("aria-pressed", "true");
|
||||
await canvas.click({ position: { x: 440, y: 180 } });
|
||||
await expect(panel.getByRole("region", { name: "定位结果" })).toContainText("上海市奉贤区南桥路1号");
|
||||
await expect(panel.getByRole("button", { name: "从地图取点查找地名" })).toHaveAttribute("aria-pressed", "false");
|
||||
await page.getByRole("button", { name: "地址定位:查询地址并定位到地图" }).click();
|
||||
await expect(panel).toBeHidden();
|
||||
await expect(canvas).not.toHaveCSS("cursor", "crosshair");
|
||||
await canvas.click({ position: { x: 430, y: 190 } });
|
||||
expect(calls).toBe(2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user