diff --git a/text12.txt b/text12.txt index d80b65a..9d427e8 100644 --- a/text12.txt +++ b/text12.txt @@ -2643,3 +2643,80 @@ host_wasm_opfs_browser_smokes=ok 继续推进 SDK/API surface。下一批建议把外部 shell mount DOM renderer 抽成可复用 helper `renderIniPanelShellSessionHandoffMountState()` 或等价 API,并用 Node/browser smoke 保护其 DOM contract;仍保持只读,不新增控制按钮,不解析 G-code。 + +三十三、2026-06-15 继续执行记录:INI panel shell handoff mount DOM renderer helper + +本轮按“第一原则:加快实质性推进”继续推进 SDK/API surface 与 browser/UI workflow,把外部 +shell mount DOM renderer 从 browser smoke 内抽为可复用 helper,让 launch 页面和 shell integration +workflow 共享同一只读 DOM contract。 + +完成内容: + +- `ui-shell.js` 新增 `renderIniPanelShellSessionHandoffMountState()`; +- `createIniPanelShellViewModel()` 暴露 `renderShellSessionHandoffMountState` helper; +- `createIniPanelLaunchApiManifest().methods` 新增 `renderShellSessionHandoffMountState`; +- `launch.html` 改为使用 `renderIniPanelShellSessionHandoffMountState()` 渲染默认 mount DOM; +- `launch.html` 的 `window.linuxCncIniPanelLaunchApi.renderShellSessionHandoffMountState()` + 新增真实 browser 入口,并支持外部 shell 传入自有 DOM nodes 与 row dataset prefix; +- `ini_panel_shell_integration_workflow_smoke.html` 删除本地专用 renderer,改用 launch API 暴露的 + shared renderer 渲染 waiting/ready mount-state; +- `ini_panel_shell_integration_workflow_smoke.html` 校验 shared renderer 返回值: + - `rendered === true`; + - row count 为 5; + - ready render result dataset `handoffReady === "true"`; +- `verify_ini_panel_ui_shell.mjs` 用最小 DOM stub 覆盖 shared renderer 的 dataset、statusLine、row + ids 与 row dataset 写入; +- `verify_ini_panel_shell_integration_manifest.mjs` 将 launch method count 更新为 27; +- `verify_ini_panel_launch_api_manifest.mjs` 覆盖 launch manifest 与 launch page API 暴露; +- `verify_ini_panel_entry_docs.mjs` 与 `docs/panel-entry.md` 同步记录和校验新 helper; +- 未新增控制按钮; +- 未解析 G-code; +- 未解释 canonical events; +- 未新增 JS CNC 语义; +- 未改变 OPFS/session persistence、LinuxCNC interpreter、tool、parameter、planner 或 + LinuxCNC-owned runtime semantics。 + +验证已通过: + +```bash +git diff --check +wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh +wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_entry_docs.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_ui_shell_node_smoke=ok +ini_panel_shell_integration_manifest_node_smoke=ok +ini_panel_launch_api_manifest_node_smoke=ok +ini_panel_entry_docs_node_smoke=ok +ui_node_smokes=ok +browser_ini_opfs_smoke=ok +browser_ini_control_page_smoke=ok +browser_ini_launch_smoke=ok +browser_ini_shell_integration_workflow_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 +host_wasm_opfs_browser_smokes=ok +``` + +下一步建议: + +继续推进 SDK/API surface。下一批建议为 shared mount DOM renderer 增加 schema/contract helper +(例如 `createIniPanelShellSessionHandoffMountDomContract()`),让外部 shell 可在渲染前校验所需 +DOM nodes、dataset keys 与 row dataset prefix;仍保持只读,不新增控制按钮,不解析 G-code。 diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index 54adf74..915e703 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -30,6 +30,8 @@ import { createIniPanelShellSessionHandoffPackageMountDisplayViewModel, createIniPanelShellSessionHandoffPackageMountRenderState, createIniPanelShellSessionHandoffPackageMountState, + renderIniPanelShellSessionHandoffMountState, + renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, createIniPanelShellSessionHandoffPackageSchema, @@ -224,7 +226,9 @@ when an outer shell needs mount-state checks as stable read-only label/value rows. Use `createIniPanelShellSessionHandoffPackageMountRenderState()` or `linuxCncIniPanelLaunchApi.getShellSessionHandoffPackageMountRenderState()` when those rows need a status line and `[data-handoff-shell]` style dataset -flags for DOM rendering. The launch page renders the default waiting mount +flags for DOM rendering. Use `renderIniPanelShellSessionHandoffMountState()` or +`linuxCncIniPanelLaunchApi.renderShellSessionHandoffMountState()` when an outer +shell needs the shared read-only DOM renderer for those rows. The launch page renders the default waiting mount state into `[data-handoff-mount]`, `[data-handoff-mount-status]`, and `[data-handoff-mount-rows]` without opening the control page. The browser workflow smoke diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index 01abc7d..1bdb1e0 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -106,6 +106,7 @@ createIniPanelLauncherLinkViewModel, createIniPanelShellViewModel, isSupportedIniPanelLaunchApiManifest, + renderIniPanelShellSessionHandoffMountState, } from "./ui-shell.js"; const shellViewModel = createIniPanelShellViewModel(); @@ -135,23 +136,7 @@ handoffRows.append(term, detail); } const handoffMountRenderState = shellViewModel.shellSessionHandoffPackageMountRenderState; - const handoffMount = document.querySelector("[data-handoff-mount]"); - handoffMount.dataset.handoffPhase = handoffMountRenderState.dataset.handoffPhase; - handoffMount.dataset.handoffReady = handoffMountRenderState.dataset.handoffReady; - handoffMount.dataset.handoffScope = handoffMountRenderState.dataset.handoffScope; - document.querySelector("[data-handoff-mount-status]").textContent = handoffMountRenderState.statusLine; - const handoffMountRows = document.querySelector("[data-handoff-mount-rows]"); - for (const row of handoffMountRenderState.rows) { - const term = document.createElement("dt"); - term.dataset.handoffMountRow = row.id; - term.dataset.handoffMountStatus = row.status; - term.textContent = row.label; - const detail = document.createElement("dd"); - detail.dataset.handoffMountValue = row.id; - detail.dataset.handoffMountStatus = row.status; - detail.textContent = row.value; - handoffMountRows.append(term, detail); - } + renderIniPanelShellSessionHandoffMountState(handoffMountRenderState, { documentRef: document }); window.linuxCncIniPanelLaunchApi = { isSupportedLaunchApiManifest: isSupportedIniPanelLaunchApiManifest, @@ -195,6 +180,9 @@ ), ) ), + renderShellSessionHandoffMountState: (renderState, options) => ( + renderIniPanelShellSessionHandoffMountState(renderState, options ?? { documentRef: document }) + ), isSupportedShellSessionHandoffPackage: shellViewModel.isSupportedShellSessionHandoffPackage, getLauncherLinks: () => shellViewModel.launcherLinks, getControlPageApiMethods: () => shellViewModel.controlPage.browserApiMethods, diff --git a/wasm-port/runtime/ui/ini-panel/ui-shell.js b/wasm-port/runtime/ui/ini-panel/ui-shell.js index eebc748..7df7632 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -143,6 +143,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "getShellSessionHandoffPackageMountState", "getShellSessionHandoffPackageMountDisplayViewModel", "getShellSessionHandoffPackageMountRenderState", + "renderShellSessionHandoffMountState", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -1078,6 +1079,55 @@ export function createIniPanelShellSessionHandoffPackageMountRenderState( }; } +export function renderIniPanelShellSessionHandoffMountState( + renderState = createIniPanelShellSessionHandoffPackageMountRenderState(), + { + documentRef = globalThis.document, + mountNode = documentRef?.querySelector?.("[data-handoff-mount]"), + statusNode = documentRef?.querySelector?.("[data-handoff-mount-status]"), + rowsNode = documentRef?.querySelector?.("[data-handoff-mount-rows]"), + rowDatasetPrefix = "handoffMount", + } = {}, +) { + if (!documentRef?.createElement) { + throw new Error("A DOM document is required to render shell handoff mount state."); + } + if (!mountNode || !statusNode || !rowsNode) { + throw new Error("Mount, status, and rows nodes are required to render shell handoff mount state."); + } + + mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked"; + mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false"; + mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope ?? "mount"; + statusNode.textContent = renderState?.statusLine ?? "Blocked: No mount render state"; + rowsNode.replaceChildren(); + + const rows = Array.isArray(renderState?.rows) ? renderState.rows : []; + for (const row of rows) { + const term = documentRef.createElement("dt"); + term.dataset[`${rowDatasetPrefix}Row`] = row.id; + term.dataset[`${rowDatasetPrefix}Status`] = row.status; + term.textContent = row.label; + const detail = documentRef.createElement("dd"); + detail.dataset[`${rowDatasetPrefix}Value`] = row.id; + detail.dataset[`${rowDatasetPrefix}Status`] = row.status; + detail.textContent = row.value; + rowsNode.append(term, detail); + } + + return { + rendered: true, + statusLine: statusNode.textContent, + rowCount: rows.length, + rowIds: rows.map(({ id }) => id), + dataset: { + handoffPhase: mountNode.dataset.handoffPhase, + handoffReady: mountNode.dataset.handoffReady, + handoffScope: mountNode.dataset.handoffScope, + }, + }; +} + export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries); const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest); @@ -1190,6 +1240,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries createShellSessionHandoffPackageMountState: createIniPanelShellSessionHandoffPackageMountState, createShellSessionHandoffPackageMountDisplayViewModel: createIniPanelShellSessionHandoffPackageMountDisplayViewModel, createShellSessionHandoffPackageMountRenderState: createIniPanelShellSessionHandoffPackageMountRenderState, + renderShellSessionHandoffMountState: renderIniPanelShellSessionHandoffMountState, isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), diff --git a/wasm-port/tests/browser/ini_panel_launch_smoke.html b/wasm-port/tests/browser/ini_panel_launch_smoke.html index 3e51bf1..01a0379 100644 --- a/wasm-port/tests/browser/ini_panel_launch_smoke.html +++ b/wasm-port/tests/browser/ini_panel_launch_smoke.html @@ -90,6 +90,7 @@ !launchApi?.getShellSessionHandoffPackageMountState || !launchApi?.getShellSessionHandoffPackageMountDisplayViewModel || !launchApi?.getShellSessionHandoffPackageMountRenderState || + !launchApi?.renderShellSessionHandoffMountState || !launchApi?.isSupportedShellSessionHandoffPackage || !launchApi?.getLauncherLinks || !launchApi?.getControlPageApiMethods @@ -130,7 +131,7 @@ ); assertEqual( launchApiManifest.methods.join(","), - "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getShellSessionHandoffChecklist,getShellSessionHandoffPackageSchema,getShellSessionHandoffPackage,getShellSessionHandoffPackageReport,getShellSessionHandoffPackageDisplayViewModel,getShellSessionHandoffPackageRenderState,getShellSessionHandoffPackageMountState,getShellSessionHandoffPackageMountDisplayViewModel,getShellSessionHandoffPackageMountRenderState,isSupportedShellSessionHandoffPackage,getLauncherLinks,getControlPageApiMethods", + "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getShellSessionHandoffChecklist,getShellSessionHandoffPackageSchema,getShellSessionHandoffPackage,getShellSessionHandoffPackageReport,getShellSessionHandoffPackageDisplayViewModel,getShellSessionHandoffPackageRenderState,getShellSessionHandoffPackageMountState,getShellSessionHandoffPackageMountDisplayViewModel,getShellSessionHandoffPackageMountRenderState,renderShellSessionHandoffMountState,isSupportedShellSessionHandoffPackage,getLauncherLinks,getControlPageApiMethods", "launch API manifest methods", ); const shellIntegrationSchema = launchApi.getShellIntegrationSchema(); diff --git a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html index f1a3776..3a3bb14 100644 --- a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html +++ b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html @@ -44,28 +44,6 @@ return frame.contentDocument; } - function renderExternalShellMountState(renderState) { - const mountNode = document.querySelector("[data-external-shell-mount]"); - const statusNode = document.querySelector("[data-external-shell-mount-status]"); - const rowsNode = document.querySelector("[data-external-shell-mount-rows]"); - mountNode.dataset.handoffPhase = renderState.dataset.handoffPhase; - mountNode.dataset.handoffReady = renderState.dataset.handoffReady; - mountNode.dataset.handoffScope = renderState.dataset.handoffScope; - statusNode.textContent = renderState.statusLine; - rowsNode.replaceChildren(); - for (const row of renderState.rows) { - const term = document.createElement("dt"); - term.dataset.externalMountRow = row.id; - term.dataset.externalMountStatus = row.status; - term.textContent = row.label; - const detail = document.createElement("dd"); - detail.dataset.externalMountValue = row.id; - detail.dataset.externalMountStatus = row.status; - detail.textContent = row.value; - rowsNode.append(term, detail); - } - } - try { const iniText = `[EMC] MACHINE = browser-shell-integration @@ -107,6 +85,7 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.getShellSessionHandoffPackageMountState || !launchApi?.getShellSessionHandoffPackageMountDisplayViewModel || !launchApi?.getShellSessionHandoffPackageMountRenderState || + !launchApi?.renderShellSessionHandoffMountState || !launchApi?.isSupportedShellSessionHandoffPackage ) { throw new Error("launch API namespace did not expose shell integration helpers"); @@ -130,7 +109,16 @@ TOOL_TABLE = browser-shell-tool.tbl const handoffPackageMountState = launchApi.getShellSessionHandoffPackageMountState(); const handoffPackageMountDisplay = launchApi.getShellSessionHandoffPackageMountDisplayViewModel(); const handoffPackageMountRenderState = launchApi.getShellSessionHandoffPackageMountRenderState(); - renderExternalShellMountState(handoffPackageMountRenderState); + const waitingMountRenderResult = launchApi.renderShellSessionHandoffMountState( + handoffPackageMountRenderState, + { + documentRef: document, + mountNode: document.querySelector("[data-external-shell-mount]"), + statusNode: document.querySelector("[data-external-shell-mount-status]"), + rowsNode: document.querySelector("[data-external-shell-mount-rows]"), + rowDatasetPrefix: "externalMount", + }, + ); assertEqual(handoffSummarySchema.summaryVersion, 1, "shell handoff summary schema version"); assertEqual( launchApi.isSupportedShellSessionHandoffSummary(handoffSummary), @@ -195,6 +183,8 @@ TOOL_TABLE = browser-shell-tool.tbl assertEqual(handoffPackageMountState.sessionLoadState.phase, "waiting-panel", "shell handoff package mount-state default session"); assertEqual(handoffPackageMountDisplay.detailText, "session-load-state", "shell handoff package mount display detail"); assertEqual(handoffPackageMountRenderState.statusLine, "Blocked: session-load-state", "shell handoff package mount render-state status"); + assertEqual(waitingMountRenderResult.rendered, true, "external shell waiting mount render result"); + assertEqual(waitingMountRenderResult.rowCount, 5, "external shell waiting mount row count"); assertEqual( document.querySelector("[data-external-shell-mount-status]").textContent, "Blocked: session-load-state", @@ -287,11 +277,22 @@ TOOL_TABLE = browser-shell-tool.tbl ); const readyMountDisplay = launchApi.getShellSessionHandoffPackageMountDisplayViewModel(readyMountState); const readyMountRenderState = launchApi.getShellSessionHandoffPackageMountRenderState(readyMountState); - renderExternalShellMountState(readyMountRenderState); + const readyMountRenderResult = launchApi.renderShellSessionHandoffMountState( + readyMountRenderState, + { + documentRef: document, + mountNode: document.querySelector("[data-external-shell-mount]"), + statusNode: document.querySelector("[data-external-shell-mount-status]"), + rowsNode: document.querySelector("[data-external-shell-mount-rows]"), + rowDatasetPrefix: "externalMount", + }, + ); assertEqual(readyMountState.ready, true, "shell handoff package mount-state readiness"); assertEqual(readyMountState.sessionLoadState.phase, "ready", "shell handoff package mount-state ready session"); assertEqual(readyMountDisplay.detailText, "No blocking reasons", "shell handoff package ready mount display"); assertEqual(readyMountRenderState.statusLine, "Ready: No blocking reasons", "shell handoff package ready mount render-state"); + assertEqual(readyMountRenderResult.rendered, true, "external shell ready mount render result"); + assertEqual(readyMountRenderResult.dataset.handoffReady, "true", "external shell ready mount render dataset"); assertEqual( document.querySelector("[data-external-shell-mount-status]").textContent, "Ready: No blocking reasons", diff --git a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs index 267a674..54553bb 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs @@ -27,6 +27,7 @@ import { createIniPanelShellSessionHandoffPackageMountDisplayViewModel, createIniPanelShellSessionHandoffPackageMountRenderState, createIniPanelShellSessionHandoffPackageMountState, + renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, createIniPanelShellSessionHandoffPackageSchema, @@ -92,6 +93,7 @@ const requiredShellExports = [ "createIniPanelShellSessionHandoffPackageMountDisplayViewModel", "createIniPanelShellSessionHandoffPackageMountRenderState", "createIniPanelShellSessionHandoffPackageMountState", + "renderIniPanelShellSessionHandoffMountState", "createIniPanelShellSessionHandoffPackageReport", "createIniPanelShellSessionHandoffPackageRenderState", "createIniPanelShellSessionHandoffPackageSchema", @@ -432,6 +434,8 @@ assert.match(docText, /\bdata-handoff-shell\b/); assert.match(docText, /\bdata-handoff-status\b/); assert.match(docText, /\bdata-handoff-rows\b/); assert.match(docText, /\bdata-external-shell-mount\b/); +assert.match(docText, /\brenderIniPanelShellSessionHandoffMountState\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.renderShellSessionHandoffMountState\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getControlPageApiMethods\b/); assert.match(docText, /\bini_panel_shell_integration_workflow_smoke\.html\b/); assert.match(browserIniPanelText, /\bini_panel_shell_integration_workflow_smoke\.html\b/); @@ -448,6 +452,7 @@ assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackage assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackage\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackageReport\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackageMountRenderState\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\brenderShellSessionHandoffMountState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-shell-mount\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-mount-value\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bisSupportedShellSessionHandoffPackage\b/); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs index 08f8131..6b0684c 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs @@ -63,6 +63,7 @@ assert.deepEqual(manifest, { "getShellSessionHandoffPackageMountState", "getShellSessionHandoffPackageMountDisplayViewModel", "getShellSessionHandoffPackageMountRenderState", + "renderShellSessionHandoffMountState", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -181,6 +182,7 @@ assert.match(launchText, /\bgetShellSessionHandoffPackageRenderState\b/); assert.match(launchText, /\bgetShellSessionHandoffPackageMountState\b/); assert.match(launchText, /\bgetShellSessionHandoffPackageMountDisplayViewModel\b/); assert.match(launchText, /\bgetShellSessionHandoffPackageMountRenderState\b/); +assert.match(launchText, /\brenderShellSessionHandoffMountState\b/); assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/); assert.match(launchText, /\bdata-handoff-mount\b/); assert.match(launchText, /\bdata-handoff-mount-status\b/); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs index f332e24..176fd82 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs @@ -148,7 +148,7 @@ assert.deepEqual(readiness, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 26, + launchMethods: 27, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -210,7 +210,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 26, + launchMethods: 27, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -1077,7 +1077,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 2, launcherLinks: 2, - launchMethods: 26, + launchMethods: 27, controlPageMethods: 11, persistenceCapabilities: 3, }, diff --git a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs index 64b33f8..a142d69 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs @@ -23,6 +23,7 @@ import { createIniPanelShellSessionHandoffPackageMountDisplayViewModel, createIniPanelShellSessionHandoffPackageMountRenderState, createIniPanelShellSessionHandoffPackageMountState, + renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, createIniPanelShellSessionHandoffPackageSchema, @@ -93,6 +94,7 @@ assert.equal(typeof createIniPanelShellSessionHandoffPackageDisplayViewModel, "f assert.equal(typeof createIniPanelShellSessionHandoffPackageMountDisplayViewModel, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageMountRenderState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageMountState, "function"); +assert.equal(typeof renderIniPanelShellSessionHandoffMountState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageReport, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageRenderState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageSchema, "function"); @@ -660,6 +662,10 @@ assert.equal( shellViewModel.createShellSessionHandoffPackageMountRenderState, createIniPanelShellSessionHandoffPackageMountRenderState, ); +assert.equal( + shellViewModel.renderShellSessionHandoffMountState, + renderIniPanelShellSessionHandoffMountState, +); assert.equal(shellViewModel.createShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageReport); assert.equal(shellViewModel.createShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema); assert.equal(shellViewModel.isSupportedShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffPackage); @@ -715,6 +721,48 @@ const controller = createMachineSessionControlPageController({ }, }); +const mountRowsNode = { + children: [], + replaceChildren() { + this.children = []; + }, + append(...nodes) { + this.children.push(...nodes); + }, +}; +const mountNode = { dataset: {} }; +const mountStatusNode = { textContent: "" }; +const mountDocument = { + createElement: (tagName) => ({ tagName, dataset: {}, textContent: "" }), +}; +assert.deepEqual( + renderIniPanelShellSessionHandoffMountState(shellViewModel.shellSessionHandoffPackageMountRenderState, { + documentRef: mountDocument, + mountNode, + statusNode: mountStatusNode, + rowsNode: mountRowsNode, + }), + { + rendered: true, + statusLine: "Blocked: session-load-state", + rowCount: 5, + rowIds: [ + "package-render-state", + "target-page", + "required-methods", + "session-load-state", + "blocking-reasons", + ], + dataset: { + handoffPhase: "blocked", + handoffReady: "false", + handoffScope: "mount", + }, + }, +); +assert.equal(mountRowsNode.children[7].dataset.handoffMountValue, "session-load-state"); +assert.equal(mountRowsNode.children[7].dataset.handoffMountStatus, "blocked"); + assert.deepEqual(controller.render(), { rendered: true }); assert.equal(statusNode.textContent, "run-gcode | ok | -"); assert.equal(renderedView.status.runStatus, "ok");