Files
SystemSimulationApp/frontend/tests/e2e/native-result.spec.ts
T

94 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from "@playwright/test";
import { expandSimulationConsole, prepareApp, resultSnapshot, wideProject } from "./fixtures";
test.beforeEach(async ({ page }) => {
await page.route("**/api/simulation/runtime-check", route => route.fulfill({ json: {
checkId: "test-runtime", status: "completed", stage: "complete",
message: "仿真环境自检通过", durationMs: 1, error: null, failure: null,
} }));
});
for (const diagnosticsMode of ["native", "legacy-native", "python"] as const) {
test(`completed ${diagnosticsMode} results can be published and restored`, async ({ page }) => {
await prepareApp(page);
const diagnostics = diagnosticsMode === "python"
? resultSnapshot.result.diagnostics
: { backend: "native-c", stateCount: 1,
...(diagnosticsMode === "native" ? { sampleCount: 3 } : {}) };
await page.route("**/api/system-xml/simulate-stream", route => route.fulfill({
contentType: "application/x-ndjson",
body: JSON.stringify({ event: "result", progress: 100, phase: "completed",
result: { ...resultSnapshot.result, diagnostics } }) + "\n",
}));
await page.goto("/");
await page.locator('input[type="file"]').setInputFiles({
name: "native-result.json", mimeType: "application/json",
buffer: Buffer.from(JSON.stringify({ ...wideProject, edges: [...wideProject.edges, {
id: "close-test-loop", source: "generic_sensor_4", target: "generic_sensor_1",
sourceHandle: "port_b", targetHandle: "port_a", data: { isContactEdge: false },
}] })),
});
await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue("native-result");
await page.getByRole("button", { name: "运行仿真", exact: true }).click();
await expandSimulationConsole(page);
const consolePanel = page.getByRole("complementary", { name: "仿真控制台", exact: true });
await expect(consolePanel).toContainText("仿真完成,已生成新的结果,共 3 个采样点");
await expect(consolePanel).not.toContainText("仿真失败");
if (diagnosticsMode === "python") {
await expect(consolePanel).toContainText("最大方程残差 0");
} else {
await expect(consolePanel).not.toContainText("最大方程残差");
}
await expect.poll(() => page.evaluate(() => JSON.parse(sessionStorage.getItem("system-simulation-flow:latest-result") ?? "null")?.storage)).toBe("indexeddb");
const saved = await page.evaluate(async () => {
// @ts-expect-error Vite serves the persistence module in the test browser.
const { loadStoredResultSnapshot } = await import("/src/resultPersistence.ts");
return loadStoredResultSnapshot();
});
expect(saved.result.diagnostics.sampleCount).toBe(3);
expect(saved.result.series).toEqual(resultSnapshot.result.series);
await page.reload();
await page.getByRole("tab", { name: "结果", exact: true }).click();
await expect(page.getByText("3 个采样点", { exact: false }).first()).toBeVisible();
});
}
for (const live of [true, false]) {
test(`property temperature warning is shown once with live delivery ${live}`, async ({ page }) => {
await prepareApp(page);
const message = "氦气物性有效温度越界:状态方程及热力性质的真实气体修正项,t = 0.001 s,T = 1600 K > Tmax = 1500 K。仿真继续计算,超范围物性不保证有效性。";
const warning = { code: "helium-equation-of-state-high", message };
const events = [
...(live ? [0, 1].map(() => ({ event: "progress", progress: 1,
phase: "property-warning", message, simulatedTime: .001, totalTime: 1 })) : []),
{ event: "result", progress: 100, phase: "completed", result: {
...resultSnapshot.result, diagnostics: { backend: "native-c", stateCount: 1,
sampleCount: 3, propertyWarnings: [warning] },
} },
];
await page.route("**/api/system-xml/simulate-stream", route => route.fulfill({
contentType: "application/x-ndjson", body: events.map(e => JSON.stringify(e)).join("\n") + "\n",
}));
await page.goto("/");
await page.locator('input[type="file"]').setInputFiles({
name: "property-warning.json", mimeType: "application/json",
buffer: Buffer.from(JSON.stringify({ ...wideProject, edges: [...wideProject.edges, {
id: "close-test-loop", source: "generic_sensor_4", target: "generic_sensor_1",
sourceHandle: "port_b", targetHandle: "port_a", data: { isContactEdge: false },
}] })),
});
await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue("property-warning");
await page.getByRole("button", { name: "运行仿真", exact: true }).click();
await expandSimulationConsole(page);
const panel = page.getByRole("complementary", { name: "仿真控制台", exact: true });
await expect(panel.getByText(message, { exact: true })).toHaveCount(1);
await expect(panel).toContainText("仿真完成,已生成新的结果,共 3 个采样点");
await expect(panel).not.toContainText("仿真失败");
await expect.poll(() => page.evaluate(async () => {
// @ts-expect-error Vite serves the persistence module in the test browser.
const { loadStoredResultSnapshot } = await import("/src/resultPersistence.ts");
return (await loadStoredResultSnapshot())?.result.diagnostics.propertyWarnings;
})).toEqual([warning]);
});
}