import { expect, test } from "@playwright/test"; import { componentCatalog, expandSimulationConsole, prepareApp, wideProject } from "./fixtures"; const extraInputs = ["vol1", "vol2", "vol3", "vol4", "dvol1", "dvol2", "dvol3", "dvol4"]; const chamber = { type: "amesim_pnch012", modelType: "amesim_pnch012", modelVersion: "0.1.0", label: "PNCH012 变容气室", symbol: "amesim_pnch012", order: 99, category: { id: "storage", label: "储能元件", order: 20 }, ports: Array.from({ length: 4 }, (_, index) => ({ ...wideProject.nodes[0].data.ports[index % 2], name: `port_${index + 1}`, order: index })), parameters: [ { name: "gi", label: "气体类型索引", default: 1, quantity: "dimensionless", unit: "" }, { name: "cvol0", label: "死容积", default: 0.015, quantity: "volume", unit: "m3" }, { name: "kth", label: "换热系数", default: 0, quantity: "heat_transfer_coefficient", unit: "W/(m2*K)" }, { name: "sth", label: "换热面积", default: 0.1, quantity: "area", unit: "m2" }, { name: "extemp", label: "外部温度", default: 293.15, quantity: "temperature", unit: "K" }, { name: "p0", label: "初始压力", default: 100000, quantity: "pressure", unit: "Pa" }, { name: "T0", label: "初始温度", default: 293.15, quantity: "temperature", unit: "K" }, ...extraInputs.map(name => ({ name, label: `端口 ${name.at(-1)} ${name.startsWith("d") ? "容积变化率" : "外部容积"}`, default: 0, quantity: name.startsWith("d") ? "volume_flow" : "volume", unit: name.startsWith("d") ? "m3/s" : "m3" })), ], }; test.beforeEach(async ({ page }) => { await prepareApp(page); await page.route("**/api/components/catalog", route => route.fulfill({ json: { ...componentCatalog, libraries: [{ ...componentCatalog.libraries[1], components: [chamber] }], } })); await page.goto("/"); await expect(page.getByRole("button", { name: chamber.label, exact: true })).toBeVisible(); }); test("PNCH012 新元件仅展示 Amesim 设置,端口容积输入默认仍为零", async ({ page }) => { await page.getByRole("button", { name: chamber.label, exact: true }).dragTo(page.locator(".flow-canvas .react-flow__pane")); const table = page.getByRole("table", { name: "组件参数", exact: true }); for (const parameter of chamber.parameters.slice(0, 7)) { await expect(table.getByRole("rowheader", { name: parameter.label, exact: true })).toBeVisible(); } for (const parameter of chamber.parameters.slice(7)) { await expect(table.getByRole("rowheader", { name: parameter.label, exact: true })).toHaveCount(0); } await page.getByRole("button", { name: "保存工程", exact: true }).click(); const parameters = await page.evaluate(() => JSON.parse(localStorage.getItem("system-simulation-flow:autosave")!).nodes[0].data.parameters); for (const name of extraInputs) expect(parameters[name]).toBe(0); }); test("隐藏端口输入不清除旧工程的非零值或表达式,保存导出及 XML 保持原值", async ({ page }) => { const parameters = { ...Object.fromEntries(chamber.parameters.map(parameter => [parameter.name, parameter.default])), vol1: 0.00123, vol2: "2*0.0001", dvol1: 0.0000042 }; const node = { ...wideProject.nodes[0], id: "chamber_1", data: { ...wideProject.nodes[0].data, componentType: chamber.type, modelType: chamber.modelType, modelVersion: chamber.modelVersion, ports: chamber.ports, parameters, parameterUnits: Object.fromEntries(chamber.parameters.map(parameter => [parameter.name, parameter.unit])), } }; await page.locator('input[type="file"]').setInputFiles({ name: "old-chamber.json", mimeType: "application/json", buffer: Buffer.from(JSON.stringify({ ...wideProject, nodes: [node], edges: [] })) }); await page.locator('.flow-canvas .react-flow__node[data-id="chamber_1"]').click(); for (const parameter of chamber.parameters.slice(7)) { await expect(page.getByRole("table", { name: "组件参数", exact: true }).getByRole("rowheader", { name: parameter.label, exact: true })).toHaveCount(0); } await page.getByRole("button", { name: "保存工程", exact: true }).click(); await page.getByRole("button", { name: "加载工程", exact: true }).click(); const downloadPromise = page.waitForEvent("download"); await page.getByRole("button", { name: "导出工程 JSON", exact: true }).click(); const stream = await (await downloadPromise).createReadStream(); if (!stream) throw new Error("没有导出的工程"); const chunks: Buffer[] = []; for await (const chunk of stream) chunks.push(Buffer.from(chunk)); expect(JSON.parse(Buffer.concat(chunks).toString()).nodes[0].data.parameters).toEqual(parameters); await page.getByRole("button", { name: "生成系统 XML", exact: true }).click(); await expandSimulationConsole(page); const xml = page.getByLabel("生成的系统 XML").last(); await expect(xml).toContainText('name="vol1" value="0.00123"'); await expect(xml).toContainText('name="vol2" value="0.0002"'); await expect(xml).toContainText('name="dvol1" value="0.0000042"'); });