import assert from "node:assert/strict"; import { createFiveAxisSessionPayload, createMemorySessionStorage } from "../../app/src/runtime/five-axis-session.js"; import { createLinuxCncInterpreterRuntime } from "../../app/src/runtime/linuxcnc-interpreter-runtime.js"; import { createSimulationStore } from "../../app/src/state/store.js"; async function waitForInterpreterExecution(store) { for (let attempt = 0; attempt < 20; attempt += 1) { const state = store.getState(); if (!state.interpreterExecutionPending && state.programExecutionSourceMode === "linuxcnc-interpreter-wasm") { return state; } await new Promise((resolve) => setTimeout(resolve, 0)); } return store.getState(); } const store = createSimulationStore(); const interpreterRuntime = await createLinuxCncInterpreterRuntime(); store.dispatch({ type: "ATTACH_INTERPRETER_RUNTIME", runtime: interpreterRuntime }); store.dispatch({ type: "TOGGLE_POWER" }); store.dispatch({ type: "HOME" }); store.dispatch({ type: "SET_MODE", mode: "auto" }); store.dispatch({ type: "SET_RTCP", enabled: true }); store.dispatch({ type: "LOAD_PROGRAM", filename: "session-demo.ngc", content: [ "G90 G17", "G0 X0 Y0 Z0", "G1 X4 Y5 A6 C7 F100", "M2", ].join("\n"), }); await waitForInterpreterExecution(store); store.dispatch({ type: "STEP" }); const beforeSave = store.getState(); const payload = createFiveAxisSessionPayload(beforeSave); assert.equal(payload.apiName, "web-rtcp-5axis-session-payload"); assert.equal(payload.machineProfile, "xyzac-trt"); assert.equal(payload.programExecution.sourceMode, "linuxcnc-interpreter-wasm"); assert.equal(payload.rtcpState, "on"); assert.equal(payload.programRuntimeFeedback.sourceMode, "linuxcnc-tp-runtime-sample"); assert.equal(payload.programRuntimeFeedback.semanticBoundary, "linuxcnc_tp_run_cycle_feedback_without_hardware"); const storage = createMemorySessionStorage(); const saved = await store.saveSession({ storage }); assert.equal(saved.snapshot.format, "web-rtcp-5axis-session-snapshot"); assert.equal(saved.path, "web-rtcp-5axis-sim-plan/sessions/gmoccapy-web-session/web-rtcp-5axis-session.json"); assert.equal(saved.storageMode, "memory"); assert.equal(store.getState().sessionPersistence.storageMode, "memory"); store.dispatch({ type: "SET_RTCP", enabled: false }); store.dispatch({ type: "STOP" }); store.dispatch({ type: "SET_MODE", mode: "manual" }); store.dispatch({ type: "JOG", axis: "x", direction: 1, increment: 25 }); assert.notEqual(store.getState().rtcpState, beforeSave.rtcpState); assert.notEqual(store.getState().axisPose.x, beforeSave.axisPose.x); const restored = await store.restoreSession({ storage }); const afterRestore = store.getState(); assert.equal(restored.path, saved.path); assert.equal(restored.storageMode, "memory"); assert.equal(afterRestore.sessionPersistence.status, "restored"); assert.equal(afterRestore.sessionPersistence.storageMode, "memory"); assert.equal(afterRestore.rtcpState, beforeSave.rtcpState); assert.equal(afterRestore.kinsType, beforeSave.kinsType); assert.equal(afterRestore.axisPose.x, beforeSave.axisPose.x); assert.equal(afterRestore.activeProgram, "session-demo.ngc"); assert.equal(afterRestore.programExecution.sourceMode, "linuxcnc-interpreter-wasm"); assert.equal(afterRestore.programExecution.summary.motionEventCount, beforeSave.programExecution.summary.motionEventCount); assert.equal(afterRestore.programRuntimeFeedback.semanticBoundary, beforeSave.programRuntimeFeedback.semanticBoundary); assert.equal(afterRestore.programRuntimeFeedback.axisPose.x, beforeSave.programRuntimeFeedback.axisPose.x); console.log("five_axis_session_smoke=ok");