fix: make Pause button pause running program
This commit is contained in:
@@ -1007,6 +1007,19 @@
|
||||
if (win.webRtcp5AxisSimulation.getState().runState !== "running") {
|
||||
throw new Error("RESUME action did not restore running state");
|
||||
}
|
||||
doc.querySelector('[data-action="PAUSE"]').click();
|
||||
await wait(50);
|
||||
if (
|
||||
win.webRtcp5AxisSimulation.getState().runState !== "paused" ||
|
||||
win.webRtcp5AxisSimulation.getState().machine.interpState !== "paused"
|
||||
) {
|
||||
throw new Error("PAUSE action did not pause running task on direct second use");
|
||||
}
|
||||
doc.querySelector('[data-action="RESUME"]').click();
|
||||
await wait(50);
|
||||
if (win.webRtcp5AxisSimulation.getState().runState !== "running") {
|
||||
throw new Error("RESUME action did not restore running state after direct second pause");
|
||||
}
|
||||
const tcpButton = doc.querySelector('[data-action="kins-tcp"]');
|
||||
tcpButton.click();
|
||||
await wait(50);
|
||||
|
||||
@@ -143,11 +143,24 @@
|
||||
if (!Array.isArray(buttonParity) || buttonParity.length < 50) {
|
||||
throw new Error(`AXIS button parity list too small: ${buttonParity?.length}`);
|
||||
}
|
||||
for (const action of ["estop", "power", "run-ready", "run", "pause", "resume", "step", "stop", "home-all", "jog-plus", "jog-minus", "kins-identity", "kins-tcp", "kins-userk", "clear-preview"]) {
|
||||
for (const action of ["estop", "power", "run-ready", "run", "pause", "resume", "pause-resume", "step", "stop", "home-all", "jog-plus", "jog-minus", "spindle-reverse", "spindle-stop", "spindle-forward", "kins-identity", "kins-tcp", "kins-userk", "clear-preview"]) {
|
||||
if (!buttonParity.some((item) => item.action === action && item.sourceSymbol && item.sourceLines && item.expected)) {
|
||||
throw new Error(`missing source-referenced button parity for ${action}`);
|
||||
}
|
||||
}
|
||||
const domControls = [...doc.querySelectorAll("[data-action], [data-menu-command]")];
|
||||
for (const action of [...new Set(buttonParity.map((item) => item.action))]) {
|
||||
const controls = domControls.filter((control) => (
|
||||
control.dataset.action === action ||
|
||||
control.dataset.menuCommand === action
|
||||
));
|
||||
if (controls.length === 0) {
|
||||
throw new Error(`button parity action has no DOM control: ${action}`);
|
||||
}
|
||||
if (!controls.some((control) => control.dataset.axisSourceRef && control.dataset.axisExpectedEffect)) {
|
||||
throw new Error(`button parity action has no source-tagged DOM control: ${action}`);
|
||||
}
|
||||
}
|
||||
for (const selector of [
|
||||
'[data-action="estop"]',
|
||||
'[data-action="power"]',
|
||||
@@ -156,6 +169,9 @@
|
||||
'[data-action="step"]',
|
||||
'[data-action="stop"]',
|
||||
'[data-action="jog-plus"]',
|
||||
'[data-action="spindle-reverse"]',
|
||||
'[data-action="spindle-stop"]',
|
||||
'[data-action="spindle-forward"]',
|
||||
'[data-action="toggle-flood"]',
|
||||
'[data-action="kins-tcp"]',
|
||||
'[data-action="clear-preview"]',
|
||||
@@ -273,17 +289,90 @@
|
||||
await click('[data-action="power"]', "AXIS power");
|
||||
await waitState((state) => state.machine.powerOn === true && state.machine.taskState === "on", "machine power on");
|
||||
await click('[data-action="home-all"]', "AXIS home all");
|
||||
await waitState((state) => state.machine.allHomed === true && state.machine.mode === "manual", "home all");
|
||||
await waitState((state) => (
|
||||
state.machine.allHomed === true
|
||||
&& state.machine.mode === "manual"
|
||||
&& Math.abs(Number(state.axisPose.x) - 0) < 1e-6
|
||||
&& Math.abs(Number(state.axisPose.y) - 0) < 1e-6
|
||||
&& Math.abs(Number(state.axisPose.z) - 10) < 1e-6
|
||||
&& Math.abs(Number(state.dro.x) - 0) < 1e-6
|
||||
&& Math.abs(Number(state.dro.y) - 0) < 1e-6
|
||||
&& Math.abs(Number(state.dro.z) - 10) < 1e-6
|
||||
), "home all");
|
||||
await click('[data-action="toggle-auto-manual"]', "AXIS AUTO mode toolbar toggle");
|
||||
await waitState((state) => state.machine.mode === "auto", "toolbar toggle to AUTO");
|
||||
await click('[data-action="toggle-auto-manual"]', "AXIS MANUAL mode toolbar toggle");
|
||||
await waitState((state) => state.machine.mode === "manual", "toolbar toggle to MANUAL");
|
||||
await click('[data-action="run"]', "AXIS immediate-pause run");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.dataset.action === "pause-resume", "toolbar pause button is LinuxCNC task_pauseresume");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS immediate pause/resume button after run click");
|
||||
await waitState((state) => (
|
||||
state.runState === "paused"
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
), "immediate pause after run click");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.dataset.paused === "true", "toolbar pause button visibly enters paused state");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.title === "Resume program", "toolbar pause button title switches to resume");
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
assert(api.getState().runState === "paused", "immediate pause remains paused after async task/HAL settle");
|
||||
await click('[data-action="stop"]', "AXIS stop after immediate pause");
|
||||
await waitState((state) => state.runState === "stopped" && state.machine.mode === "auto", "stop after immediate pause");
|
||||
await click('[data-action="tab-manual"]', "AXIS manual tab after immediate pause");
|
||||
await waitState((state) => state.machine.mode === "manual", "manual mode after immediate pause");
|
||||
await click('[data-action="run"]', "AXIS direct run after home");
|
||||
await waitState((state) => (
|
||||
(state.runState === "running" || state.runState === "complete")
|
||||
&& state.machine.mode === "auto"
|
||||
&& state.programRuntimeFeedback
|
||||
), "direct run after power and home");
|
||||
await click('[data-menu-command="pause"]', "AXIS menu Pause after direct run");
|
||||
await waitState((state) => (
|
||||
state.runState === "paused"
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
), "menu Pause after direct run");
|
||||
await click('[data-menu-command="resume"]', "AXIS menu Resume after direct Pause");
|
||||
await waitState((state) => state.runState === "running" && state.machine.interpState === "reading", "menu Resume after direct Pause");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS toolbar pause after direct run");
|
||||
await waitState((state) => (
|
||||
state.runState === "paused"
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
), "pause after direct run");
|
||||
const pauseToolbarAfterPause = doc.querySelector('[data-tool-id="tbtn_pause"]');
|
||||
assert(pauseToolbarAfterPause?.dataset.action === "pause-resume", "toolbar pause button stays bound to LinuxCNC task_pauseresume while paused");
|
||||
assert(pauseToolbarAfterPause?.dataset.paused === "true", "toolbar pause button has paused dataset while paused");
|
||||
assert(pauseToolbarAfterPause?.getAttribute("aria-pressed") === "true", "toolbar pause button aria pressed while paused");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS toolbar pause/resume resumes while already paused");
|
||||
await waitState((state) => state.runState === "running" && state.machine.interpState === "reading", "toolbar pause/resume resumes while paused");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.dataset.paused === "false", "toolbar pause button leaves paused state after resume");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.title === "Pause program", "toolbar pause button title switches to pause after resume");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS toolbar pause/resume pauses again");
|
||||
await waitState((state) => (
|
||||
state.runState === "paused"
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
), "toolbar pause/resume pauses again");
|
||||
const beforeStepSample = api.getState().programExecutionSampleIndex;
|
||||
await click('[data-action="step"]', "AXIS step after pause");
|
||||
await waitState((state) => (
|
||||
(state.runState === "stepping" || state.runState === "paused")
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
&& Number(state.programExecutionSampleIndex) > Number(beforeStepSample)
|
||||
), "step after pause");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.dataset.action === "pause-resume", "toolbar pause button stays task_pauseresume after step");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS toolbar pause/resume after pause");
|
||||
await waitState((state) => state.runState === "running" && state.machine.interpState === "reading", "resume after pause");
|
||||
assert(doc.querySelector('[data-tool-id="tbtn_pause"]')?.dataset.action === "pause-resume", "toolbar pause button stays task_pauseresume after resume");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS second toolbar pause after resume");
|
||||
await waitState((state) => (
|
||||
state.runState === "paused"
|
||||
&& state.machine.interpState === "paused"
|
||||
&& state.machine.taskPaused === true
|
||||
), "second pause after resume");
|
||||
await click('[data-tool-id="tbtn_pause"]', "AXIS second toolbar resume after pause");
|
||||
await waitState((state) => state.runState === "running" && state.machine.interpState === "reading", "second resume after pause");
|
||||
await click('[data-action="stop"]', "AXIS stop after direct run");
|
||||
await waitState((state) => state.runState === "stopped" && state.machine.mode === "auto", "stop after direct run");
|
||||
await click('[data-action="tab-manual"]', "AXIS manual tab after direct run");
|
||||
@@ -329,10 +418,38 @@
|
||||
const beforeFeed = api.getState().feed.feedOverride;
|
||||
await click('[data-action="feed-override-up"]', "feed override up");
|
||||
await waitState((state) => state.feed.feedOverride === Math.min(beforeFeed + 10, 200), "feed override");
|
||||
await click('[data-action="spindle-forward"]', "spindle forward");
|
||||
await waitState((state) => state.spindle.direction === "forward" && state.spindle.enabled === true, "spindle forward");
|
||||
await click('[data-action="spindle-reverse"]', "spindle reverse");
|
||||
await waitState((state) => (
|
||||
state.spindle.direction === "reverse"
|
||||
&& state.spindle.enabled === true
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.on === 1
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.forward === 0
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.reverse === 1
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.speedOut > 0
|
||||
), "spindle reverse");
|
||||
await waitFor(() => doc.querySelector("[data-active-gcodes]")?.dataset.activeGcodes.includes("M4") ? true : null, "active G-codes reverse spindle");
|
||||
await click('[data-action="spindle-stop"]', "spindle stop");
|
||||
await waitState((state) => state.spindle.direction === "stop" && state.spindle.enabled === false, "spindle stop");
|
||||
await waitState((state) => (
|
||||
state.spindle.direction === "stop"
|
||||
&& state.spindle.enabled === false
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.on === 0
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.forward === 0
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.reverse === 0
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.speedOut === 0
|
||||
), "spindle stop");
|
||||
await waitFor(() => doc.querySelector("[data-active-gcodes]")?.dataset.activeGcodes.includes("M5") ? true : null, "active G-codes stopped spindle");
|
||||
await click('[data-action="spindle-forward"]', "spindle forward");
|
||||
await waitState((state) => (
|
||||
state.spindle.direction === "forward"
|
||||
&& state.spindle.enabled === true
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.on === 1
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.forward === 1
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.reverse === 0
|
||||
&& state.linuxCncProcessMonitor.spindle.halPins.speedOut > 0
|
||||
), "spindle forward");
|
||||
await waitFor(() => doc.querySelector("[data-active-gcodes]")?.dataset.activeGcodes.includes("M3") ? true : null, "active G-codes forward spindle");
|
||||
await click('[data-action="spindle-stop"]', "spindle stop after forward");
|
||||
await waitState((state) => state.spindle.direction === "stop" && state.spindle.enabled === false, "spindle stop after forward");
|
||||
await click('[data-action="toggle-flood"]', "flood coolant");
|
||||
await waitState((state) => state.coolant.flood === true, "flood coolant");
|
||||
await click('[data-action="block-delete"]', "block delete");
|
||||
|
||||
Reference in New Issue
Block a user