结论:新增 LinuxCNC WASM 驱动的真实浏览器仿真页面,接入 browser smoke、release gate、SDK 与项目交付文档,并完成当前推进批次的验收记录。
84 lines
3.1 KiB
HTML
84 lines
3.1 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>LinuxCNC Real Simulation Page Smoke</title>
|
|
</head>
|
|
<body>
|
|
<pre id="status">running</pre>
|
|
<script type="module">
|
|
const status = document.getElementById("status");
|
|
|
|
async function loadFrame(src) {
|
|
const frame = document.createElement("iframe");
|
|
frame.src = src;
|
|
frame.width = "1280";
|
|
frame.height = "800";
|
|
document.body.appendChild(frame);
|
|
await new Promise((resolve, reject) => {
|
|
frame.addEventListener("load", resolve, { once: true });
|
|
frame.addEventListener("error", reject, { once: true });
|
|
});
|
|
return frame;
|
|
}
|
|
|
|
async function waitForState(frame) {
|
|
for (let i = 0; i < 200; i += 1) {
|
|
const state = frame.contentWindow?.linuxCncRealSimulationState;
|
|
if (state?.summary?.ready) {
|
|
return state;
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
}
|
|
throw new Error("real simulation page did not expose ready state");
|
|
}
|
|
|
|
try {
|
|
const frame = await loadFrame("../../runtime/ui/simulation/index.html");
|
|
const doc = frame.contentDocument;
|
|
const state = await waitForState(frame);
|
|
const polyline = doc.querySelector("[data-toolpath-polyline]");
|
|
const rows = [...doc.querySelectorAll("[data-motion-row]")];
|
|
const programRows = [...doc.querySelectorAll("[data-program-line]")];
|
|
const canonicalOutput = doc.querySelector("[data-canonical-output]")?.textContent ?? "";
|
|
|
|
if (doc.body.dataset.simulationReady !== "true") {
|
|
throw new Error("simulation body readiness flag not true");
|
|
}
|
|
if (state.apiName !== "real-browser-simulation-state") {
|
|
throw new Error("simulation state API name drift");
|
|
}
|
|
if (state.summary.motionEventCount < 5) {
|
|
throw new Error("simulation motion event count too low");
|
|
}
|
|
if (!canonicalOutput.includes("canon_event=STRAIGHT_FEED line=2 x=1 y=0 z=0")) {
|
|
throw new Error("simulation canonical output missing LinuxCNC feed event");
|
|
}
|
|
if (!polyline?.getAttribute("points")?.includes("1,0")) {
|
|
throw new Error("simulation toolpath polyline missing expected point");
|
|
}
|
|
if (rows.length !== state.motion.length) {
|
|
throw new Error("simulation motion table row count drift");
|
|
}
|
|
if (programRows.length < 6) {
|
|
throw new Error("simulation program rows missing");
|
|
}
|
|
if (doc.querySelector('[data-axis="x"]')?.textContent !== "0.000") {
|
|
throw new Error("simulation final X axis drift");
|
|
}
|
|
if (doc.querySelector('[data-axis="y"]')?.textContent !== "0.000") {
|
|
throw new Error("simulation final Y axis drift");
|
|
}
|
|
if (!doc.querySelector("[data-toolpath-svg]")?.getAttribute("viewBox")) {
|
|
throw new Error("simulation SVG viewBox missing");
|
|
}
|
|
|
|
status.textContent = "browser_real_simulation_page_smoke=ok";
|
|
} catch (error) {
|
|
status.textContent = `browser_real_simulation_page_smoke=fail ${error.stack || error.message}`;
|
|
throw error;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|