199 lines
8.1 KiB
TypeScript
199 lines
8.1 KiB
TypeScript
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<string, number | string>;
|
||
parameterUnits: Record<string, string>;
|
||
};
|
||
}>;
|
||
};
|
||
|
||
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(
|
||
`<Parameter name="reference_pressure" value="${expectedValue}"`,
|
||
);
|
||
}
|
||
|
||
async function addPressureComponent(page: Page) {
|
||
await page
|
||
.getByRole("button", { name: "AMESim 气动测试元件", exact: true })
|
||
.dragTo(page.locator(".flow-canvas .react-flow__pane"), {
|
||
targetPosition: { x: 620, y: 330 },
|
||
});
|
||
await selectPressureComponent(page);
|
||
}
|
||
|
||
function legacyPressureProject(value: number | string, unit?: string) {
|
||
return {
|
||
...wideProject,
|
||
nodes: [{
|
||
...wideProject.nodes[0],
|
||
id: componentId,
|
||
data: {
|
||
...wideProject.nodes[0].data,
|
||
label: componentId,
|
||
componentType: "amesim_pneumatic_test",
|
||
modelType: "amesim_pneumatic_test",
|
||
parameters: {
|
||
gi: 0,
|
||
reference_pressure: value,
|
||
reference_temperature: 300,
|
||
},
|
||
parameterUnits: unit ? { reference_pressure: unit } : undefined,
|
||
},
|
||
}],
|
||
edges: [],
|
||
};
|
||
}
|
||
|
||
test.beforeEach(async ({ page }) => {
|
||
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(2.5);
|
||
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");
|
||
});
|