import { expect, test, type Page } from "@playwright/test"; import { expandSimulationConsole, prepareApp, wideProject } from "./fixtures"; const componentId = "amesim_pneumatic_test_1"; const pressureInput = (page: Page) => page.getByLabel("参考压力", { exact: true }); const pressureUnit = (page: Page) => page.getByLabel("参考压力单位", { exact: true }); const selectPressureComponent = (page: Page) => page.locator(`.flow-canvas .react-flow__node[data-id="${componentId}"]`).click(); type ExportedProject = { nodes: Array<{ data: { parameters: Record; parameterUnits: Record; }; }>; }; async function exportProject(page: Page) { const downloadPromise = page.waitForEvent("download"); await page.getByRole("button", { name: "导出工程 JSON", exact: true }).click(); const download = await downloadPromise; const stream = await download.createReadStream(); if (!stream) throw new Error("无法读取导出的工程 JSON"); const chunks: Buffer[] = []; for await (const chunk of stream) chunks.push(Buffer.from(chunk)); const buffer = Buffer.concat(chunks); return { buffer, project: JSON.parse(buffer.toString("utf8")) as ExportedProject, }; } async function expectPressureXml(page: Page, expectedValue: number) { await page.getByRole("button", { name: "生成系统 XML", exact: true }).click(); await expandSimulationConsole(page); await expect(page.getByLabel("生成的系统 XML").last()).toContainText( ` { await prepareApp(page); await page.goto("/"); await expect( page.getByRole("button", { name: "AMESim 气动测试元件", exact: true }), ).toBeVisible(); }); test("压力默认显示 Pa,bar 与 Pa 换算保持绝压且无大气压偏移", async ({ page }) => { await addPressureComponent(page); await expect(pressureUnit(page)).toHaveValue("Pa"); await expect(pressureInput(page)).toHaveValue("100000"); await expect(pressureUnit(page).locator('option[value="barA"]')).toHaveCount(0); await pressureUnit(page).selectOption("bar"); await expect(pressureInput(page)).toHaveValue("1"); await pressureInput(page).fill("2.5"); await pressureInput(page).press("Enter"); await expectPressureXml(page, 250000); for (const { unit, value } of [ { unit: "Pa", value: "250000" }, { unit: "kPa", value: "250" }, { unit: "MPa", value: "0.25" }, { unit: "bar", value: "2.5" }, ]) { await pressureUnit(page).selectOption(unit); await expect(pressureInput(page)).toHaveValue(value); await expectPressureXml(page, 250000); } const exported = await exportProject(page); expect(exported.project.nodes[0].data.parameters.reference_pressure).toBe(250000); expect(exported.project.nodes[0].data.parameterUnits.reference_pressure).toBe("bar"); }); test("bar 压力公式在保存、加载和 JSON 导入导出后保留原式与单位", async ({ page }) => { await addPressureComponent(page); await pressureUnit(page).selectOption("bar"); const expression = "1+1.5"; await pressureInput(page).fill(expression); await pressureInput(page).press("Enter"); await expect(pressureUnit(page)).toHaveValue("bar"); await expectPressureXml(page, 250000); await page.getByRole("button", { name: "保存工程", exact: true }).click(); await pressureInput(page).fill("7"); await pressureInput(page).press("Enter"); await pressureUnit(page).selectOption("kPa"); await page.getByRole("button", { name: "加载工程", exact: true }).click(); await selectPressureComponent(page); await expect(pressureInput(page)).toHaveValue(expression); await expect(pressureUnit(page)).toHaveValue("bar"); const exported = await exportProject(page); expect(exported.project.nodes[0].data.parameters.reference_pressure).toBe(expression); expect(exported.project.nodes[0].data.parameterUnits.reference_pressure).toBe("bar"); await pressureInput(page).fill("9"); await pressureInput(page).press("Enter"); await page.locator('input[type="file"]').setInputFiles({ name: "pressure-expression.json", mimeType: "application/json", buffer: exported.buffer, }); // Wait for the imported project before selecting its component. await expect(page.getByRole("textbox", { name: "工程", exact: true })).toHaveValue( "pressure-expression", ); await selectPressureComponent(page); await expect(pressureInput(page)).toHaveValue(expression); await expect(pressureUnit(page)).toHaveValue("bar"); await expectPressureXml(page, 250000); }); for (const { storedUnit, displayedUnit, displayedValue } of [ { storedUnit: "Pa", displayedUnit: "Pa", displayedValue: "250000" }, { storedUnit: undefined, displayedUnit: "Pa", displayedValue: "250000" }, ]) { test(`旧 JSON 数值参数单位 ${storedUnit ?? "未记录"} 加载为 ${displayedUnit},SI 数值不变`, async ({ page }) => { await page.locator('input[type="file"]').setInputFiles({ name: "legacy-pressure.json", mimeType: "application/json", buffer: Buffer.from(JSON.stringify(legacyPressureProject(250000, storedUnit))), }); await selectPressureComponent(page); await expect(pressureUnit(page)).toHaveValue(displayedUnit); await expect(pressureInput(page)).toHaveValue(displayedValue); await expectPressureXml(page, 250000); const exported = await exportProject(page); expect(exported.project.nodes[0].data.parameters.reference_pressure).toBe(250000); expect(exported.project.nodes[0].data.parameterUnits.reference_pressure).toBe(displayedUnit); }); } test("旧 JSON 公式没有记录单位时沿用原 Pa 含义", async ({ page }) => { const expression = "100000+150000"; await page.locator('input[type="file"]').setInputFiles({ name: "legacy-pressure-expression.json", mimeType: "application/json", buffer: Buffer.from(JSON.stringify(legacyPressureProject(expression))), }); await selectPressureComponent(page); await expect(pressureUnit(page)).toHaveValue("Pa"); await expect(pressureInput(page)).toHaveValue(expression); await expectPressureXml(page, 250000); const exported = await exportProject(page); expect(exported.project.nodes[0].data.parameters.reference_pressure).toBe(expression); expect(exported.project.nodes[0].data.parameterUnits.reference_pressure).toBe("Pa"); }); test("弹性接触的剪切模量 G 保持 Pa 默认单位", async ({ page }) => { await page .getByRole("button", { name: "LSTP00A 弹性接触", exact: true }) .dragTo(page.locator(".flow-canvas .react-flow__pane"), { targetPosition: { x: 620, y: 330 }, }); await page.locator('.flow-canvas .react-flow__node[data-id="amesim_lstp00a_1"]').click(); await page.getByLabel("刚度模式", { exact: true }).selectOption("2"); await page.getByRole("table", { name: "组件参数" }).getByRole("button", { name: /刚度/ }).click(); await expect(page.getByLabel("剪切模量单位", { exact: true })).toHaveValue("Pa"); await expect(page.getByLabel("剪切模量", { exact: true })).toHaveValue("85700000000"); const exported = await exportProject(page); expect(exported.project.nodes[0].data.parameters.G).toBe(8.57e10); expect(exported.project.nodes[0].data.parameterUnits.G).toBe("Pa"); });