diff --git a/text12.txt b/text12.txt index 0c790f5..0595f93 100644 --- a/text12.txt +++ b/text12.txt @@ -2868,3 +2868,83 @@ host_wasm_opfs_browser_smokes=ok (例如 `mountIniPanelShellSessionHandoffFromControlPage()`),让外部 shell 可以把 control-page API 或 session-load state 传入后一次生成 mount-state、render-state 与 DOM workflow result;仍保持只读, 不新增控制按钮,不解析 G-code。 + +三十六、2026-06-15 继续执行记录:INI panel shell handoff control-page mount workflow helper + +本轮按“第一原则:加快实质性推进”继续推进 SDK/API surface 与 browser/UI workflow,为 shell +handoff mount workflow 增加 control-page/session-load 聚合 helper,让外部 shell 可以把 control-page +API 或已观察到的 session-load state 传入后,一次生成 mount-state、render-state 与 DOM workflow +result。 + +完成内容: + +- `ui-shell.js` 新增 `mountIniPanelShellSessionHandoffFromControlPage()`; +- 新 helper 支持传入 `sessionLoadState`,也支持从 `controlPageApi.loadControlPageSessionState()` + 读取只读 session readiness; +- 新 helper 返回 `apiName`、`workflowVersion`、`phase`、`ready`、`statusLine`、 + `loadSessionStateMethod`、`sessionLoadState`、`sessionLoadError`、`mountState`、 + `mountDisplayViewModel`、`mountRenderState` 与 `mountWorkflow`; +- control-page API 缺失时返回 waiting-api 派生的 blocked workflow result; +- control-page API 抛错时把错误转换为 `createControlPageSessionLoadState({ phase: "error" })`, + 不把异常直接抛给外部 shell; +- `createIniPanelShellViewModel()` 暴露 `mountShellSessionHandoffFromControlPage`; +- `createIniPanelLaunchApiManifest().methods` 新增 `mountShellSessionHandoffFromControlPage`, + launch method count 更新为 31; +- `launch.html` 的 `window.linuxCncIniPanelLaunchApi.mountShellSessionHandoffFromControlPage()` 暴露 + 真实 browser API,并默认复用 launch 侧 handoff package 与 package render-state; +- `ini_panel_shell_integration_workflow_smoke.html` 改为通过 control-page mount workflow 渲染 ready + mount-state,并校验 session-load、mount-state 与 DOM workflow result; +- Node smoke 覆盖 session-load state 直传、control-page API 读取与缺失 API blocked 路径; +- 文档同步记录 control-page mount workflow 用法; +- 未新增控制按钮; +- 未解析 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_launch_api_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_shell_integration_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_launch_api_manifest_node_smoke=ok +ini_panel_shell_integration_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。下一批建议增加 shell handoff readonly status 聚合 helper(例如 +`readIniPanelShellSessionHandoffStatusFromControlPage()`),让外部 shell 在 mount workflow ready 后一次 +读取 readonly status、校验 expected status fields,并返回 structured status result;仍保持只读,不新增 +控制按钮,不解析 G-code。 diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index 4975720..49e3a77 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -33,6 +33,7 @@ import { createIniPanelShellSessionHandoffMountDomContract, createIniPanelShellSessionHandoffMountDomReadiness, mountIniPanelShellSessionHandoff, + mountIniPanelShellSessionHandoffFromControlPage, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -240,6 +241,11 @@ that the required document and nodes exist before calling the renderer. Use `linuxCncIniPanelLaunchApi.mountShellSessionHandoff()` when an outer shell needs one browser-side workflow result containing the contract, DOM readiness, mount render-state, renderer result, and any mount error as data. Use +`mountIniPanelShellSessionHandoffFromControlPage()` or +`linuxCncIniPanelLaunchApi.mountShellSessionHandoffFromControlPage()` when an +outer shell has a control-page API or already-observed session-load state and +needs one read-only result containing the derived mount-state, mount display +view-model, mount render-state, and DOM mount workflow result. Use `renderIniPanelShellSessionHandoffMountState()` or `linuxCncIniPanelLaunchApi.renderShellSessionHandoffMountState()` when an outer shell needs the shared read-only DOM renderer for those rows. The launch page @@ -251,7 +257,7 @@ The browser workflow smoke same external shell handoff: read integration manifest, pass readiness gate, open the control page target, mount waiting and ready mount-state into an external shell-owned `[data-external-shell-mount]` DOM region through the shared -mount workflow, then read readonly machine-session status. +mount workflows, then read readonly machine-session status. The control-page refresh workflow lives in `runtime/ui/ini-panel/control-page-refresh-workflow.js`. Use diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index 5bce42a..165562e 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -109,6 +109,7 @@ createIniPanelShellSessionHandoffMountDomContract, createIniPanelShellSessionHandoffMountDomReadiness, mountIniPanelShellSessionHandoff, + mountIniPanelShellSessionHandoffFromControlPage, renderIniPanelShellSessionHandoffMountState, } from "./ui-shell.js"; @@ -198,6 +199,14 @@ documentRef: document, }) ), + mountShellSessionHandoffFromControlPage: (options) => ( + mountIniPanelShellSessionHandoffFromControlPage({ + handoffPackage: shellViewModel.shellSessionHandoffPackage, + packageRenderState: shellViewModel.shellSessionHandoffPackageRenderState, + documentRef: document, + ...(options ?? {}), + }) + ), 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 3958980..72f741d 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -147,6 +147,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "getShellSessionHandoffMountDomReadiness", "renderShellSessionHandoffMountState", "mountShellSessionHandoff", + "mountShellSessionHandoffFromControlPage", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -1263,6 +1264,70 @@ export function mountIniPanelShellSessionHandoff({ } } +export function mountIniPanelShellSessionHandoffFromControlPage({ + controlPageApi = null, + sessionLoadState = null, + loadSessionStateMethod = "loadControlPageSessionState", + handoffPackage = createIniPanelShellSessionHandoffPackage(), + packageRenderState = createIniPanelShellSessionHandoffPackageRenderState(), + rowDatasetPrefix = "handoffMount", + contract = createIniPanelShellSessionHandoffMountDomContract({ rowDatasetPrefix }), + documentRef = globalThis.document, + mountNode = documentRef?.querySelector?.(contract.selectors.mount), + statusNode = documentRef?.querySelector?.(contract.selectors.status), + rowsNode = documentRef?.querySelector?.(contract.selectors.rows), +} = {}) { + let observedSessionLoadState = sessionLoadState; + let sessionLoadError = null; + if (!observedSessionLoadState) { + const loadSessionState = controlPageApi?.[loadSessionStateMethod]; + if (typeof loadSessionState === "function") { + try { + observedSessionLoadState = loadSessionState.call(controlPageApi); + } catch (error) { + sessionLoadError = error?.message ?? String(error); + observedSessionLoadState = createControlPageSessionLoadState({ + phase: "error", + error: sessionLoadError, + }); + } + } else { + observedSessionLoadState = createControlPageSessionLoadState({ phase: "waiting-api" }); + } + } + + const mountState = createIniPanelShellSessionHandoffPackageMountState({ + handoffPackage, + packageRenderState, + sessionLoadState: observedSessionLoadState, + }); + const mountDisplayViewModel = createIniPanelShellSessionHandoffPackageMountDisplayViewModel(mountState); + const mountRenderState = createIniPanelShellSessionHandoffPackageMountRenderState(mountDisplayViewModel); + const mountWorkflow = mountIniPanelShellSessionHandoff({ + renderState: mountRenderState, + contract, + documentRef, + mountNode, + statusNode, + rowsNode, + }); + + return { + apiName: "ini-panel-shell-session-handoff-control-page-mount-workflow", + workflowVersion: 1, + phase: mountWorkflow.phase, + ready: mountWorkflow.ready, + statusLine: mountWorkflow.statusLine, + loadSessionStateMethod, + sessionLoadState: observedSessionLoadState, + sessionLoadError, + mountState, + mountDisplayViewModel, + mountRenderState, + mountWorkflow, + }; +} + export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) { const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries); const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest); @@ -1381,6 +1446,7 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries createShellSessionHandoffMountDomReadiness: createIniPanelShellSessionHandoffMountDomReadiness, renderShellSessionHandoffMountState: renderIniPanelShellSessionHandoffMountState, mountShellSessionHandoff: mountIniPanelShellSessionHandoff, + mountShellSessionHandoffFromControlPage: mountIniPanelShellSessionHandoffFromControlPage, isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage, controlPage: { browserApiSchema: createControlPageBrowserApiSchema(), 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 16f7eee..47c27b0 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 @@ -89,6 +89,7 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.getShellSessionHandoffMountDomReadiness || !launchApi?.renderShellSessionHandoffMountState || !launchApi?.mountShellSessionHandoff || + !launchApi?.mountShellSessionHandoffFromControlPage || !launchApi?.isSupportedShellSessionHandoffPackage ) { throw new Error("launch API namespace did not expose shell integration helpers"); @@ -287,21 +288,24 @@ TOOL_TABLE = browser-shell-tool.tbl "ready", "shell integration control-page session readiness", ); - const readyMountState = launchApi.getShellSessionHandoffPackageMountState( - controlPageApi[handoffSummary.handoffMethods.loadSessionState](), - ); + const readySessionLoadState = controlPageApi[handoffSummary.handoffMethods.loadSessionState](); + const readyMountState = launchApi.getShellSessionHandoffPackageMountState(readySessionLoadState); const readyMountDisplay = launchApi.getShellSessionHandoffPackageMountDisplayViewModel(readyMountState); const readyMountRenderState = launchApi.getShellSessionHandoffPackageMountRenderState(readyMountState); - const readyMountWorkflow = launchApi.mountShellSessionHandoff({ - renderState: readyMountRenderState, + const readyControlPageMountWorkflow = launchApi.mountShellSessionHandoffFromControlPage({ + sessionLoadState: readySessionLoadState, contract: externalMountDomContract, documentRef: document, }); + const readyMountWorkflow = readyControlPageMountWorkflow.mountWorkflow; const readyMountRenderResult = readyMountWorkflow.renderResult; 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(readyControlPageMountWorkflow.phase, "ready", "external shell control-page mount workflow phase"); + assertEqual(readyControlPageMountWorkflow.sessionLoadState.phase, "ready", "external shell control-page mount workflow session"); + assertEqual(readyControlPageMountWorkflow.mountState.ready, true, "external shell control-page mount workflow state"); assertEqual(readyMountRenderResult.rendered, true, "external shell ready mount render result"); assertEqual(readyMountWorkflow.phase, "ready", "external shell ready mount workflow phase"); assertEqual(readyMountRenderResult.dataset.handoffReady, "true", "external shell ready mount render dataset"); 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 f48c860..3b0c6f9 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 @@ -30,6 +30,7 @@ import { createIniPanelShellSessionHandoffMountDomContract, createIniPanelShellSessionHandoffMountDomReadiness, mountIniPanelShellSessionHandoff, + mountIniPanelShellSessionHandoffFromControlPage, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -99,6 +100,7 @@ const requiredShellExports = [ "createIniPanelShellSessionHandoffMountDomContract", "createIniPanelShellSessionHandoffMountDomReadiness", "mountIniPanelShellSessionHandoff", + "mountIniPanelShellSessionHandoffFromControlPage", "renderIniPanelShellSessionHandoffMountState", "createIniPanelShellSessionHandoffPackageReport", "createIniPanelShellSessionHandoffPackageRenderState", @@ -297,6 +299,10 @@ assert.equal( mountIniPanelShellSessionHandoff({ documentRef: null }).phase, "blocked", ); +assert.equal( + mountIniPanelShellSessionHandoffFromControlPage({ documentRef: null }).mountWorkflow.phase, + "blocked", +); assert.equal(isSupportedIniPanelShellSessionHandoffPackage(createIniPanelShellViewModel().shellSessionHandoffPackage), true); assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true); assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema()); @@ -457,6 +463,7 @@ assert.match(docText, /\blinuxCncIniPanelLaunchApi\.renderShellSessionHandoffMou assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffMountDomContract\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffMountDomReadiness\b/); assert.match(docText, /\blinuxCncIniPanelLaunchApi\.mountShellSessionHandoff\b/); +assert.match(docText, /\blinuxCncIniPanelLaunchApi\.mountShellSessionHandoffFromControlPage\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/); @@ -476,6 +483,7 @@ assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffPackage assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffMountDomContract\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffMountDomReadiness\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bmountShellSessionHandoff\b/); +assert.match(shellIntegrationWorkflowSmokeText, /\bmountShellSessionHandoffFromControlPage\b/); assert.match(shellIntegrationWorkflowSmokeText, /\brenderShellSessionHandoffMountState\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-shell-mount\b/); assert.match(shellIntegrationWorkflowSmokeText, /\bdata-external-mount-value\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 378c474..728c438 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 @@ -67,6 +67,7 @@ assert.deepEqual(manifest, { "getShellSessionHandoffMountDomReadiness", "renderShellSessionHandoffMountState", "mountShellSessionHandoff", + "mountShellSessionHandoffFromControlPage", "isSupportedShellSessionHandoffPackage", "getLauncherLinks", "getControlPageApiMethods", @@ -189,6 +190,7 @@ assert.match(launchText, /\bgetShellSessionHandoffMountDomContract\b/); assert.match(launchText, /\bgetShellSessionHandoffMountDomReadiness\b/); assert.match(launchText, /\brenderShellSessionHandoffMountState\b/); assert.match(launchText, /\bmountShellSessionHandoff\b/); +assert.match(launchText, /\bmountShellSessionHandoffFromControlPage\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 904edfc..99ac953 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 @@ -26,6 +26,7 @@ import { createIniPanelShellSessionHandoffMountDomContract, createIniPanelShellSessionHandoffMountDomReadiness, mountIniPanelShellSessionHandoff, + mountIniPanelShellSessionHandoffFromControlPage, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, createIniPanelShellSessionHandoffPackageSchema, @@ -152,7 +153,7 @@ assert.deepEqual(readiness, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 30, + launchMethods: 31, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -214,7 +215,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 2, launcherLinks: 2, - launchMethods: 30, + launchMethods: 31, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -706,6 +707,10 @@ assert.equal( mountIniPanelShellSessionHandoff({ documentRef: null }).statusLine, "Blocked: document, mount, status, rows", ); +assert.equal( + mountIniPanelShellSessionHandoffFromControlPage({ documentRef: null }).sessionLoadState.phase, + "waiting-api", +); assert.deepEqual( createIniPanelShellSessionHandoffPackageMountState({ handoffPackage, @@ -1117,7 +1122,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 2, launcherLinks: 2, - launchMethods: 30, + launchMethods: 31, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -1289,6 +1294,7 @@ assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPack assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffMountDomContract\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffMountDomReadiness\b/); assert.match(shellText, /\bexport function mountIniPanelShellSessionHandoff\b/); +assert.match(shellText, /\bexport function mountIniPanelShellSessionHandoffFromControlPage\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageReport\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageRenderState\b/); assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageSchema\b/); @@ -1317,6 +1323,7 @@ assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageMountState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffMountDomContract\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffMountDomReadiness\b/); assert.match(docText, /\bmountIniPanelShellSessionHandoff\b/); +assert.match(docText, /\bmountIniPanelShellSessionHandoffFromControlPage\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageReport\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageRenderState\b/); assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageSchema\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 b18d814..49664f1 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 @@ -26,6 +26,7 @@ import { createIniPanelShellSessionHandoffMountDomContract, createIniPanelShellSessionHandoffMountDomReadiness, mountIniPanelShellSessionHandoff, + mountIniPanelShellSessionHandoffFromControlPage, renderIniPanelShellSessionHandoffMountState, createIniPanelShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageRenderState, @@ -100,6 +101,7 @@ assert.equal(typeof createIniPanelShellSessionHandoffPackageMountState, "functio assert.equal(typeof createIniPanelShellSessionHandoffMountDomContract, "function"); assert.equal(typeof createIniPanelShellSessionHandoffMountDomReadiness, "function"); assert.equal(typeof mountIniPanelShellSessionHandoff, "function"); +assert.equal(typeof mountIniPanelShellSessionHandoffFromControlPage, "function"); assert.equal(typeof renderIniPanelShellSessionHandoffMountState, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageReport, "function"); assert.equal(typeof createIniPanelShellSessionHandoffPackageRenderState, "function"); @@ -702,6 +704,10 @@ assert.equal( renderIniPanelShellSessionHandoffMountState, ); assert.equal(shellViewModel.mountShellSessionHandoff, mountIniPanelShellSessionHandoff); +assert.equal( + shellViewModel.mountShellSessionHandoffFromControlPage, + mountIniPanelShellSessionHandoffFromControlPage, +); assert.equal(shellViewModel.createShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageReport); assert.equal(shellViewModel.createShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema); assert.equal(shellViewModel.isSupportedShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffPackage); @@ -840,6 +846,43 @@ assert.equal(mountWorkflowResult.domReadiness.ready, true); assert.equal(mountWorkflowResult.renderResult.rendered, true); assert.equal(mountWorkflowResult.renderResult.rowCount, 5); assert.equal(mountWorkflowResult.error, null); +const controlPageMountWorkflow = mountIniPanelShellSessionHandoffFromControlPage({ + handoffPackage: shellViewModel.shellSessionHandoffPackage, + packageRenderState: shellViewModel.shellSessionHandoffPackageRenderState, + sessionLoadState: createControlPageSessionLoadState({ + phase: "ready", + panelReady: true, + apiReady: true, + controlViewReady: true, + controlView: { status: { runStatus: "not-run" } }, + }), + documentRef: mountDocument, + mountNode, + statusNode: mountStatusNode, + rowsNode: mountRowsNode, +}); +assert.equal(controlPageMountWorkflow.apiName, "ini-panel-shell-session-handoff-control-page-mount-workflow"); +assert.equal(controlPageMountWorkflow.workflowVersion, 1); +assert.equal(controlPageMountWorkflow.phase, "ready"); +assert.equal(controlPageMountWorkflow.ready, true); +assert.equal(controlPageMountWorkflow.sessionLoadState.phase, "ready"); +assert.equal(controlPageMountWorkflow.mountState.ready, true); +assert.equal(controlPageMountWorkflow.mountRenderState.ready, true); +assert.equal(controlPageMountWorkflow.mountWorkflow.renderResult.dataset.handoffReady, "true"); +assert.equal(controlPageMountWorkflow.sessionLoadError, null); +const controlPageApiMountWorkflow = mountIniPanelShellSessionHandoffFromControlPage({ + handoffPackage: shellViewModel.shellSessionHandoffPackage, + packageRenderState: shellViewModel.shellSessionHandoffPackageRenderState, + controlPageApi: { + loadControlPageSessionState: () => createControlPageSessionLoadState({ phase: "waiting-session" }), + }, + documentRef: mountDocument, + mountNode, + statusNode: mountStatusNode, + rowsNode: mountRowsNode, +}); +assert.equal(controlPageApiMountWorkflow.phase, "blocked"); +assert.equal(controlPageApiMountWorkflow.sessionLoadState.phase, "waiting-session"); assert.deepEqual( mountIniPanelShellSessionHandoff({ documentRef: mountDocument }).renderResult, null,