From c92021fa82c03ebd9385c1001f60ce87c2390691 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Mon, 15 Jun 2026 10:07:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E8=BF=9B=20INI=20=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=20shell=20handoff=20checklist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- text13.txt | 101 ++++++++++++++++ wasm-port/docs/panel-entry.md | 7 ++ wasm-port/runtime/ui/ini-panel/launch.html | 1 + wasm-port/runtime/ui/ini-panel/ui-shell.js | 74 ++++++++++++ .../tests/browser/ini_panel_launch_smoke.html | 29 ++++- ...anel_shell_integration_workflow_smoke.html | 16 ++- .../ui/node/verify_ini_panel_entry_docs.mjs | 14 +++ .../verify_ini_panel_launch_api_manifest.mjs | 2 + ...y_ini_panel_shell_integration_manifest.mjs | 111 +++++++++++++++++- .../ui/node/verify_ini_panel_ui_shell.mjs | 52 ++++++++ 10 files changed, 402 insertions(+), 5 deletions(-) diff --git a/text13.txt b/text13.txt index dea9f48..91c2dba 100644 --- a/text13.txt +++ b/text13.txt @@ -706,3 +706,104 @@ host_wasm_opfs_browser_smokes=ok `createIniPanelShellSessionHandoffChecklist()` 或等价 helper,把 action-plan、render-state、 required methods 和 blocking reasons 压成外部 shell 可显示的 checklist/health rows,并补真实 browser workflow smoke;仍保持只读,不新增控制按钮,不解析 G-code。 + +六、2026-06-15 继续执行记录:INI panel shell handoff checklist + +本轮按“第一原则:加快实质性推进”继续推进 OPFS/session persistence 与 browser/UI workflow +的交界,新增只读 shell handoff checklist helper,把 action-plan、render-state、required +methods 和 blocking reasons 压成外部 shell 可显示的 health rows。 + +完成内容: + +- `ui-shell.js` 新增 `createIniPanelShellSessionHandoffChecklist()`; +- checklist 输出: + - `apiName: "ini-panel-shell-session-handoff-checklist"`; + - `checklistVersion: 1`; + - `phase`; + - `ready`; + - `statusLine`; + - `checks`; + - `displayRows`; + - `nextStepIds`; + - `blockingReasons`; +- checklist checks 固定覆盖: + - `render-state`; + - `target-page`; + - `load-session-method`; + - `read-status-method`; + - `blocking-reasons`; +- `createIniPanelShellViewModel()` 新增: + - `shellSessionHandoffChecklist`; + - `createShellSessionHandoffChecklist`; +- `createIniPanelLaunchApiManifest().methods` 新增 + `getShellSessionHandoffChecklist`; +- `launch.html` 的 `window.linuxCncIniPanelLaunchApi` 新增真实 browser 入口 + `getShellSessionHandoffChecklist()`; +- `ini_panel_launch_smoke.html` 校验真实 launch iframe: + - checklist version 为 1; + - checklist `ready === true`; + - 5 个 health checks 全部为 `pass`; + - `nextStepIds` 为 `open-control-page,read-readonly-status`; + - `displayRows` 与 render-state rows 一致; +- `ini_panel_shell_integration_workflow_smoke.html` 校验外部 shell workflow 能读取 + checklist,并确认 checks 与 nextStepIds; +- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖: + - ready checklist 完整 shape; + - default checklist check 数量; + - blocked/mismatch checklist health rows; +- `verify_ini_panel_ui_shell.mjs` 覆盖 shell view-model 的 checklist 聚合关系; +- `verify_ini_panel_launch_api_manifest.mjs`、`verify_ini_panel_entry_docs.mjs` 与 + `docs/panel-entry.md` 同步记录和校验新 helper/API; +- 未新增控制按钮; +- 未执行 action-plan; +- 未解析 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_shell_integration_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_ui_shell.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_shell_integration_manifest_node_smoke=ok +ini_panel_launch_api_manifest_node_smoke=ok +ini_panel_ui_shell_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 +``` + +下一步建议: + +继续推进 browser/UI workflow 与 OPFS/session persistence 的交界。下一批建议新增一个只读 +`createIniPanelShellSessionHandoffPackage()` 或等价 helper,把 snapshot、render-state、 +action-plan、checklist 和 launch/control method manifests 打包成单次 browser shell 可读取的 +handoff package,并补真实 browser workflow smoke;仍保持只读,不新增控制按钮,不解析 G-code。 diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index 14204f8..251fcbd 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -22,6 +22,7 @@ import { createIniPanelShellIntegrationSchema, createIniPanelShellIntegrationWorkflowPlan, createIniPanelShellSessionHandoffActionPlan, + createIniPanelShellSessionHandoffChecklist, createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffRenderState, @@ -172,6 +173,12 @@ shell needs a read-only next-step description derived from the same snapshot: target page, required readonly methods, blocking reasons, display rows, and ready/blocked next step ids. The action plan describes what an outer shell can do next; it does not execute actions or add controls. +Use `createIniPanelShellSessionHandoffChecklist()` or +`linuxCncIniPanelLaunchApi.getShellSessionHandoffChecklist()` when an outer +shell needs the same handoff state as stable health rows for display: render +state, target page, load-session method, read-status method, blocking reasons, +display rows, and next step ids. The checklist is read-only and does not +execute the action plan. The browser workflow smoke `tests/browser/ini_panel_shell_integration_workflow_smoke.html` verifies the same external shell handoff: read integration manifest, pass readiness gate, diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index 7e4b13e..d89c825 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -145,6 +145,7 @@ getShellSessionHandoffSnapshot: () => shellViewModel.shellSessionHandoffSnapshot, getShellSessionHandoffRenderState: () => shellViewModel.shellSessionHandoffRenderState, getShellSessionHandoffActionPlan: () => shellViewModel.shellSessionHandoffActionPlan, + getShellSessionHandoffChecklist: () => shellViewModel.shellSessionHandoffChecklist, 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 7dbb3b5..d612f1d 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -134,6 +134,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "getShellSessionHandoffSnapshot", "getShellSessionHandoffRenderState", "getShellSessionHandoffActionPlan", + "getShellSessionHandoffChecklist", "getLauncherLinks", "getControlPageApiMethods", ], @@ -647,6 +648,73 @@ export function createIniPanelShellSessionHandoffActionPlan({ }; } +export function createIniPanelShellSessionHandoffChecklist({ + actionPlan = createIniPanelShellSessionHandoffActionPlan(), + renderState = createIniPanelShellSessionHandoffRenderState(), +} = {}) { + const displayRows = Array.isArray(actionPlan?.displayRows) + ? actionPlan.displayRows.map(({ id, label, value }) => ({ id, label, value })) + : []; + const blockingReasons = Array.isArray(actionPlan?.blockingReasons) + ? [...actionPlan.blockingReasons] + : []; + const targetPageReady = Boolean(actionPlan?.targetPage?.href); + const loadMethodReady = Boolean(actionPlan?.requiredMethods?.loadSessionState); + const readMethodReady = Boolean(actionPlan?.requiredMethods?.readStatus); + const ready = actionPlan?.ready === true + && renderState?.ready === true + && targetPageReady + && loadMethodReady + && readMethodReady + && blockingReasons.length === 0; + const checks = [ + { + id: "render-state", + label: "Render state", + status: renderState?.ready ? "pass" : "blocked", + value: renderState?.statusLine ?? "missing", + }, + { + id: "target-page", + label: "Control target", + status: targetPageReady ? "pass" : "blocked", + value: actionPlan?.targetPage?.href ?? "missing", + }, + { + id: "load-session-method", + label: "Load session method", + status: loadMethodReady ? "pass" : "blocked", + value: actionPlan?.requiredMethods?.loadSessionState ?? "missing", + }, + { + id: "read-status-method", + label: "Read status method", + status: readMethodReady ? "pass" : "blocked", + value: actionPlan?.requiredMethods?.readStatus ?? "missing", + }, + { + id: "blocking-reasons", + label: "Blocking reasons", + status: blockingReasons.length === 0 ? "pass" : "blocked", + value: blockingReasons.length === 0 ? "none" : blockingReasons.join(", "), + }, + ]; + + return { + apiName: "ini-panel-shell-session-handoff-checklist", + checklistVersion: 1, + phase: ready ? "ready" : "blocked", + ready, + statusLine: actionPlan?.statusLine ?? renderState?.statusLine ?? "Blocked: No handoff action plan", + checks, + displayRows, + nextStepIds: Array.isArray(actionPlan?.nextSteps) + ? actionPlan.nextSteps.map(({ id }) => id) + : [], + blockingReasons, + }; +} + export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries); const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest); @@ -678,6 +746,10 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries snapshot: shellSessionHandoffSnapshot, renderState: shellSessionHandoffRenderState, }); + const shellSessionHandoffChecklist = createIniPanelShellSessionHandoffChecklist({ + actionPlan: shellSessionHandoffActionPlan, + renderState: shellSessionHandoffRenderState, + }); return { pages: entries.map(({ id, href, title }) => ({ id, @@ -696,6 +768,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries shellSessionHandoffSnapshot, shellSessionHandoffRenderState, shellSessionHandoffActionPlan, + shellSessionHandoffChecklist, launchApiSchema: createIniPanelLaunchApiSchema(), launchApiManifest: createIniPanelLaunchApiManifest(entries), isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest, @@ -709,6 +782,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries createShellSessionHandoffSnapshot: createIniPanelShellSessionHandoffSnapshot, createShellSessionHandoffRenderState: createIniPanelShellSessionHandoffRenderState, createShellSessionHandoffActionPlan: createIniPanelShellSessionHandoffActionPlan, + createShellSessionHandoffChecklist: createIniPanelShellSessionHandoffChecklist, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), browserApiManifest: createControlPageBrowserApiManifest(), diff --git a/wasm-port/tests/browser/ini_panel_launch_smoke.html b/wasm-port/tests/browser/ini_panel_launch_smoke.html index e90b81c..058df48 100644 --- a/wasm-port/tests/browser/ini_panel_launch_smoke.html +++ b/wasm-port/tests/browser/ini_panel_launch_smoke.html @@ -81,6 +81,7 @@ !launchApi?.getShellSessionHandoffSnapshot || !launchApi?.getShellSessionHandoffRenderState || !launchApi?.getShellSessionHandoffActionPlan || + !launchApi?.getShellSessionHandoffChecklist || !launchApi?.getLauncherLinks || !launchApi?.getControlPageApiMethods ) { @@ -120,7 +121,7 @@ ); assertEqual( launchApiManifest.methods.join(","), - "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getLauncherLinks,getControlPageApiMethods", + "isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getShellSessionHandoffRenderState,getShellSessionHandoffActionPlan,getShellSessionHandoffChecklist,getLauncherLinks,getControlPageApiMethods", "launch API manifest methods", ); const shellIntegrationSchema = launchApi.getShellIntegrationSchema(); @@ -133,6 +134,7 @@ const shellSessionHandoffSnapshot = launchApi.getShellSessionHandoffSnapshot(); const shellSessionHandoffRenderState = launchApi.getShellSessionHandoffRenderState(); const shellSessionHandoffActionPlan = launchApi.getShellSessionHandoffActionPlan(); + const shellSessionHandoffChecklist = launchApi.getShellSessionHandoffChecklist(); assertEqual( shellIntegrationSchema.manifestVersion, 1, @@ -263,6 +265,26 @@ "readControlPageStatus", "shell session handoff action-plan read method", ); + assertEqual( + shellSessionHandoffChecklist.checklistVersion, + 1, + "shell session handoff checklist version", + ); + assertEqual( + shellSessionHandoffChecklist.ready, + true, + "shell session handoff checklist readiness", + ); + assertEqual( + shellSessionHandoffChecklist.checks.map(({ status }) => status).join(","), + "pass,pass,pass,pass,pass", + "shell session handoff checklist checks", + ); + assertEqual( + shellSessionHandoffChecklist.nextStepIds.join(","), + "open-control-page,read-readonly-status", + "shell session handoff checklist next step ids", + ); assertEqual( JSON.stringify(shellSessionHandoffSnapshot.readiness), JSON.stringify(shellIntegrationReadiness), @@ -288,6 +310,11 @@ JSON.stringify(shellSessionHandoffRenderState.rows), "shell session handoff action-plan rows", ); + assertEqual( + JSON.stringify(shellSessionHandoffChecklist.displayRows), + JSON.stringify(shellSessionHandoffRenderState.rows), + "shell session handoff checklist rows", + ); assertEqual( launchDoc.querySelector("[data-handoff-status]").textContent, "Ready: No blocking reasons", 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 d191fa7..127dbca 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 @@ -71,7 +71,8 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.getShellSessionHandoffDisplayViewModel || !launchApi?.getShellSessionHandoffSnapshot || !launchApi?.getShellSessionHandoffRenderState || - !launchApi?.getShellSessionHandoffActionPlan + !launchApi?.getShellSessionHandoffActionPlan || + !launchApi?.getShellSessionHandoffChecklist ) { throw new Error("launch API namespace did not expose shell integration helpers"); } @@ -85,6 +86,7 @@ TOOL_TABLE = browser-shell-tool.tbl const handoffSnapshot = launchApi.getShellSessionHandoffSnapshot(); const handoffRenderState = launchApi.getShellSessionHandoffRenderState(); const handoffActionPlan = launchApi.getShellSessionHandoffActionPlan(); + const handoffChecklist = launchApi.getShellSessionHandoffChecklist(); assertEqual(handoffSummarySchema.summaryVersion, 1, "shell handoff summary schema version"); assertEqual( launchApi.isSupportedShellSessionHandoffSummary(handoffSummary), @@ -108,6 +110,18 @@ TOOL_TABLE = browser-shell-tool.tbl "open-control-page,read-readonly-status", "shell handoff action-plan next steps", ); + assertEqual(handoffChecklist.ready, true, "shell handoff checklist readiness"); + assertEqual(handoffChecklist.checks.length, 5, "shell handoff checklist checks"); + assertEqual( + handoffChecklist.checks.map(({ status }) => status).join(","), + "pass,pass,pass,pass,pass", + "shell handoff checklist check status", + ); + assertEqual( + handoffChecklist.nextStepIds.join(","), + "open-control-page,read-readonly-status", + "shell handoff checklist next steps", + ); assertEqual(readiness.phase, "ready", "shell integration readiness phase"); assertEqual(readiness.ready, true, "shell integration readiness"); assertEqual(readiness.missing.join(","), "", "shell integration readiness missing checks"); 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 ad53af8..0e636ff 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 @@ -19,6 +19,7 @@ import { createIniPanelShellIntegrationSchema, createIniPanelShellIntegrationWorkflowPlan, createIniPanelShellSessionHandoffActionPlan, + createIniPanelShellSessionHandoffChecklist, createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffRenderState, @@ -74,6 +75,7 @@ const requiredShellExports = [ "createIniPanelShellIntegrationSchema", "createIniPanelShellIntegrationWorkflowPlan", "createIniPanelShellSessionHandoffActionPlan", + "createIniPanelShellSessionHandoffChecklist", "createIniPanelShellSessionHandoffCompatibilityReport", "createIniPanelShellSessionHandoffDisplayViewModel", "createIniPanelShellSessionHandoffRenderState", @@ -199,6 +201,13 @@ assert.deepEqual( renderState: createIniPanelShellViewModel().shellSessionHandoffRenderState, }), ); +assert.deepEqual( + createIniPanelShellViewModel().shellSessionHandoffChecklist, + createIniPanelShellSessionHandoffChecklist({ + actionPlan: createIniPanelShellViewModel().shellSessionHandoffActionPlan, + renderState: createIniPanelShellViewModel().shellSessionHandoffRenderState, + }), +); assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true); assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema()); assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, createIniPanelLaunchApiManifest()); @@ -254,6 +263,7 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifes assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/); assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffActionPlan\b/); +assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffChecklist\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffRenderState\b/); @@ -283,6 +293,7 @@ assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/); assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/); assert.match(launchText, /\bgetShellSessionHandoffRenderState\b/); assert.match(launchText, /\bgetShellSessionHandoffActionPlan\b/); +assert.match(launchText, /\bgetShellSessionHandoffChecklist\b/); assert.match(launchText, /\bdata-handoff-shell\b/); assert.match(launchText, /\bdata-handoff-status\b/); assert.match(launchText, /\bdata-handoff-rows\b/); @@ -305,6 +316,7 @@ assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/); assert.match(docText, /\bcreateIniPanelShellIntegrationSchema\b/); assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffActionPlan\b/); +assert.match(docText, /\bcreateIniPanelShellSessionHandoffChecklist\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffRenderState\b/); @@ -329,6 +341,7 @@ assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffDispla assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSnapshot\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffRenderState\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffActionPlan\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffChecklist\b/); assert.match(docText, /\bdata-handoff-shell\b/); assert.match(docText, /\bdata-handoff-status\b/); assert.match(docText, /\bdata-handoff-rows\b/); @@ -343,6 +356,7 @@ assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffDisplay assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSnapshot\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffRenderState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffActionPlan\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffChecklist\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bhandoffSummary\.handoffMethods\.readStatus\b/); assert.match(shellIntegrationWorkflowSmokeText, /\breadControlPageStatus\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bbrowser_ini_shell_integration_workflow_smoke=ok\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 d47d33b..39821ae 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 @@ -54,6 +54,7 @@ assert.deepEqual(manifest, { "getShellSessionHandoffSnapshot", "getShellSessionHandoffRenderState", "getShellSessionHandoffActionPlan", + "getShellSessionHandoffChecklist", "getLauncherLinks", "getControlPageApiMethods", ], @@ -162,6 +163,7 @@ assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/); assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/); assert.match(launchText, /\bgetShellSessionHandoffRenderState\b/); assert.match(launchText, /\bgetShellSessionHandoffActionPlan\b/); +assert.match(launchText, /\bgetShellSessionHandoffChecklist\b/); assert.match(launchText, /\blinuxCncIniPanelLaunchApi\b/); console.log("ini_panel_launch_api_manifest_node_smoke=ok"); 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 7ed7a1a..bf3653f 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 @@ -15,6 +15,7 @@ import { createIniPanelShellIntegrationSchema, createIniPanelShellIntegrationWorkflowPlan, createIniPanelShellSessionHandoffActionPlan, + createIniPanelShellSessionHandoffChecklist, createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffRenderState, @@ -51,6 +52,10 @@ const handoffActionPlan = createIniPanelShellSessionHandoffActionPlan({ snapshot: handoffSnapshot, renderState: handoffRenderState, }); +const handoffChecklist = createIniPanelShellSessionHandoffChecklist({ + actionPlan: handoffActionPlan, + renderState: handoffRenderState, +}); assert.deepEqual(schema, { apiName: "ini-panel-shell-integration", @@ -106,7 +111,7 @@ assert.deepEqual(readiness, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 16, + launchMethods: 17, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -168,7 +173,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 16, + launchMethods: 17, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -367,9 +372,52 @@ assert.deepEqual(handoffActionPlan, { }, ], }); +assert.deepEqual(handoffChecklist, { + apiName: "ini-panel-shell-session-handoff-checklist", + checklistVersion: 1, + phase: "ready", + ready: true, + statusLine: "Ready: No blocking reasons", + checks: [ + { + id: "render-state", + label: "Render state", + status: "pass", + value: "Ready: No blocking reasons", + }, + { + id: "target-page", + label: "Control target", + status: "pass", + value: "./control-page.html", + }, + { + id: "load-session-method", + label: "Load session method", + status: "pass", + value: "loadControlPageSessionState", + }, + { + id: "read-status-method", + label: "Read status method", + status: "pass", + value: "readControlPageStatus", + }, + { + id: "blocking-reasons", + label: "Blocking reasons", + status: "pass", + value: "none", + }, + ], + displayRows: handoffActionPlan.displayRows, + nextStepIds: ["open-control-page", "read-readonly-status"], + blockingReasons: [], +}); assert.equal(createIniPanelShellSessionHandoffSnapshot().displayViewModel.rows.length, 5); assert.equal(createIniPanelShellSessionHandoffRenderState().statusLine, "Ready: No blocking reasons"); assert.equal(createIniPanelShellSessionHandoffActionPlan().nextSteps.length, 2); +assert.equal(createIniPanelShellSessionHandoffChecklist().checks.length, 5); assert.deepEqual( createIniPanelShellSessionHandoffDisplayViewModel( createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }), @@ -510,6 +558,61 @@ assert.deepEqual( }, ], ); +assert.deepEqual( + createIniPanelShellSessionHandoffChecklist({ + actionPlan: createIniPanelShellSessionHandoffActionPlan({ + snapshot: createIniPanelShellSessionHandoffSnapshot({ + summary: { + ...handoffSummary, + summaryVersion: 2, + }, + compatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport({ + ...handoffSummary, + summaryVersion: 2, + }), + }), + renderState: createIniPanelShellSessionHandoffRenderState(createIniPanelShellSessionHandoffSnapshot({ + compatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport({ + ...handoffSummary, + summaryVersion: 2, + }), + })), + }), + renderState: createIniPanelShellSessionHandoffRenderState(createIniPanelShellSessionHandoffSnapshot({ + compatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport({ + ...handoffSummary, + summaryVersion: 2, + }), + })), + }).checks.map(({ id, status, value }) => ({ id, status, value })), + [ + { + id: "render-state", + status: "blocked", + value: "Blocked: summaryVersion", + }, + { + id: "target-page", + status: "pass", + value: "./control-page.html", + }, + { + id: "load-session-method", + status: "pass", + value: "loadControlPageSessionState", + }, + { + id: "read-status-method", + status: "pass", + value: "readControlPageStatus", + }, + { + id: "blocking-reasons", + status: "pass", + value: "none", + }, + ], +); const blockedManifest = { ...createIniPanelShellIntegrationManifest(), compatibility: { @@ -531,7 +634,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 2, launcherLinks: 2, - launchMethods: 16, + launchMethods: 17, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -692,6 +795,7 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifes assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/); assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffActionPlan\b/); +assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffChecklist\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffRenderState\b/); @@ -707,6 +811,7 @@ assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/); assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/); assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffActionPlan\b/); +assert.match(docText, /\bcreateIniPanelShellSessionHandoffChecklist\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffRenderState\b/); 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 8d3f261..df2a5a1 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 @@ -15,6 +15,7 @@ import { createIniPanelShellIntegrationSchema, createIniPanelShellIntegrationWorkflowPlan, createIniPanelShellSessionHandoffActionPlan, + createIniPanelShellSessionHandoffChecklist, createIniPanelShellSessionHandoffCompatibilityReport, createIniPanelShellSessionHandoffDisplayViewModel, createIniPanelShellSessionHandoffRenderState, @@ -75,6 +76,7 @@ assert.equal(typeof createIniPanelShellIntegrationReadiness, "function"); assert.equal(typeof createIniPanelShellIntegrationSchema, "function"); assert.equal(typeof createIniPanelShellIntegrationWorkflowPlan, "function"); assert.equal(typeof createIniPanelShellSessionHandoffActionPlan, "function"); +assert.equal(typeof createIniPanelShellSessionHandoffChecklist, "function"); assert.equal(typeof createIniPanelShellSessionHandoffCompatibilityReport, "function"); assert.equal(typeof createIniPanelShellSessionHandoffDisplayViewModel, "function"); assert.equal(typeof createIniPanelShellSessionHandoffRenderState, "function"); @@ -176,6 +178,13 @@ assert.deepEqual( renderState: shellViewModel.shellSessionHandoffRenderState, }), ); +assert.deepEqual( + shellViewModel.shellSessionHandoffChecklist, + createIniPanelShellSessionHandoffChecklist({ + actionPlan: shellViewModel.shellSessionHandoffActionPlan, + renderState: shellViewModel.shellSessionHandoffRenderState, + }), +); assert.deepEqual(shellViewModel.shellSessionHandoffDisplayViewModel, { phase: "ready", title: "Shell handoff compatibility", @@ -259,6 +268,48 @@ assert.deepEqual(shellViewModel.shellSessionHandoffActionPlan, { }, ], }); +assert.deepEqual(shellViewModel.shellSessionHandoffChecklist, { + apiName: "ini-panel-shell-session-handoff-checklist", + checklistVersion: 1, + phase: "ready", + ready: true, + statusLine: "Ready: No blocking reasons", + checks: [ + { + id: "render-state", + label: "Render state", + status: "pass", + value: "Ready: No blocking reasons", + }, + { + id: "target-page", + label: "Control target", + status: "pass", + value: "./control-page.html", + }, + { + id: "load-session-method", + label: "Load session method", + status: "pass", + value: "loadControlPageSessionState", + }, + { + id: "read-status-method", + label: "Read status method", + status: "pass", + value: "readControlPageStatus", + }, + { + id: "blocking-reasons", + label: "Blocking reasons", + status: "pass", + value: "none", + }, + ], + displayRows: shellViewModel.shellSessionHandoffActionPlan.displayRows, + nextStepIds: ["open-control-page", "read-readonly-status"], + blockingReasons: [], +}); assert.equal( isSupportedIniPanelShellIntegrationManifest(shellViewModel.shellIntegrationManifest), true, @@ -305,6 +356,7 @@ assert.equal( assert.equal(shellViewModel.createShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSnapshot); assert.equal(shellViewModel.createShellSessionHandoffRenderState, createIniPanelShellSessionHandoffRenderState); assert.equal(shellViewModel.createShellSessionHandoffActionPlan, createIniPanelShellSessionHandoffActionPlan); +assert.equal(shellViewModel.createShellSessionHandoffChecklist, createIniPanelShellSessionHandoffChecklist); assert.deepEqual(shellViewModel.controlPage.contract, createIniPanelShellControlPageContract()); assert.equal(shellViewModel.controlPage.isSupportedBrowserApiManifest, isSupportedIniPanelControlPageApiManifest); assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);