完善 LinuxCNC 对标矩阵与 gmoccapy TRT 仿真
This commit is contained in:
@@ -71,9 +71,12 @@
|
||||
throw new Error(`executed G-code row should be light gray, got ${previousBackground}`);
|
||||
}
|
||||
}
|
||||
const listText = list.textContent;
|
||||
if (/\bpending\b|\bstopped\s+\|\s+F\b|\brunning\s+\|\s+F\b/.test(listText)) {
|
||||
throw new Error("G-code list should not render execution status text");
|
||||
const executionText = activeRow.querySelector("[data-line-execution]")?.textContent || "";
|
||||
if (
|
||||
executionText &&
|
||||
!/\b(running|done|paused|stopped|mdi|ready)\b\s+\|\s+F\s+[-.\d]+\s+\|\s+cycle\s+\d+\/\d+/.test(executionText)
|
||||
) {
|
||||
throw new Error(`G-code line execution text has unexpected format: ${executionText}`);
|
||||
}
|
||||
const rowBounds = activeRow.getBoundingClientRect();
|
||||
const listBounds = list.getBoundingClientRect();
|
||||
@@ -82,6 +85,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
function assertSidebarModeVisualState(doc, { manualActive, autoActive }) {
|
||||
const expected = [
|
||||
[doc.querySelector('[data-action="mode-manual"]'), "MANUAL", manualActive],
|
||||
[doc.querySelector('[data-action="mode-auto"]'), "AUTO", autoActive],
|
||||
];
|
||||
for (const [button, label, active] of expected) {
|
||||
if (!button) {
|
||||
throw new Error(`missing ${label} mode button`);
|
||||
}
|
||||
if (button.dataset.active !== String(active)) {
|
||||
throw new Error(`${label} mode button active flag should be ${active}, got ${button.dataset.active}`);
|
||||
}
|
||||
const style = getComputedStyle(button);
|
||||
const backgroundImage = style.backgroundImage;
|
||||
const color = style.color.replace(/\s/g, "");
|
||||
if (active) {
|
||||
if (!backgroundImage.includes("rgb(174, 233, 174)") || color !== "rgb(7,95,22)") {
|
||||
throw new Error(`${label} active mode button should render green, got ${backgroundImage} / ${color}`);
|
||||
}
|
||||
} else if (!backgroundImage.includes("rgb(221, 217, 209)") || color !== "rgb(48,48,48)") {
|
||||
throw new Error(`${label} inactive mode button should render gray, got ${backgroundImage} / ${color}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function runSmoke() {
|
||||
await new Promise((resolve, reject) => {
|
||||
frame.addEventListener("load", resolve, { once: true });
|
||||
@@ -216,6 +244,21 @@
|
||||
if (!profileSelector || profileSelector.options.length < 2) {
|
||||
throw new Error("missing five-axis profile selector");
|
||||
}
|
||||
const titlebar = doc.querySelector('[data-region="titlebar"]');
|
||||
const currentLineIndicator = titlebar?.querySelector("[data-titlebar-current-line]");
|
||||
if (!titlebar || !currentLineIndicator) {
|
||||
throw new Error("missing stable titlebar nodes");
|
||||
}
|
||||
win.webRtcp5AxisSimulation.dispatch({ type: "SET_VIEW", view: "x" });
|
||||
await wait(50);
|
||||
if (profileSelector !== doc.querySelector('[data-action="select-profile"]')) {
|
||||
throw new Error("titlebar profile selector should not be remounted on state updates");
|
||||
}
|
||||
if (currentLineIndicator !== doc.querySelector("[data-titlebar-current-line]")) {
|
||||
throw new Error("titlebar current-line indicator should not be remounted on state updates");
|
||||
}
|
||||
win.webRtcp5AxisSimulation.dispatch({ type: "RESET_VIEW" });
|
||||
await wait(50);
|
||||
profileSelector.value = "xyzbc-trt";
|
||||
profileSelector.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
await wait(500);
|
||||
@@ -273,7 +316,7 @@
|
||||
['[data-action="STOP"]', "stop"],
|
||||
['[data-action="PAUSE"]', "pause"],
|
||||
['[data-action="HOME"]', "ref_all"],
|
||||
['[data-action="toggle-flood"]', "coolant_flood_active"],
|
||||
['[data-action="toggle-flood"]', "coolant_flood_inactive"],
|
||||
['[data-action="toggle-mist"]', "coolant_mist_inactive"],
|
||||
['[data-action="view-x"]', "tool_axis_x"],
|
||||
]) {
|
||||
@@ -523,6 +566,18 @@
|
||||
}
|
||||
doc.querySelector('[data-action="mode-auto"]').click();
|
||||
await wait(50);
|
||||
const autoModeState = win.webRtcp5AxisSimulation.getState();
|
||||
if (autoModeState.machine.mode !== "auto") {
|
||||
throw new Error(`AUTO mode button did not switch task mode: ${autoModeState.machine.mode}`);
|
||||
}
|
||||
if (autoModeState.machine.powerOn !== true || autoModeState.machine.taskState !== "on") {
|
||||
throw new Error(`AUTO mode button should preserve machine power: ${JSON.stringify(autoModeState.machine)}`);
|
||||
}
|
||||
const postAutoManualButton = doc.querySelector('[data-action="mode-manual"]');
|
||||
if (postAutoManualButton?.disabled || postAutoManualButton.dataset.commandReady !== "true") {
|
||||
throw new Error("MANUAL mode button should remain enabled after switching to AUTO");
|
||||
}
|
||||
assertSidebarModeVisualState(doc, { manualActive: false, autoActive: true });
|
||||
if (!doc.querySelector('[data-linuxcnc-task-policy="gates"]')?.textContent.includes("auto")) {
|
||||
throw new Error("LinuxCNC task policy did not expose auto run gate");
|
||||
}
|
||||
@@ -779,6 +834,10 @@
|
||||
throw new Error("RUN did not highlight a LinuxCNC task/HAL motion line");
|
||||
}
|
||||
assertActiveGcodeRowVisible(doc);
|
||||
const runExecutionText = doc.querySelector(".gcode-row.active [data-line-execution]")?.textContent || "";
|
||||
if (!runExecutionText.includes("F ") || !runExecutionText.includes("cycle") || !runExecutionText.includes("linuxcnc-task-motion-hal-wasm")) {
|
||||
throw new Error(`RUN did not render current G-code line execution details: ${runExecutionText}`);
|
||||
}
|
||||
const stopLineBefore = win.webRtcp5AxisSimulation.getState().activeLine;
|
||||
doc.querySelector('[data-action="STOP"]').click();
|
||||
await wait(150);
|
||||
@@ -928,6 +987,7 @@
|
||||
}
|
||||
doc.querySelector('[data-action="mode-manual"]').click();
|
||||
await wait(50);
|
||||
assertSidebarModeVisualState(doc, { manualActive: true, autoActive: false });
|
||||
doc.querySelector('[data-action="mode-jog"]').click();
|
||||
await wait(50);
|
||||
const xBeforeJog = win.webRtcp5AxisSimulation.getState().axisPose.x;
|
||||
@@ -1248,7 +1308,7 @@
|
||||
doc.querySelector('[data-action="toggle-mist"]').click();
|
||||
await wait(50);
|
||||
const coolantState = win.webRtcp5AxisSimulation.getState().coolant;
|
||||
if (coolantState.flood !== false || coolantState.mist !== true) {
|
||||
if (coolantState.flood !== true || coolantState.mist !== true) {
|
||||
throw new Error("coolant buttons did not update state");
|
||||
}
|
||||
doc.querySelector('[data-action="view-x"]').click();
|
||||
|
||||
Reference in New Issue
Block a user