现有组件功能与Amesim组件比较对齐,补全功能;仿真服务启动环境检测,旧版json工程文件适配读取
This commit is contained in:
1 parent
b6c22a54f8
commit
6fc9afe41d
119 files changed
+260114
-351
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
import { prepareApp, wideProject } from "./fixtures";
|
||||
import { expandSimulationConsole, prepareApp, wideProject } from "./fixtures";
|
||||
|
||||
const projectNameField = (page: Page) =>
|
||||
page.getByRole("textbox", { name: "工程", exact: true });
|
||||
@@ -72,7 +72,7 @@ test("外部重命名的工程 JSON 导入后名称一致,保存和刷新后
|
||||
);
|
||||
return raw ? JSON.parse(raw) : null;
|
||||
}, renamedProject);
|
||||
expect(saved).toMatchObject({ name: renamedProject });
|
||||
expect(saved).toMatchObject({ name: renamedProject, projectSchemaVersion: 2 });
|
||||
expect(saved.nodes).toHaveLength(wideProject.nodes.length);
|
||||
|
||||
await deleteFirstNode(page);
|
||||
@@ -93,6 +93,156 @@ test("外部重命名的工程 JSON 导入后名称一致,保存和刷新后
|
||||
await expect(projectNameField(page)).toHaveValue(renamedProject);
|
||||
});
|
||||
|
||||
for (const pressure of [2.5, "1+1.5"]) {
|
||||
test(`v2 浏览器保存、加载及草稿恢复不重复提示或换算:${pressure}`, async ({ page }) => {
|
||||
const project = { ...wideProject, projectSchemaVersion: 2, name: "unit-roundtrip", edges: [],
|
||||
nodes: [{ ...wideProject.nodes[0], id: "pressure_1", data: {
|
||||
...wideProject.nodes[0].data, label: "pressure_1", componentType: "amesim_pneumatic_test",
|
||||
modelType: "amesim_pneumatic_test", parameters: {
|
||||
gi: 0, reference_pressure: pressure, reference_temperature: 20,
|
||||
}, parameterUnits: { reference_pressure: "bar", reference_temperature: "degC" },
|
||||
} }],
|
||||
};
|
||||
await page.locator('input[type="file"]').setInputFiles({ name: "unit-roundtrip.json",
|
||||
mimeType: "application/json", buffer: Buffer.from(JSON.stringify(project)) });
|
||||
await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(1);
|
||||
await expandSimulationConsole(page);
|
||||
const consolePanel = page.getByRole("complementary", { name: "仿真控制台", exact: true });
|
||||
const readSaved = () => page.evaluate(() => JSON.parse(localStorage.getItem("system-simulation-flow:autosave") || "null"));
|
||||
await expect.poll(async () => (await readSaved())?.projectSchemaVersion).toBe(2);
|
||||
for (let iteration = 0; iteration < 3; iteration++) {
|
||||
await page.getByRole("button", { name: "保存工程", exact: true }).click();
|
||||
const saved = await readSaved();
|
||||
expect(saved.nodes[0].data.parameters.reference_pressure).toBe(pressure);
|
||||
expect(saved.nodes[0].data.parameters.reference_temperature).toBe(20);
|
||||
const exported = await exportProject(page);
|
||||
expect(exported.project).toEqual(saved);
|
||||
await page.getByRole("button", { name: "加载工程", exact: true }).click();
|
||||
await expect(consolePanel).not.toContainText("已按旧工程规则读取参数");
|
||||
}
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible();
|
||||
await page.getByRole("button", { name: "恢复", exact: true }).click();
|
||||
await expandSimulationConsole(page);
|
||||
await expect(consolePanel).not.toContainText("已按旧工程规则读取参数");
|
||||
await page.getByRole("button", { name: "生成系统 XML", exact: true }).click();
|
||||
await expect(page.getByLabel("生成的系统 XML").last()).toContainText('name="reference_pressure" value="250000"');
|
||||
await expect(page.getByLabel("生成的系统 XML").last()).toContainText('name="reference_temperature" value="293.15"');
|
||||
});
|
||||
}
|
||||
|
||||
test("草稿提示空闲淡出、交互暂停,精简按钮直接恢复且不删除存档", async ({ page }) => {
|
||||
await page.evaluate(project => localStorage.setItem("system-simulation-flow:autosave", JSON.stringify(project)), wideProject);
|
||||
await page.clock.install();
|
||||
await page.reload();
|
||||
const banner = page.locator(".recovery-banner");
|
||||
await expect(banner).toBeVisible();
|
||||
await banner.hover();
|
||||
await page.clock.runFor(6000);
|
||||
await expect(banner).toBeVisible();
|
||||
await page.mouse.move(0, 0);
|
||||
await page.getByRole("button", { name: "恢复", exact: true }).focus();
|
||||
await page.clock.runFor(6000);
|
||||
await expect(banner).toBeVisible();
|
||||
await projectNameField(page).focus();
|
||||
await page.clock.runFor(5100);
|
||||
await expect(banner).toHaveClass(/is-fading/);
|
||||
await page.clock.runFor(200);
|
||||
await expect(banner).toHaveCount(0);
|
||||
expect(await page.evaluate(() => JSON.parse(localStorage.getItem("system-simulation-flow:pending-recovery")!).nodes.length)).toBe(4);
|
||||
await expect(page.locator(".save-indicator")).toHaveCount(0);
|
||||
await page.getByRole("button", { name: "恢复草稿", exact: true }).click();
|
||||
await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(4);
|
||||
await expect(banner).toHaveCount(0);
|
||||
await expect(page.getByRole("button", { name: "恢复草稿", exact: true })).toBeDisabled();
|
||||
});
|
||||
|
||||
test("草稿提示立即让位于粘贴提示,结束粘贴后不自动弹回", async ({ page }) => {
|
||||
await page.evaluate(project => localStorage.setItem("system-simulation-flow:autosave", JSON.stringify(project)), wideProject);
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible();
|
||||
await page.locator(".recovery-banner").hover();
|
||||
await page.locator('input[type="file"]').setInputFiles({ name: "other.json",
|
||||
mimeType: "application/json", buffer: Buffer.from(JSON.stringify(wideProject)) });
|
||||
await page.locator('.flow-canvas .react-flow__node[data-id="generic_sensor_1"]').click();
|
||||
await page.keyboard.press("Control+c");
|
||||
await page.keyboard.press("Control+v");
|
||||
await expect(page.locator(".pending-paste-hint")).toBeVisible();
|
||||
await expect(page.locator(".recovery-banner")).toHaveCount(0);
|
||||
await page.keyboard.press("Escape");
|
||||
await expect(page.locator(".recovery-banner")).toHaveCount(0);
|
||||
await page.getByRole("button", { name: "恢复草稿", exact: true }).click();
|
||||
await expect(page.locator(".recovery-banner")).toHaveCount(0);
|
||||
await expect(projectNameField(page)).toHaveValue(wideProject.name);
|
||||
await expect(page.getByRole("button", { name: "恢复草稿", exact: true })).toBeDisabled();
|
||||
});
|
||||
|
||||
test("未恢复旧草稿也正常自动保存,控制台每 30 秒汇总成功消息且空闲不刷屏", async ({ page }) => {
|
||||
await page.evaluate(project => localStorage.setItem("system-simulation-flow:autosave", JSON.stringify(project)), wideProject);
|
||||
await page.clock.install();
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible();
|
||||
await page.locator('input[type="file"]').setInputFiles({ name: "current-work.json",
|
||||
mimeType: "application/json", buffer: Buffer.from(JSON.stringify(wideProject)) });
|
||||
await expandSimulationConsole(page);
|
||||
await page.clock.runFor(1000);
|
||||
const stored = await page.evaluate(() => ({
|
||||
current: JSON.parse(localStorage.getItem("system-simulation-flow:autosave")!),
|
||||
recovery: JSON.parse(localStorage.getItem("system-simulation-flow:pending-recovery")!),
|
||||
}));
|
||||
expect(stored.current).toMatchObject({ projectSchemaVersion: 2, name: "current-work" });
|
||||
expect(stored.recovery).toEqual(wideProject);
|
||||
await expect(page.getByRole("button", { name: "恢复草稿", exact: true })).toBeEnabled();
|
||||
await expect(page.locator(".save-indicator")).toHaveCount(0);
|
||||
expect(await projectNameField(page).evaluate(input => input.getBoundingClientRect().width)).toBeGreaterThanOrEqual(240);
|
||||
const notices = page.locator(".simulation-console-dock-entry-message").filter({ hasText: "工程已自动保存:" });
|
||||
await expect(notices).toHaveCount(0);
|
||||
await page.clock.runFor(30_000);
|
||||
await expect(notices).toHaveCount(1);
|
||||
await expect(notices.last()).toContainText("current-work");
|
||||
await page.clock.runFor(30_000);
|
||||
await expect(notices).toHaveCount(1);
|
||||
await projectNameField(page).fill("changed-work");
|
||||
await page.clock.runFor(31_000);
|
||||
await expect(notices).toHaveCount(2);
|
||||
await expect(notices.last()).toContainText("changed-work");
|
||||
await page.getByRole("button", { name: "恢复草稿", exact: true }).click();
|
||||
await expect(projectNameField(page)).toHaveValue(wideProject.name);
|
||||
expect(await page.evaluate(() => localStorage.getItem("system-simulation-flow:pending-recovery"))).toBeNull();
|
||||
});
|
||||
|
||||
test("旧草稿未处理时编辑并刷新,下次恢复最近的自动保存而非旧副本", async ({ page }) => {
|
||||
await page.evaluate(project => localStorage.setItem("system-simulation-flow:autosave", JSON.stringify(project)), wideProject);
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible();
|
||||
await page.locator('input[type="file"]').setInputFiles({ name: "newer-work.json",
|
||||
mimeType: "application/json", buffer: Buffer.from(JSON.stringify(wideProject)) });
|
||||
await expect.poll(() => page.evaluate(() => JSON.parse(localStorage.getItem("system-simulation-flow:autosave")!).name)).toBe("newer-work");
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: /通用测试元件/ })).toBeVisible();
|
||||
await page.getByRole("button", { name: "恢复草稿", exact: true }).click();
|
||||
await expect(projectNameField(page)).toHaveValue("newer-work");
|
||||
await expect(page.locator(".flow-canvas .react-flow__node")).toHaveCount(4);
|
||||
});
|
||||
|
||||
test("不能编码新版的工程不覆盖已有浏览器存档,也不下载旧格式", async ({ page }) => {
|
||||
const storageKey = `system-simulation-flow:project:${wideProject.name}`;
|
||||
await page.evaluate(({ key, project }) => localStorage.setItem(key, JSON.stringify(project)), { key: storageKey, project: wideProject });
|
||||
const invalid = structuredClone(wideProject);
|
||||
Object.assign(invalid.nodes[0].data.parameters, { obsolete: 1 });
|
||||
await page.locator('input[type="file"]').setInputFiles({ name: `${wideProject.name}.json`,
|
||||
mimeType: "application/json", buffer: Buffer.from(JSON.stringify(invalid)) });
|
||||
await expandSimulationConsole(page);
|
||||
await page.getByRole("button", { name: "保存工程", exact: true }).click();
|
||||
await expect(page.getByRole("complementary", { name: "仿真控制台", exact: true })).toContainText("保存失败");
|
||||
expect(await page.evaluate(key => JSON.parse(localStorage.getItem(key)!), storageKey)).toEqual(wideProject);
|
||||
const downloads: string[] = [];
|
||||
page.on("download", download => downloads.push(download.suggestedFilename()));
|
||||
await page.getByRole("button", { name: "导出工程 JSON", exact: true }).click();
|
||||
await expect(page.getByRole("complementary", { name: "仿真控制台", exact: true })).toContainText("未生成旧格式文件");
|
||||
expect(downloads).toEqual([]);
|
||||
});
|
||||
|
||||
test("浏览器工程内容保留旧名称时,按存储名称连续加载仍能恢复工程", async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
Reference in new issue
Block a user