实现AXIS风格仿真外壳
结论:真实浏览器仿真页面完成 AXIS-style Phase 1 外壳,新增菜单、工具栏、Manual/MDI、Preview/DRO、G-code pane、machine state 和状态栏,并保留 LinuxCNC WASM 执行与回放验证。
This commit is contained in:
@@ -68,6 +68,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
function assertAxisShell(doc) {
|
||||
for (const region of [
|
||||
"titlebar",
|
||||
"menubar",
|
||||
"toolbar",
|
||||
"workspace",
|
||||
"manual-mdi",
|
||||
"preview-dro",
|
||||
"active-codes",
|
||||
"gcode-pane",
|
||||
"machine-state",
|
||||
"statusbar",
|
||||
]) {
|
||||
if (!doc.querySelector(`[data-axis-shell="${region}"]`)) {
|
||||
throw new Error(`AXIS-style shell missing ${region}`);
|
||||
}
|
||||
}
|
||||
for (const tab of ["manual", "mdi", "preview", "dro"]) {
|
||||
if (!doc.querySelector(`[data-axis-tab="${tab}"]`)) {
|
||||
throw new Error(`AXIS-style shell missing ${tab} tab`);
|
||||
}
|
||||
if (!doc.querySelector(`[data-axis-panel="${tab}"]`)) {
|
||||
throw new Error(`AXIS-style shell missing ${tab} panel`);
|
||||
}
|
||||
}
|
||||
const menuText = doc.querySelector('[data-axis-shell="menubar"]')?.textContent ?? "";
|
||||
for (const label of ["File", "Machine", "View", "Help"]) {
|
||||
if (!menuText.includes(label)) {
|
||||
throw new Error(`AXIS-style menu missing ${label}`);
|
||||
}
|
||||
}
|
||||
const statusText = doc.querySelector('[data-axis-shell="statusbar"]')?.textContent ?? "";
|
||||
if (!statusText.includes("ESTOP") || !statusText.includes("Position: Relative Actual")) {
|
||||
throw new Error(`AXIS-style statusbar drift: ${statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const frame = await loadFrame("../../runtime/ui/simulation/index.html");
|
||||
const doc = frame.contentDocument;
|
||||
@@ -75,6 +112,7 @@
|
||||
const canonicalOutput = doc.querySelector("[data-canonical-output]")?.textContent ?? "";
|
||||
const api = frame.contentWindow?.linuxCncRealSimulationApi;
|
||||
|
||||
assertAxisShell(doc);
|
||||
assertRenderedState(doc, state);
|
||||
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");
|
||||
@@ -100,6 +138,27 @@
|
||||
throw new Error("simulation test program inventory too small");
|
||||
}
|
||||
|
||||
doc.querySelector('[data-axis-tab="mdi"]')?.click();
|
||||
if (!doc.querySelector('[data-axis-panel="manual"]')?.hidden || doc.querySelector('[data-axis-panel="mdi"]')?.hidden) {
|
||||
throw new Error("AXIS-style Manual/MDI tab switch failed");
|
||||
}
|
||||
doc.querySelector('[data-axis-tab="manual"]')?.click();
|
||||
if (doc.querySelector('[data-axis-panel="manual"]')?.hidden || !doc.querySelector('[data-axis-panel="mdi"]')?.hidden) {
|
||||
throw new Error("AXIS-style Manual tab restore failed");
|
||||
}
|
||||
|
||||
doc.querySelector('[data-axis-tab="dro"]')?.click();
|
||||
if (!doc.querySelector('[data-axis-panel="preview"]')?.hidden || doc.querySelector('[data-axis-panel="dro"]')?.hidden) {
|
||||
throw new Error("AXIS-style Preview/DRO tab switch failed");
|
||||
}
|
||||
if (doc.querySelector('[data-axis-shell="dro-readout"]')?.textContent.includes("undefined")) {
|
||||
throw new Error("AXIS-style DRO should not render undefined fields");
|
||||
}
|
||||
doc.querySelector('[data-axis-tab="preview"]')?.click();
|
||||
if (doc.querySelector('[data-axis-panel="preview"]')?.hidden || !doc.querySelector('[data-axis-panel="dro"]')?.hidden) {
|
||||
throw new Error("AXIS-style Preview tab restore failed");
|
||||
}
|
||||
|
||||
api.resetPlayback();
|
||||
if (doc.body.dataset.playbackIndex !== "0") {
|
||||
throw new Error("simulation playback did not reset to first frame");
|
||||
@@ -130,6 +189,11 @@
|
||||
throw new Error("simulation step playback did not highlight active motion row");
|
||||
}
|
||||
|
||||
doc.querySelector("[data-playback-next]")?.click();
|
||||
if (doc.body.dataset.playbackIndex !== "2") {
|
||||
throw new Error("AXIS-style toolbar step button did not advance playback");
|
||||
}
|
||||
|
||||
const finishedFrame = api.finishPlayback();
|
||||
if (finishedFrame.index !== state.motion.length - 1 || doc.body.dataset.playbackComplete !== "true") {
|
||||
throw new Error("simulation finish playback did not reach final frame");
|
||||
|
||||
Reference in New Issue
Block a user