推进 INI 面板 run readiness workflow helper
This commit is contained in:
81
text12.txt
81
text12.txt
@@ -371,6 +371,87 @@ host_wasm_opfs_browser_smokes=ok
|
||||
`loadMachineSessionIntoWasmWorkflow()`,避免 restore+load 与单独 load 的 field/log 状态模型
|
||||
分叉;仍保持由 LinuxCNC/OPFS bridge 执行实际语义,不在 JS 中解释 CNC 行为。
|
||||
|
||||
三、2026-06-15 继续执行记录:INI panel run readiness workflow helper
|
||||
|
||||
本轮按“第一原则:加快实质性推进”继续推进 run 前置状态模型,将 run 按钮可执行条件、
|
||||
默认/快照 G-code 选择结果与已加载 session 的 WASM 绑定关系抽成可复用 readiness helper,
|
||||
让 app、state summary、control view 和 Node smoke 共享同一份运行前状态。
|
||||
|
||||
完成内容:
|
||||
|
||||
- 新增 `wasm-port/runtime/ui/ini-panel/run-workflow.js` 的
|
||||
`createRunSessionReadinessState(input)`;
|
||||
- `runGcodeSessionWorkflow()` 现在先生成 readiness state,再复用其中的选定程序和 loaded
|
||||
session 信息执行实际 run;
|
||||
- readiness state 固定返回:
|
||||
- `phase`
|
||||
- `canRun`
|
||||
- `missing`
|
||||
- `loadedSession`
|
||||
- `snapshot`
|
||||
- `defaultProgram`
|
||||
- `program`
|
||||
- `runButton`
|
||||
- `wasm-port/runtime/ui/ini-panel/app.js` 在点击 Run 前先写入 readiness state,并把
|
||||
`selectedProgram`、`runReadiness` 和 field state 一起更新到 panel state;
|
||||
- `wasm-port/runtime/ui/ini-panel/panel-state-summary.js` 新增 `runReadiness` 的 report /
|
||||
workflowStatus / control-view 映射;
|
||||
- `createMachineSessionControlView()` 的 Run 区新增 `Ready` 与 `Button` 行,用于 read-only
|
||||
control page 读取首帧 run 前置状态;
|
||||
- `wasm-port/tests/ui/node/verify_ini_panel_run_workflow.mjs` 覆盖 readiness helper 与
|
||||
workflow readiness 返回值;
|
||||
- `wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs` 覆盖 runReadiness 在 report、
|
||||
bundle、workflowStatus 和 control view 中的映射;
|
||||
- `wasm-port/docs/ui-run-summary-helpers.md` 和 `wasm-port/docs/ui-panel-state-summary.md`
|
||||
同步说明 readiness helper 与 runReadiness 状态;
|
||||
- 未新增控制按钮;
|
||||
- 未解析 G-code;
|
||||
- 未解释 canonical events;
|
||||
- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或
|
||||
LinuxCNC-owned runtime semantics。
|
||||
|
||||
验证已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/ui/node/verify_ini_panel_run_workflow.sh
|
||||
wasm-port/tests/ui/node/verify_ini_panel_state_summary.sh
|
||||
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
|
||||
wasm-port/tools/verify_vendor_sync.sh
|
||||
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||
wasm-port/tests/host/verify_host_smokes.sh
|
||||
```
|
||||
|
||||
关键输出:
|
||||
|
||||
```text
|
||||
ini_panel_run_workflow_node_smoke=ok
|
||||
ini_panel_state_summary_node_smoke=ok
|
||||
ui_node_smokes=ok
|
||||
browser_ini_opfs_smoke=ok
|
||||
browser_ini_control_page_smoke=ok
|
||||
browser_ini_launch_smoke=ok
|
||||
vendor sync up to date
|
||||
standalone CNC semantics guard complete
|
||||
interp_wasm_node_smoke=ok
|
||||
sim_configs_wasm_node_inventory_executed=28
|
||||
sim_configs_wasm_node_inventory_passed=28
|
||||
sim_configs_wasm_node_inventory_skipped=131
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
browser_interp_smoke=ok
|
||||
host_wasm_opfs_browser_smokes=ok
|
||||
```
|
||||
|
||||
下一步建议:
|
||||
|
||||
继续推进 OPFS/session persistence 的实质链路。下一批建议将 `load-session` 与
|
||||
`restore-load-session` 的 field/log 路径再做一次轻量整合,优先把“已加载 session、快照恢复、
|
||||
run readiness、run 结果”汇总成一个更上层的只读工作流状态对象;仍保持只描述 UI/host
|
||||
boundary facts,不在 JS 中解释 G-code、canonical events 或 CNC 运行语义。
|
||||
|
||||
三、2026-06-15 继续执行记录:INI panel restore-load workflow 复用 load-session helper
|
||||
|
||||
本轮按“第一原则:加快实质性推进”继续推进 OPFS/session persistence 主链路,将
|
||||
|
||||
@@ -49,6 +49,7 @@ For the short page/entry map, see `docs/panel-entry.md`.
|
||||
machineFiles: { iniOpfsPath: "...", toolTableOpfsPath: "...", parameterOpfsPath: "...", gcodeOpfsPath: "..." },
|
||||
sessionSnapshot: { snapshotLabel: "...", workflow: "save-session-snapshot" },
|
||||
sessionLoad: { iniOpfsPath: "...", iniWasmPath: "..." },
|
||||
runReadiness: { phase: "ready", canRun: true, runButton: { enabled: true } },
|
||||
run: { runStatus: "ok", programSource: "snapshot" },
|
||||
fiveaxisRemap: "ok"
|
||||
}
|
||||
@@ -100,6 +101,7 @@ with four sections:
|
||||
session: { snapshotLabel: "...", workflow: "...", ini: "...", parameters: "...", toolTable: "...", gcode: "..." },
|
||||
loaded: { iniWasmPath: "...", parameterWasmPath: "...", toolTableWasmPath: "..." },
|
||||
program: { source: "snapshot", opfsPath: "...", wasmPath: "..." },
|
||||
runReadiness: { phase: "ready", canRun: true, buttonEnabled: true, programOpfsPath: "..." },
|
||||
run: { status: "ok", canonicalEventCount: 2, motionSnapshotCount: 2, iniWasmPath: "..." },
|
||||
status: { lastAction: "run-gcode", error: null, fiveaxisRemap: "ok" }
|
||||
}
|
||||
@@ -130,6 +132,7 @@ This helper derives a lightweight status object for upper-level control pages:
|
||||
```js
|
||||
{
|
||||
readiness: { ini: "...", interp: "...", opfs: "..." },
|
||||
runReadiness: { phase: "ready", canRun: true, buttonEnabled: true },
|
||||
lastAction: "run-gcode",
|
||||
error: null,
|
||||
session: { snapshotLabel: "...", workflow: "...", gcode: "..." },
|
||||
@@ -167,7 +170,7 @@ This helper maps a bundle into UI-ready status and sections:
|
||||
sections: [
|
||||
{ id: "readiness", title: "Readiness", rows: [{ label: "INI", value: "..." }] },
|
||||
{ id: "session", title: "Session", rows: [{ label: "Workflow", value: "..." }] },
|
||||
{ id: "run", title: "Run", rows: [{ label: "Canonical events", value: 2 }] }
|
||||
{ id: "run", title: "Run", rows: [{ label: "Ready", value: "ready" }] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -7,7 +7,7 @@ summarizing an INI panel G-code run.
|
||||
`runtime/ui/ini-panel/run-workflow.js` contains the reusable UI workflow for
|
||||
selecting the session/default G-code program, loading it from OPFS, staging it
|
||||
into the interpreter WASM filesystem, invoking the LinuxCNC interpreter, and
|
||||
returning run field/log state. These helpers are intentionally pure so browser
|
||||
returning run readiness, field, and log state. These helpers are intentionally pure so browser
|
||||
UI panels, SDK-facing wrappers, and Node smoke tests can share the same summary
|
||||
shape without reading DOM text or parsing log output.
|
||||
|
||||
@@ -95,8 +95,8 @@ functions:
|
||||
```
|
||||
|
||||
It returns the selected program mapping, raw interpreter result text, run
|
||||
summary, UI field state, log lines, and optional UI motion snapshots produced
|
||||
by the injected `summarizeRun` callback:
|
||||
summary, readiness state, UI field state, log lines, and optional UI motion
|
||||
snapshots produced by the injected `summarizeRun` callback:
|
||||
|
||||
```js
|
||||
{
|
||||
@@ -108,6 +108,7 @@ by the injected `summarizeRun` callback:
|
||||
},
|
||||
resultText: "canon_event=...",
|
||||
summary: { runStatus: "ok", programSource: "snapshot" },
|
||||
readiness: { phase: "ready", canRun: true },
|
||||
fields: { runStatus: "ok", sessionGcode: "linuxcnc/gcode/ui-session.ngc" },
|
||||
motionSnapshots: [{ line: 1 }],
|
||||
logLines: ["Program: linuxcnc/gcode/ui-session.ngc -> /work/ui-session.ngc"]
|
||||
@@ -117,6 +118,10 @@ by the injected `summarizeRun` callback:
|
||||
`selectSessionGcodeProgram(input)` is the pure program-selection helper used by
|
||||
the workflow. Invalid snapshot G-code paths fall back to the UI default program.
|
||||
|
||||
`createRunSessionReadinessState(input)` is the pure readiness helper used by the
|
||||
workflow and panel state summary. It reports the selected program, loaded
|
||||
session path, snapshot metadata, and whether the run button can execute.
|
||||
|
||||
## Boundary Rules
|
||||
|
||||
- Do not parse G-code text in these helpers.
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
summarizeRunResult,
|
||||
} from "./run-summary.js";
|
||||
import {
|
||||
createRunSessionReadinessState,
|
||||
runGcodeSessionWorkflow,
|
||||
} from "./run-workflow.js";
|
||||
import {
|
||||
@@ -772,8 +773,28 @@ document.getElementById("restore-load-session").addEventListener("click", async
|
||||
|
||||
document.getElementById("run-gcode").addEventListener("click", async () => {
|
||||
try {
|
||||
if (!loadedSession) {
|
||||
throw new Error("Load a machine session before running G-code.");
|
||||
const readiness = createRunSessionReadinessState({
|
||||
loadedSession,
|
||||
snapshot: restoredSessionSnapshot,
|
||||
defaultFilename: UI_SESSION.defaultGcodeFilename,
|
||||
defaultOpfsPath: defaultGcodeOpfsPath(),
|
||||
wasmPath: UI_SESSION.gcodeWasmPath,
|
||||
gcodeFilenameFromProgramPath,
|
||||
});
|
||||
updatePanelMachineSessionState({
|
||||
runReadiness: readiness,
|
||||
selectedProgram: readiness.program,
|
||||
fields: {
|
||||
sessionGcode: readiness.program.opfsPath,
|
||||
runSource: readiness.program.source,
|
||||
runOpfsPath: readiness.program.opfsPath,
|
||||
runWasmPath: readiness.program.wasmPath,
|
||||
},
|
||||
lastAction: "run-gcode-readiness",
|
||||
error: readiness.runButton.reason,
|
||||
});
|
||||
if (!readiness.canRun) {
|
||||
throw new Error(readiness.runButton.reason ?? "Load a machine session before running G-code.");
|
||||
}
|
||||
const interp = requireInterpSdk();
|
||||
clearRunPlayback();
|
||||
@@ -803,6 +824,7 @@ document.getElementById("run-gcode").addEventListener("click", async () => {
|
||||
setField("runStatus", workflow.fields.runStatus);
|
||||
setLastRunSummary(workflow.summary);
|
||||
updatePanelMachineSessionState({
|
||||
runReadiness: workflow.readiness,
|
||||
selectedProgram: {
|
||||
source: workflow.program.source,
|
||||
opfsPath: workflow.program.opfsPath,
|
||||
|
||||
@@ -4,6 +4,7 @@ export function createIniPanelStateSummary({
|
||||
machineFiles = null,
|
||||
sessionSnapshot = null,
|
||||
sessionLoad = null,
|
||||
runReadiness = null,
|
||||
run = null,
|
||||
fiveaxisRemap = null,
|
||||
} = {}) {
|
||||
@@ -17,6 +18,7 @@ export function createIniPanelStateSummary({
|
||||
machineFiles,
|
||||
sessionSnapshot,
|
||||
sessionLoad,
|
||||
runReadiness,
|
||||
run,
|
||||
fiveaxisRemap: fiveaxisRemap ?? null,
|
||||
};
|
||||
@@ -28,6 +30,7 @@ export function createMachineSessionStateSnapshot({
|
||||
machineFiles = null,
|
||||
sessionSnapshot = null,
|
||||
sessionLoad = null,
|
||||
runReadiness = null,
|
||||
selectedProgram = null,
|
||||
run = null,
|
||||
fields = {},
|
||||
@@ -42,6 +45,7 @@ export function createMachineSessionStateSnapshot({
|
||||
machineFiles,
|
||||
sessionSnapshot,
|
||||
sessionLoad,
|
||||
runReadiness,
|
||||
run,
|
||||
fiveaxisRemap,
|
||||
}),
|
||||
@@ -69,6 +73,7 @@ export function createMachineSessionStateReport(state = {}) {
|
||||
const fields = state.fields ?? {};
|
||||
const sessionSnapshot = state.sessionSnapshot ?? {};
|
||||
const sessionLoad = state.sessionLoad ?? {};
|
||||
const runReadiness = state.runReadiness ?? {};
|
||||
const selectedProgram = state.selectedProgram ?? {};
|
||||
const run = state.run ?? {};
|
||||
return {
|
||||
@@ -95,6 +100,17 @@ export function createMachineSessionStateReport(state = {}) {
|
||||
opfsPath: selectedProgram.opfsPath ?? run.programOpfsPath ?? fields.runOpfsPath ?? null,
|
||||
wasmPath: selectedProgram.wasmPath ?? run.programWasmPath ?? fields.runWasmPath ?? null,
|
||||
},
|
||||
runReadiness: {
|
||||
phase: runReadiness.phase ?? null,
|
||||
canRun: Boolean(runReadiness.canRun),
|
||||
missing: Array.isArray(runReadiness.missing) ? runReadiness.missing : [],
|
||||
buttonEnabled: Boolean(runReadiness.runButton?.enabled),
|
||||
buttonReason: runReadiness.runButton?.reason ?? null,
|
||||
programSource: runReadiness.program?.source ?? null,
|
||||
programOpfsPath: runReadiness.program?.opfsPath ?? null,
|
||||
programWasmPath: runReadiness.program?.wasmPath ?? null,
|
||||
iniWasmPath: runReadiness.loadedSession?.iniWasmPath ?? null,
|
||||
},
|
||||
run: {
|
||||
status: run.runStatus ?? fields.runStatus ?? null,
|
||||
canonicalEventCount: run.canonicalEventCount ?? 0,
|
||||
@@ -123,6 +139,7 @@ export function createMachineSessionWorkflowStatus(state = {}) {
|
||||
const report = createMachineSessionStateReport(state);
|
||||
return {
|
||||
readiness: report.readiness,
|
||||
runReadiness: report.runReadiness,
|
||||
lastAction: report.status.lastAction,
|
||||
error: report.status.error,
|
||||
session: report.session,
|
||||
@@ -145,6 +162,7 @@ export function createMachineSessionControlView(bundle = {}) {
|
||||
const report = bundle.report ?? {};
|
||||
const workflowStatus = bundle.workflowStatus ?? {};
|
||||
const session = workflowStatus.session ?? report.session ?? {};
|
||||
const runReadiness = workflowStatus.runReadiness ?? report.runReadiness ?? {};
|
||||
const run = workflowStatus.run ?? report.run ?? {};
|
||||
return {
|
||||
status: {
|
||||
@@ -176,6 +194,8 @@ export function createMachineSessionControlView(bundle = {}) {
|
||||
id: "run",
|
||||
title: "Run",
|
||||
rows: [
|
||||
{ label: "Ready", value: runReadiness.phase ?? null },
|
||||
{ label: "Button", value: runReadiness.buttonEnabled ? "enabled" : "disabled" },
|
||||
{ label: "Status", value: run.status ?? null },
|
||||
{ label: "Canonical events", value: run.canonicalEventCount ?? 0 },
|
||||
{ label: "Motion snapshots", value: run.motionSnapshotCount ?? 0 },
|
||||
|
||||
@@ -34,6 +34,55 @@ export function selectSessionGcodeProgram({
|
||||
};
|
||||
}
|
||||
|
||||
export function createRunSessionReadinessState({
|
||||
loadedSession = null,
|
||||
snapshot = null,
|
||||
defaultFilename,
|
||||
defaultOpfsPath,
|
||||
wasmPath,
|
||||
gcodeFilenameFromProgramPath,
|
||||
}) {
|
||||
const program = selectSessionGcodeProgram({
|
||||
snapshot,
|
||||
defaultFilename,
|
||||
defaultOpfsPath,
|
||||
wasmPath,
|
||||
gcodeFilenameFromProgramPath,
|
||||
});
|
||||
const missing = [];
|
||||
if (!loadedSession?.ini?.wasmPath) {
|
||||
missing.push("loaded-session");
|
||||
}
|
||||
if (!program.filename || !program.opfsPath || !program.wasmPath) {
|
||||
missing.push("gcode-program");
|
||||
}
|
||||
const canRun = missing.length === 0;
|
||||
return {
|
||||
phase: canRun ? "ready" : "blocked",
|
||||
canRun,
|
||||
missing,
|
||||
loadedSession: {
|
||||
iniWasmPath: loadedSession?.ini?.wasmPath ?? null,
|
||||
},
|
||||
snapshot: {
|
||||
present: Boolean(snapshot),
|
||||
label: snapshot?.metadata?.snapshotLabel ?? snapshot?.sessionId ?? null,
|
||||
workflow: snapshot?.metadata?.workflow ?? null,
|
||||
gcodeOpfsPath: snapshot?.payload?.files?.gcode ?? null,
|
||||
},
|
||||
defaultProgram: {
|
||||
filename: defaultFilename ?? null,
|
||||
opfsPath: defaultOpfsPath ?? null,
|
||||
wasmPath: wasmPath ?? null,
|
||||
},
|
||||
program,
|
||||
runButton: {
|
||||
enabled: canRun,
|
||||
reason: canRun ? null : `Missing ${missing.join(", ")}.`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function runSessionContextLogLines(program, snapshot = null, snapshotLabel = null) {
|
||||
const summary = createSessionSnapshotSummary({
|
||||
metadata: snapshot?.metadata ?? {},
|
||||
@@ -58,16 +107,18 @@ export async function runGcodeSessionWorkflow({
|
||||
summarizeRun = () => ({}),
|
||||
snapshotLabel = null,
|
||||
}) {
|
||||
if (!loadedSession) {
|
||||
throw new Error("Load a machine session before running G-code.");
|
||||
}
|
||||
const program = selectSessionGcodeProgram({
|
||||
const readiness = createRunSessionReadinessState({
|
||||
loadedSession,
|
||||
snapshot,
|
||||
defaultFilename,
|
||||
defaultOpfsPath,
|
||||
wasmPath,
|
||||
gcodeFilenameFromProgramPath,
|
||||
});
|
||||
if (!readiness.canRun) {
|
||||
throw new Error("Load a machine session before running G-code.");
|
||||
}
|
||||
const program = readiness.program;
|
||||
const programText = await loadGcodeProgram(program.filename);
|
||||
interp.writeTextFile(program.wasmPath, programText);
|
||||
const resultText = interp.runFileWithIni(program.wasmPath, loadedSession.ini.wasmPath).trim();
|
||||
@@ -91,6 +142,7 @@ export async function runGcodeSessionWorkflow({
|
||||
resultText,
|
||||
motionSnapshots,
|
||||
summary,
|
||||
readiness,
|
||||
fields: {
|
||||
sessionGcode: program.opfsPath,
|
||||
runStatus: summary.runStatus,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import {
|
||||
createRunSessionReadinessState,
|
||||
runGcodeSessionWorkflow,
|
||||
selectSessionGcodeProgram,
|
||||
} from "../../../runtime/ui/ini-panel/run-workflow.js";
|
||||
@@ -42,6 +43,61 @@ assert.deepEqual(snapshotProgram, {
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
});
|
||||
|
||||
const readiness = createRunSessionReadinessState({
|
||||
loadedSession: {
|
||||
ini: {
|
||||
wasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
},
|
||||
snapshot: {
|
||||
sessionId: "ui-machine-session",
|
||||
metadata: {
|
||||
workflow: "save-session-snapshot",
|
||||
snapshotLabel: "ui-machine-session/ui-machine-session.json",
|
||||
defaultGcodeOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
},
|
||||
payload: {
|
||||
files: {
|
||||
gcode: "linuxcnc/gcode/snapshot-session.ngc",
|
||||
},
|
||||
},
|
||||
},
|
||||
defaultFilename: "ui-session.ngc",
|
||||
defaultOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
gcodeFilenameFromProgramPath: (path) => path.split("/").at(-1),
|
||||
});
|
||||
|
||||
assert.deepEqual(readiness, {
|
||||
phase: "ready",
|
||||
canRun: true,
|
||||
missing: [],
|
||||
loadedSession: {
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
snapshot: {
|
||||
present: true,
|
||||
label: "ui-machine-session/ui-machine-session.json",
|
||||
workflow: "save-session-snapshot",
|
||||
gcodeOpfsPath: "linuxcnc/gcode/snapshot-session.ngc",
|
||||
},
|
||||
defaultProgram: {
|
||||
filename: "ui-session.ngc",
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
},
|
||||
program: {
|
||||
filename: "snapshot-session.ngc",
|
||||
opfsPath: "linuxcnc/gcode/snapshot-session.ngc",
|
||||
source: "snapshot",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
},
|
||||
runButton: {
|
||||
enabled: true,
|
||||
reason: null,
|
||||
},
|
||||
});
|
||||
|
||||
const calls = [];
|
||||
const workflow = await runGcodeSessionWorkflow({
|
||||
interp: {
|
||||
@@ -126,6 +182,7 @@ assert.deepEqual(workflow.fields, {
|
||||
runOpfsPath: "linuxcnc/gcode/snapshot-session.ngc",
|
||||
runWasmPath: "/work/ui-session.ngc",
|
||||
});
|
||||
assert.deepEqual(workflow.readiness, readiness);
|
||||
|
||||
assert.deepEqual(workflow.motionSnapshots, [{ line: 1 }]);
|
||||
|
||||
|
||||
@@ -13,6 +13,60 @@ import {
|
||||
renderMachineSessionControlView,
|
||||
} from "../../../runtime/ui/ini-panel/control-view-renderer.js";
|
||||
|
||||
const runReadinessFixture = {
|
||||
phase: "ready",
|
||||
canRun: true,
|
||||
missing: [],
|
||||
loadedSession: {
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
snapshot: {
|
||||
present: true,
|
||||
label: "ui-machine-session/ui-machine-session.json",
|
||||
workflow: "save-session-snapshot",
|
||||
gcodeOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
},
|
||||
defaultProgram: {
|
||||
filename: "ui-session.ngc",
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
},
|
||||
program: {
|
||||
filename: "ui-session.ngc",
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
source: "default",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
},
|
||||
runButton: {
|
||||
enabled: true,
|
||||
reason: null,
|
||||
},
|
||||
};
|
||||
|
||||
const expectedRunReadinessReport = {
|
||||
phase: "ready",
|
||||
canRun: true,
|
||||
missing: [],
|
||||
buttonEnabled: true,
|
||||
buttonReason: null,
|
||||
programSource: "default",
|
||||
programOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
programWasmPath: "/work/ui-session.ngc",
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
};
|
||||
|
||||
const expectedEmptyRunReadinessReport = {
|
||||
phase: null,
|
||||
canRun: false,
|
||||
missing: [],
|
||||
buttonEnabled: false,
|
||||
buttonReason: null,
|
||||
programSource: null,
|
||||
programOpfsPath: null,
|
||||
programWasmPath: null,
|
||||
iniWasmPath: null,
|
||||
};
|
||||
|
||||
const summary = createIniPanelStateSummary({
|
||||
badges: {
|
||||
ini: "INI WASM: ready",
|
||||
@@ -37,6 +91,7 @@ const summary = createIniPanelStateSummary({
|
||||
iniOpfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
run: {
|
||||
runStatus: "ok",
|
||||
programSource: "snapshot",
|
||||
@@ -68,6 +123,7 @@ assert.deepEqual(summary, {
|
||||
iniOpfsPath: "linuxcnc/machines/xyzab-tdr/machine.ini",
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
run: {
|
||||
runStatus: "ok",
|
||||
programSource: "snapshot",
|
||||
@@ -87,6 +143,7 @@ assert.deepEqual(
|
||||
machineFiles: null,
|
||||
sessionSnapshot: null,
|
||||
sessionLoad: null,
|
||||
runReadiness: null,
|
||||
run: null,
|
||||
fiveaxisRemap: null,
|
||||
},
|
||||
@@ -108,6 +165,7 @@ assert.deepEqual(
|
||||
sessionLoad: {
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
selectedProgram: {
|
||||
source: "snapshot",
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
@@ -149,6 +207,7 @@ assert.deepEqual(
|
||||
sessionLoad: {
|
||||
iniWasmPath: "/work/session-machine.ini",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
run: {
|
||||
runStatus: "ok",
|
||||
programSource: "snapshot",
|
||||
@@ -219,6 +278,7 @@ assert.deepEqual(
|
||||
parameterWasmPath: "/work/session-linuxcnc.var",
|
||||
toolTableWasmPath: "/work/session-tool.tbl",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
selectedProgram: {
|
||||
source: "snapshot",
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
@@ -261,6 +321,7 @@ assert.deepEqual(
|
||||
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||
wasmPath: "/work/ui-session.ngc",
|
||||
},
|
||||
runReadiness: expectedRunReadinessReport,
|
||||
run: {
|
||||
status: "ok",
|
||||
canonicalEventCount: 2,
|
||||
@@ -299,6 +360,7 @@ const expectedExportReport = {
|
||||
opfsPath: null,
|
||||
wasmPath: null,
|
||||
},
|
||||
runReadiness: expectedEmptyRunReadinessReport,
|
||||
run: {
|
||||
status: null,
|
||||
canonicalEventCount: 0,
|
||||
@@ -350,6 +412,7 @@ assert.deepEqual(
|
||||
runStatus: "ok",
|
||||
runWorkflow: "save-session-snapshot",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
run: {
|
||||
runStatus: "ok",
|
||||
canonicalEventCount: 2,
|
||||
@@ -364,6 +427,7 @@ assert.deepEqual(
|
||||
interp: "Interpreter WASM: ready",
|
||||
opfs: "OPFS: ready",
|
||||
},
|
||||
runReadiness: expectedRunReadinessReport,
|
||||
lastAction: "run-gcode",
|
||||
error: null,
|
||||
session: {
|
||||
@@ -407,6 +471,7 @@ const expectedBundleReport = {
|
||||
opfsPath: null,
|
||||
wasmPath: null,
|
||||
},
|
||||
runReadiness: expectedRunReadinessReport,
|
||||
run: {
|
||||
status: "ok",
|
||||
canonicalEventCount: 2,
|
||||
@@ -434,6 +499,7 @@ assert.deepEqual(
|
||||
runStatus: "ok",
|
||||
runWorkflow: "save-session-snapshot",
|
||||
},
|
||||
runReadiness: runReadinessFixture,
|
||||
run: {
|
||||
runStatus: "ok",
|
||||
canonicalEventCount: 2,
|
||||
@@ -458,6 +524,7 @@ assert.deepEqual(
|
||||
},
|
||||
lastAction: "run-gcode",
|
||||
error: null,
|
||||
runReadiness: expectedRunReadinessReport,
|
||||
session: {
|
||||
snapshotLabel: "ui-machine-session/ui-machine-session.json",
|
||||
workflow: "save-session-snapshot",
|
||||
@@ -501,6 +568,7 @@ assert.deepEqual(
|
||||
toolTable: null,
|
||||
gcode: "linuxcnc/gcode/ui-session.ngc",
|
||||
},
|
||||
runReadiness: expectedRunReadinessReport,
|
||||
run: {
|
||||
status: "ok",
|
||||
canonicalEventCount: 2,
|
||||
@@ -539,6 +607,8 @@ assert.deepEqual(
|
||||
id: "run",
|
||||
title: "Run",
|
||||
rows: [
|
||||
{ label: "Ready", value: "ready" },
|
||||
{ label: "Button", value: "enabled" },
|
||||
{ label: "Status", value: "ok" },
|
||||
{ label: "Canonical events", value: 2 },
|
||||
{ label: "Motion snapshots", value: 2 },
|
||||
@@ -578,6 +648,7 @@ const renderedControlView = renderMachineSessionControlView(
|
||||
lastAction: "run-gcode",
|
||||
error: null,
|
||||
session: expectedBundleReport.session,
|
||||
runReadiness: expectedBundleReport.runReadiness,
|
||||
run: expectedBundleReport.run,
|
||||
},
|
||||
}),
|
||||
@@ -588,7 +659,7 @@ assert.equal(renderedControlView.sectionNodes.length, 3);
|
||||
assert.equal(renderedControlView.sectionNodes[2].dataset.sectionId, "run");
|
||||
assert.equal(
|
||||
renderedControlView.sectionNodes[2].children[1].children[3].textContent,
|
||||
"2",
|
||||
"enabled",
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
|
||||
Reference in New Issue
Block a user