更新v2版本适配skill
This commit is contained in:
1 parent
7611f13208
commit
2f3f7d00ec
58 files changed
+180419
-526
No files matched your search
@@ -0,0 +1,75 @@
|
||||
// Run against a separately started backend serving the current frontend build.
|
||||
// No mocked catalog or simulation; a fresh browser context protects user state.
|
||||
import { chromium } from '../../frontend/node_modules/playwright/index.mjs';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
const [baseURL, projectPath, output] = process.argv.slice(2);
|
||||
assert(baseURL && projectPath && output, 'Usage: node tests/manual/system_simulation_skill.mjs BASE_URL PROJECT OUTPUT');
|
||||
const project = JSON.parse(await fs.readFile(projectPath, 'utf8'));
|
||||
await fs.mkdir(output, { recursive: true });
|
||||
const browser = await chromium.launch({ headless: true,
|
||||
...(process.env.PLAYWRIGHT_CHANNEL ? { channel: process.env.PLAYWRIGHT_CHANNEL } : {}),
|
||||
...(process.env.PLAYWRIGHT_EXECUTABLE_PATH ? { executablePath: process.env.PLAYWRIGHT_EXECUTABLE_PATH } : {}),
|
||||
});
|
||||
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 }, acceptDownloads: true });
|
||||
const errors = [];
|
||||
page.on('pageerror', error => errors.push(String(error)));
|
||||
page.setDefaultTimeout(15000);
|
||||
try {
|
||||
await page.goto(baseURL);
|
||||
await page.getByRole('button', { name: '运行仿真', exact: true }).waitFor();
|
||||
await page.locator('input[type="file"][accept*=".json"]').setInputFiles(path.resolve(projectPath));
|
||||
const canvasNodes = page.locator('.flow-canvas .react-flow__node');
|
||||
await page.waitForFunction(count => document.querySelectorAll('.flow-canvas .react-flow__node').length === count, project.nodes.length);
|
||||
assert.equal(await canvasNodes.count(), project.nodes.length);
|
||||
for (const node of project.nodes) {
|
||||
assert.equal(await page.locator(`.flow-canvas .react-flow__node[data-id="${node.id}"]`).count(), 1);
|
||||
}
|
||||
await page.getByRole('button', { name: '检查模型', exact: true }).click();
|
||||
const expand = page.getByRole('button', { name: '展开仿真控制台', exact: true });
|
||||
if (await expand.count()) await expand.click();
|
||||
await page.getByRole('button', { name: '生成系统 XML', exact: true }).click();
|
||||
const xml = await page.getByLabel('生成的系统 XML', { exact: true }).last().innerText();
|
||||
assert.match(xml, /schemaVersion="3"/);
|
||||
assert.match(xml, /name="p0" value="250000"/);
|
||||
assert.match(xml, /name="T0" value="293.15"/);
|
||||
await fs.writeFile(path.join(output, 'browser.xml'), xml);
|
||||
|
||||
const responsePromise = page.waitForResponse(response => response.url().endsWith('/api/system-xml/simulate-stream'), { timeout: 120000 });
|
||||
await page.getByRole('button', { name: '运行仿真', exact: true }).click();
|
||||
const response = await responsePromise;
|
||||
assert(response.ok(), await response.text());
|
||||
const events = (await response.text()).trim().split('\n').map(line => JSON.parse(line));
|
||||
const resultEvent = events.find(event => event.event === 'result');
|
||||
assert(resultEvent?.result?.success, JSON.stringify(events.slice(-3)));
|
||||
const result = resultEvent.result;
|
||||
assert.equal(result.simulatedUntil, project.simulation.t_stop);
|
||||
assert(Object.values(result.series).every(values => values.every(Number.isFinite)));
|
||||
const pressure = result.variables.find(variable => variable.componentId === 'tank' && variable.quantity === 'pressure');
|
||||
assert(pressure && result.series[pressure.key]?.length > 1);
|
||||
assert(result.series[pressure.key].every(value => Math.abs(value - 250000) < 1e-6));
|
||||
await fs.writeFile(path.join(output, 'result.json'), JSON.stringify(result));
|
||||
const downloadPromise = page.waitForEvent('download');
|
||||
await page.getByRole('button', { name: '导出工程 JSON', exact: true }).click();
|
||||
await (await downloadPromise).saveAs(path.join(output, 'roundtrip.json'));
|
||||
const exported = JSON.parse(await fs.readFile(path.join(output, 'roundtrip.json'), 'utf8'));
|
||||
assert.equal(exported.projectSchemaVersion, 2);
|
||||
assert.equal(exported.nodes.length, project.nodes.length);
|
||||
assert.equal(exported.edges.length, project.edges.length);
|
||||
assert.deepEqual(errors, []);
|
||||
await page.screenshot({ path: path.join(output, 'acceptance.png'), fullPage: true });
|
||||
const summary = { browser: browser.version(), components: exported.nodes.length,
|
||||
connections: exported.edges.length, simulatedUntil: result.simulatedUntil,
|
||||
sampleCount: result.series.time.length, pressureKey: pressure.key,
|
||||
browserImport: 'passed', browserExport: 'passed', simulation: 'passed', errors };
|
||||
await fs.writeFile(path.join(output, 'summary.json'), JSON.stringify(summary, null, 2));
|
||||
console.log(JSON.stringify(summary));
|
||||
} catch (error) {
|
||||
await fs.writeFile(path.join(output, 'failure.txt'), `${error.stack}\n${await page.locator('body').innerText()}`);
|
||||
await page.screenshot({ path: path.join(output, 'failure.png'), fullPage: true });
|
||||
throw error;
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
Reference in new issue
Block a user