feat: add project-aware agent workspace
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { mockAgentApi } from "./support/mock-agent-api";
|
||||
|
||||
test.describe("外围工单测试", () => {
|
||||
test.describe("外围系统", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await mockAgentApi(page);
|
||||
await page.route("**/runtime-config.js", (route) =>
|
||||
@@ -96,8 +96,8 @@ test.describe("外围工单测试", () => {
|
||||
});
|
||||
});
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围工单测试" });
|
||||
await page.getByRole("button", { name: "外围系统", exact: true }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await expect(panel).toBeVisible();
|
||||
await expect(panel.getByText("工单接口测试", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("历史监测回放", { exact: true })).toHaveCount(0);
|
||||
@@ -137,11 +137,11 @@ test.describe("外围工单测试", () => {
|
||||
if (request.url().includes("/api/sample/v1")) peripheralRequests.push(request.url());
|
||||
});
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
await expect(page.getByRole("complementary", { name: "外围工单测试" })).toBeVisible();
|
||||
await page.getByRole("button", { name: "外围系统", exact: true }).click();
|
||||
await expect(page.getByRole("complementary", { name: "外围系统" })).toBeVisible();
|
||||
await expect(
|
||||
page
|
||||
.getByRole("complementary", { name: "外围工单测试" })
|
||||
.getByRole("complementary", { name: "外围系统" })
|
||||
.getByText("仅用于验证外围工单接口与同步过程,不代表真实现场处置", { exact: true })
|
||||
.last()
|
||||
).toBeVisible();
|
||||
@@ -149,6 +149,129 @@ test.describe("外围工单测试", () => {
|
||||
expect(peripheralRequests).toEqual([]);
|
||||
});
|
||||
|
||||
test("SCADA 系统按当前项目读取最新记录并设定模拟异常", async ({ page }, testInfo) => {
|
||||
const latestRequests: string[] = [];
|
||||
const simulatedWrites: Array<Record<string, unknown>> = [];
|
||||
const projectId = "324ff7ee-c2d4-5184-a84b-48fb14a2933e";
|
||||
await page.route("**/runtime-config.js", (route) =>
|
||||
route.fulfill({
|
||||
contentType: "text/javascript",
|
||||
body: `globalThis.__TJWATER_CONFIG__ = ${JSON.stringify({
|
||||
TJWATER_AUTH_MODE: "disabled",
|
||||
TJWATER_SERVER_API_BASE_URL: "http://server.test",
|
||||
TJWATER_PERIPHERAL_SAMPLE_API_BASE_URL: "http://peripheral.test"
|
||||
})};`
|
||||
})
|
||||
);
|
||||
await page.route("http://peripheral.test/api/sample/v1/**", (route) => {
|
||||
const request = route.request();
|
||||
const path = new URL(request.url()).pathname;
|
||||
if (path.endsWith("/context")) return route.fulfill({ json: {
|
||||
protocol_version: "tjwater-peripheral-sample@1", origin: "synthetic", project_id: projectId,
|
||||
user_id: "50000000-0000-4000-8000-000000000001", can_write: true,
|
||||
scenarios: ["normal"], managed_resources: { work_orders: "available", test_data: "available" },
|
||||
state_transitions: { pending: [], processing: [], pending_review: [], completed: [] }
|
||||
} });
|
||||
if (path.endsWith("/test-data") && request.method() === "GET") {
|
||||
return route.fulfill({ json: { items: [], next_cursor: null } });
|
||||
}
|
||||
if (path.endsWith("/test-data") && request.method() === "POST") {
|
||||
const body = request.postDataJSON() as Record<string, unknown>;
|
||||
simulatedWrites.push(body);
|
||||
return route.fulfill({ status: 201, json: {
|
||||
...body,
|
||||
record_id: "50000000-0000-4000-8000-000000000017",
|
||||
project_id: projectId,
|
||||
revision: 1,
|
||||
origin: "synthetic",
|
||||
created_at: "2026-10-22T02:03:01Z",
|
||||
updated_at: "2026-10-22T02:03:01Z",
|
||||
created_by: "tester",
|
||||
updated_by: "tester"
|
||||
} });
|
||||
}
|
||||
if (path.endsWith("/work-orders")) {
|
||||
return route.fulfill({ json: { items: [], next_cursor: null } });
|
||||
}
|
||||
return route.fulfill({ status: 404, json: {} });
|
||||
});
|
||||
await page.route("http://server.test/api/v1/timeseries/scada-readings/latest?**", (route) => {
|
||||
latestRequests.push(route.request().headers()["x-project-id"] ?? "");
|
||||
return route.fulfill({
|
||||
json: {
|
||||
items: [
|
||||
{
|
||||
device_id: "PRESSURE-17",
|
||||
device_type: "pressure",
|
||||
measurement_unit: "MPa",
|
||||
transmission_mode: "realtime",
|
||||
transmission_frequency: "15min",
|
||||
observed_at: "2026-10-22T01:02:03Z",
|
||||
monitored_value: 0.3172,
|
||||
cleaned_value: 0.315
|
||||
},
|
||||
{
|
||||
device_id: "FLOW-09",
|
||||
device_type: "pipe_flow",
|
||||
measurement_unit: "m³/h",
|
||||
transmission_mode: "realtime",
|
||||
transmission_frequency: "15min",
|
||||
observed_at: null,
|
||||
monitored_value: null,
|
||||
cleaned_value: null
|
||||
}
|
||||
],
|
||||
total: 2,
|
||||
limit: 500,
|
||||
offset: 0,
|
||||
observed_count: 1,
|
||||
latest_observed_at: "2026-10-22T01:02:03Z"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围系统", exact: true }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await panel.getByRole("tab", { name: "SCADA 系统" }).click();
|
||||
|
||||
await expect(panel.getByRole("table", { name: "SCADA 最新数据表" })).toBeVisible();
|
||||
await expect(panel.getByText("PRESSURE-17", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("0.3172 MPa", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("0.315 MPa", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("FLOW-09", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("无记录", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByLabel("SCADA 最新数据概览")).toContainText(/1\s*\/\s*2 个设备/);
|
||||
expect(latestRequests).toEqual(["324ff7ee-c2d4-5184-a84b-48fb14a2933e"]);
|
||||
|
||||
await panel.getByRole("textbox", { name: "筛选 SCADA 设备" }).fill("pressure");
|
||||
await expect(panel.getByText("PRESSURE-17", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("FLOW-09", { exact: true })).toHaveCount(0);
|
||||
await panel.getByRole("textbox", { name: "筛选 SCADA 设备" }).fill("");
|
||||
|
||||
await panel.getByRole("button", { name: "设定读数" }).click();
|
||||
for (const width of [1280, 375, 320]) {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
await panel.getByPlaceholder("输入需要演练的异常值").scrollIntoViewIfNeeded();
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(width);
|
||||
await testInfo.attach(`scada-peripheral-anomaly-${width}`, {
|
||||
body: await page.screenshot(),
|
||||
contentType: "image/png"
|
||||
});
|
||||
}
|
||||
await panel.getByPlaceholder("输入需要演练的异常值").fill("0.08");
|
||||
await panel.getByPlaceholder("例如:压力突降,偏离近一小时稳定区间").fill("压力突降");
|
||||
await panel.getByRole("button", { name: "保存模拟读数", exact: true }).click();
|
||||
await expect(panel.getByLabel("SCADA 模拟异常列表")).toContainText("PRESSURE-17");
|
||||
await expect(panel.getByLabel("SCADA 模拟异常列表")).toContainText("0.08 MPa");
|
||||
expect(simulatedWrites[0]).toMatchObject({
|
||||
point_id: "PRESSURE-17",
|
||||
value: 0.08,
|
||||
quality: "valid",
|
||||
notes: "[SCADA_ANOMALY] 压力突降"
|
||||
});
|
||||
});
|
||||
|
||||
test("管理面板打开时阻止地图接收鼠标行为", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
|
||||
@@ -194,10 +317,10 @@ test.describe("外围工单测试", () => {
|
||||
.toEqual([]);
|
||||
};
|
||||
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
await expect(page.getByRole("complementary", { name: "外围工单测试" })).toBeVisible();
|
||||
await expectMapInteractionBlocked("外围工单测试");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
await page.getByRole("button", { name: "外围系统", exact: true }).click();
|
||||
await expect(page.getByRole("complementary", { name: "外围系统" })).toBeVisible();
|
||||
await expectMapInteractionBlocked("外围系统");
|
||||
await page.getByRole("button", { name: "外围系统", exact: true }).click();
|
||||
|
||||
await page.getByRole("button", { name: "项目分析成果" }).click();
|
||||
await expect(page.getByRole("complementary", { name: "项目分析成果" })).toBeVisible();
|
||||
@@ -241,8 +364,8 @@ test.describe("外围工单测试", () => {
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围工单测试" });
|
||||
await page.getByRole("button", { name: "外围系统" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await expect(panel.getByText("测试工单存储待供给", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByText("测试数据存储待供给", { exact: true })).toHaveCount(0);
|
||||
await expect(panel.getByText("历史监测回放", { exact: true })).toHaveCount(0);
|
||||
@@ -294,8 +417,8 @@ test.describe("外围工单测试", () => {
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围工单测试" });
|
||||
await page.getByRole("button", { name: "外围系统" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await expect(panel.getByText("工单接口测试", { exact: true })).toBeVisible();
|
||||
await expect(panel.getByLabel("预约工单列表")).toContainText("暂无预约工单");
|
||||
await expect(panel.getByLabel("投诉工单列表")).toContainText("暂无投诉工单");
|
||||
@@ -567,8 +690,8 @@ test.describe("外围工单测试", () => {
|
||||
});
|
||||
|
||||
await page.goto("/");
|
||||
await page.getByRole("button", { name: "外围样板管理" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围工单测试" });
|
||||
await page.getByRole("button", { name: "外围系统" }).click();
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await panel.getByRole("button", { name: "投诉与爆管上报" }).click();
|
||||
await panel.getByRole("textbox", { name: "事件位置" }).fill("演示小区");
|
||||
await panel.getByRole("textbox", { name: "现场描述" }).fill("多户居民反映晨间用水有异味");
|
||||
@@ -681,10 +804,10 @@ test.describe("外围工单测试", () => {
|
||||
test("在 375px 视口内完整呈现面板", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 720 });
|
||||
await page.goto("/");
|
||||
const launcher = page.getByRole("button", { name: "外围样板管理" });
|
||||
const launcher = page.getByRole("button", { name: "外围系统" });
|
||||
await launcher.focus();
|
||||
await page.keyboard.press("Enter");
|
||||
const panel = page.getByRole("complementary", { name: "外围工单测试" });
|
||||
const panel = page.getByRole("complementary", { name: "外围系统" });
|
||||
await expect(panel).toBeVisible();
|
||||
const box = await panel.boundingBox();
|
||||
expect(box).not.toBeNull();
|
||||
|
||||
Reference in New Issue
Block a user