推进 INI 面板 shell handoff snapshot API

This commit is contained in:
2026-06-15 09:42:43 +08:00
parent 01817f6493
commit 5c951ab9bc
11 changed files with 1272 additions and 10 deletions

View File

@@ -21,7 +21,11 @@ import {
createIniPanelShellIntegrationReadiness,
createIniPanelShellIntegrationSchema,
createIniPanelShellIntegrationWorkflowPlan,
createIniPanelShellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSummary,
createIniPanelShellSessionHandoffSummarySchema,
createIniPanelShellViewModel,
getIniPanelEntryByHref,
getVisibleIniPanelEntries,
@@ -37,6 +41,7 @@ import {
isSupportedIniPanelControlPageApiManifest,
isSupportedIniPanelLaunchApiManifest,
isSupportedIniPanelShellIntegrationManifest,
isSupportedIniPanelShellSessionHandoffSummary,
} from "../runtime/ui/ini-panel/ui-shell.js";
```
@@ -135,6 +140,25 @@ read-only display summary of readiness, target page, persistence capabilities,
readonly status fields, handoff methods, and blocking reasons. Browser shells
can read the same summary through
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSummary()`.
Use `createIniPanelShellSessionHandoffSummarySchema()` or
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSummarySchema()` for the
versioned summary shape, and `isSupportedIniPanelShellSessionHandoffSummary()`
or `linuxCncIniPanelLaunchApi.isSupportedShellSessionHandoffSummary()` before
consuming a summary from a browser shell.
Use `createIniPanelShellSessionHandoffCompatibilityReport()` or
`linuxCncIniPanelLaunchApi.getShellSessionHandoffCompatibilityReport()` when an
outer shell needs display-ready diagnostics for schema support, missing fields,
api/version mismatches, and current blocking reasons before consuming the
handoff summary.
Use `createIniPanelShellSessionHandoffDisplayViewModel()` or
`linuxCncIniPanelLaunchApi.getShellSessionHandoffDisplayViewModel()` when an
outer shell needs the same diagnostics as stable read-only label/value rows for
DOM display. The launch page renders those rows in `[data-handoff-status]` and
`[data-handoff-rows]` without adding control actions.
Use `createIniPanelShellSessionHandoffSnapshot()` or
`linuxCncIniPanelLaunchApi.getShellSessionHandoffSnapshot()` when an outer shell
needs one read-only API read that includes readiness, handoff summary,
compatibility report, and display view-model together.
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,

View File

@@ -46,6 +46,27 @@
display: grid;
gap: 8px;
}
.handoff-status {
border-top: 1px solid var(--border);
padding-top: 12px;
display: grid;
gap: 8px;
}
.handoff-status dl {
margin: 0;
display: grid;
grid-template-columns: minmax(120px, 180px) 1fr;
gap: 6px 12px;
font: 13px/1.4 "Segoe UI", "Noto Sans", sans-serif;
}
.handoff-status dt {
color: var(--muted);
}
.handoff-status dd {
margin: 0;
color: var(--text);
overflow-wrap: anywhere;
}
a {
color: var(--accent);
text-decoration: none;
@@ -70,6 +91,10 @@
<a data-entry-id="edit-run" href="./index.html">Open edit and run panel</a>
<a data-entry-id="control-view" href="./control-page.html">Open read-only control view</a>
</div>
<section class="handoff-status" aria-label="Shell handoff compatibility">
<p data-handoff-status>Checking shell handoff compatibility.</p>
<dl data-handoff-rows></dl>
</section>
</section>
</main>
<script type="module">
@@ -89,6 +114,18 @@
link.textContent = linkModel.label;
link.href = linkModel.href;
}
const handoffDisplay = shellViewModel.shellSessionHandoffDisplayViewModel;
document.querySelector("[data-handoff-status]").textContent = `${handoffDisplay.statusText}: ${handoffDisplay.detailText}`;
const handoffRows = document.querySelector("[data-handoff-rows]");
for (const row of handoffDisplay.rows) {
const term = document.createElement("dt");
term.dataset.handoffRow = row.id;
term.textContent = row.label;
const detail = document.createElement("dd");
detail.dataset.handoffValue = row.id;
detail.textContent = row.value;
handoffRows.append(term, detail);
}
window.linuxCncIniPanelLaunchApi = {
isSupportedLaunchApiManifest: isSupportedIniPanelLaunchApiManifest,
@@ -97,7 +134,12 @@
getShellIntegrationSchema: () => shellViewModel.shellIntegrationSchema,
getShellIntegrationManifest: () => shellViewModel.shellIntegrationManifest,
getShellIntegrationReadiness: () => shellViewModel.shellIntegrationReadiness,
getShellSessionHandoffSummarySchema: () => shellViewModel.shellSessionHandoffSummarySchema,
getShellSessionHandoffSummary: () => shellViewModel.shellSessionHandoffSummary,
isSupportedShellSessionHandoffSummary: shellViewModel.isSupportedShellSessionHandoffSummary,
getShellSessionHandoffCompatibilityReport: () => shellViewModel.shellSessionHandoffCompatibilityReport,
getShellSessionHandoffDisplayViewModel: () => shellViewModel.shellSessionHandoffDisplayViewModel,
getShellSessionHandoffSnapshot: () => shellViewModel.shellSessionHandoffSnapshot,
getLauncherLinks: () => shellViewModel.launcherLinks,
getControlPageApiMethods: () => shellViewModel.controlPage.browserApiMethods,
};

View File

@@ -126,7 +126,12 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr
"getShellIntegrationSchema",
"getShellIntegrationManifest",
"getShellIntegrationReadiness",
"getShellSessionHandoffSummarySchema",
"getShellSessionHandoffSummary",
"isSupportedShellSessionHandoffSummary",
"getShellSessionHandoffCompatibilityReport",
"getShellSessionHandoffDisplayViewModel",
"getShellSessionHandoffSnapshot",
"getLauncherLinks",
"getControlPageApiMethods",
],
@@ -381,11 +386,44 @@ export function createIniPanelShellIntegrationWorkflowPlan({
};
}
export function createIniPanelShellSessionHandoffSummarySchema() {
return {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 1,
fields: [
"apiName",
"summaryVersion",
"phase",
"ready",
"targetPage",
"readiness",
"persistenceCapabilities",
"readonlyStatusFields",
"handoffMethods",
"blockingReasons",
],
};
}
export function isSupportedIniPanelShellSessionHandoffSummary(
summary,
schema = createIniPanelShellSessionHandoffSummarySchema(),
) {
if (!summary || typeof summary !== "object") {
return false;
}
if (summary.apiName !== schema.apiName || summary.summaryVersion !== schema.summaryVersion) {
return false;
}
return schema.fields.every((fieldName) => Object.hasOwn(summary, fieldName));
}
export function createIniPanelShellSessionHandoffSummary({
manifest = createIniPanelShellIntegrationManifest(),
readiness = createIniPanelShellIntegrationReadiness(manifest),
workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness }),
} = {}) {
const schema = createIniPanelShellSessionHandoffSummarySchema();
const persistenceCapabilities = Array.isArray(manifest?.persistenceCapabilities)
? manifest.persistenceCapabilities.map(({ id, label, scope }) => ({ id, label, scope }))
: [];
@@ -393,6 +431,8 @@ export function createIniPanelShellSessionHandoffSummary({
? [...workflowPlan.readonlyStatusHandoff.expectedStatusFields]
: [];
return {
apiName: schema.apiName,
summaryVersion: schema.summaryVersion,
phase: workflowPlan.ready ? "ready" : "blocked",
ready: Boolean(workflowPlan.ready),
targetPage: workflowPlan.targetPage,
@@ -412,6 +452,107 @@ export function createIniPanelShellSessionHandoffSummary({
};
}
export function createIniPanelShellSessionHandoffCompatibilityReport(
summary = createIniPanelShellSessionHandoffSummary(),
schema = createIniPanelShellSessionHandoffSummarySchema(),
) {
const summaryObject = summary && typeof summary === "object" ? summary : {};
const missingFields = schema.fields.filter((fieldName) => !Object.hasOwn(summaryObject, fieldName));
const mismatchFields = [
...(summaryObject.apiName === schema.apiName ? [] : ["apiName"]),
...(summaryObject.summaryVersion === schema.summaryVersion ? [] : ["summaryVersion"]),
];
const summarySupported = missingFields.length === 0 && mismatchFields.length === 0;
const blockingReasons = Array.isArray(summaryObject.blockingReasons)
? [...summaryObject.blockingReasons]
: [];
const handoffReady = summarySupported && summaryObject.ready === true && blockingReasons.length === 0;
return {
apiName: "ini-panel-shell-session-handoff-compatibility-report",
reportVersion: 1,
phase: handoffReady ? "ready" : "blocked",
compatible: handoffReady,
summarySupported,
handoffReady,
schema: {
apiName: schema.apiName,
summaryVersion: schema.summaryVersion,
fields: [...schema.fields],
},
summary: {
apiName: summaryObject.apiName ?? null,
summaryVersion: summaryObject.summaryVersion ?? null,
phase: summaryObject.phase ?? null,
ready: summaryObject.ready ?? false,
},
missingFields,
mismatchFields,
blockingReasons,
};
}
export function createIniPanelShellSessionHandoffDisplayViewModel(
report = createIniPanelShellSessionHandoffCompatibilityReport(),
) {
const missingFields = Array.isArray(report?.missingFields) ? report.missingFields : [];
const mismatchFields = Array.isArray(report?.mismatchFields) ? report.mismatchFields : [];
const blockingReasons = Array.isArray(report?.blockingReasons) ? report.blockingReasons : [];
const problems = [...missingFields, ...mismatchFields, ...blockingReasons];
return {
phase: report?.phase === "ready" ? "ready" : "blocked",
title: "Shell handoff compatibility",
statusText: report?.compatible ? "Ready" : "Blocked",
detailText: problems.length === 0 ? "No blocking reasons" : problems.join(", "),
rows: [
{
id: "summary-supported",
label: "Summary schema",
value: report?.summarySupported ? "supported" : "blocked",
},
{
id: "handoff-ready",
label: "Handoff readiness",
value: report?.handoffReady ? "ready" : "blocked",
},
{
id: "missing-fields",
label: "Missing fields",
value: missingFields.length === 0 ? "none" : missingFields.join(", "),
},
{
id: "mismatch-fields",
label: "Mismatched fields",
value: mismatchFields.length === 0 ? "none" : mismatchFields.join(", "),
},
{
id: "blocking-reasons",
label: "Blocking reasons",
value: blockingReasons.length === 0 ? "none" : blockingReasons.join(", "),
},
],
};
}
export function createIniPanelShellSessionHandoffSnapshot({
readiness = createIniPanelShellIntegrationReadiness(),
summary = createIniPanelShellSessionHandoffSummary(),
compatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(summary),
displayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(compatibilityReport),
} = {}) {
return {
apiName: "ini-panel-shell-session-handoff-snapshot",
snapshotVersion: 1,
phase: compatibilityReport.phase,
ready: Boolean(compatibilityReport.compatible),
readiness,
summary,
compatibilityReport,
displayViewModel,
};
}
export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) {
const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries);
const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest);
@@ -419,6 +560,23 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
manifest: shellIntegrationManifest,
readiness: shellIntegrationReadiness,
});
const shellSessionHandoffSummary = createIniPanelShellSessionHandoffSummary({
manifest: shellIntegrationManifest,
readiness: shellIntegrationReadiness,
workflowPlan: shellIntegrationWorkflowPlan,
});
const shellSessionHandoffCompatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(
shellSessionHandoffSummary,
);
const shellSessionHandoffDisplayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(
shellSessionHandoffCompatibilityReport,
);
const shellSessionHandoffSnapshot = createIniPanelShellSessionHandoffSnapshot({
readiness: shellIntegrationReadiness,
summary: shellSessionHandoffSummary,
compatibilityReport: shellSessionHandoffCompatibilityReport,
displayViewModel: shellSessionHandoffDisplayViewModel,
});
return {
pages: entries.map(({ id, href, title }) => ({
id,
@@ -430,17 +588,22 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
shellIntegrationManifest,
shellIntegrationReadiness,
shellIntegrationWorkflowPlan,
shellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary({
manifest: shellIntegrationManifest,
readiness: shellIntegrationReadiness,
workflowPlan: shellIntegrationWorkflowPlan,
}),
shellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema(),
shellSessionHandoffSummary,
shellSessionHandoffCompatibilityReport,
shellSessionHandoffDisplayViewModel,
shellSessionHandoffSnapshot,
launchApiSchema: createIniPanelLaunchApiSchema(),
launchApiManifest: createIniPanelLaunchApiManifest(entries),
isSupportedShellIntegrationManifest: isSupportedIniPanelShellIntegrationManifest,
createShellIntegrationReadiness: createIniPanelShellIntegrationReadiness,
createShellIntegrationWorkflowPlan: createIniPanelShellIntegrationWorkflowPlan,
isSupportedShellSessionHandoffSummary: isSupportedIniPanelShellSessionHandoffSummary,
createShellSessionHandoffSummarySchema: createIniPanelShellSessionHandoffSummarySchema,
createShellSessionHandoffSummary: createIniPanelShellSessionHandoffSummary,
createShellSessionHandoffCompatibilityReport: createIniPanelShellSessionHandoffCompatibilityReport,
createShellSessionHandoffDisplayViewModel: createIniPanelShellSessionHandoffDisplayViewModel,
createShellSessionHandoffSnapshot: createIniPanelShellSessionHandoffSnapshot,
controlPage: {
browserApiSchema: createControlPageBrowserApiSchema(),
browserApiManifest: createControlPageBrowserApiManifest(),

View File

@@ -73,7 +73,12 @@
!launchApi?.getShellIntegrationSchema ||
!launchApi?.getShellIntegrationManifest ||
!launchApi?.getShellIntegrationReadiness ||
!launchApi?.getShellSessionHandoffSummarySchema ||
!launchApi?.getShellSessionHandoffSummary ||
!launchApi?.isSupportedShellSessionHandoffSummary ||
!launchApi?.getShellSessionHandoffCompatibilityReport ||
!launchApi?.getShellSessionHandoffDisplayViewModel ||
!launchApi?.getShellSessionHandoffSnapshot ||
!launchApi?.getLauncherLinks ||
!launchApi?.getControlPageApiMethods
) {
@@ -113,13 +118,17 @@
);
assertEqual(
launchApiManifest.methods.join(","),
"isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummary,getLauncherLinks,getControlPageApiMethods",
"isSupportedLaunchApiManifest,getLaunchApiSchema,getLaunchApiManifest,getShellIntegrationSchema,getShellIntegrationManifest,getShellIntegrationReadiness,getShellSessionHandoffSummarySchema,getShellSessionHandoffSummary,isSupportedShellSessionHandoffSummary,getShellSessionHandoffCompatibilityReport,getShellSessionHandoffDisplayViewModel,getShellSessionHandoffSnapshot,getLauncherLinks,getControlPageApiMethods",
"launch API manifest methods",
);
const shellIntegrationSchema = launchApi.getShellIntegrationSchema();
const shellIntegrationManifest = launchApi.getShellIntegrationManifest();
const shellIntegrationReadiness = launchApi.getShellIntegrationReadiness();
const shellSessionHandoffSummarySchema = launchApi.getShellSessionHandoffSummarySchema();
const shellSessionHandoffSummary = launchApi.getShellSessionHandoffSummary();
const shellSessionHandoffCompatibilityReport = launchApi.getShellSessionHandoffCompatibilityReport();
const shellSessionHandoffDisplayViewModel = launchApi.getShellSessionHandoffDisplayViewModel();
const shellSessionHandoffSnapshot = launchApi.getShellSessionHandoffSnapshot();
assertEqual(
shellIntegrationSchema.manifestVersion,
1,
@@ -165,6 +174,86 @@
true,
"shell session handoff summary readiness",
);
assertEqual(
shellSessionHandoffSummarySchema.summaryVersion,
1,
"shell session handoff summary schema version",
);
assertEqual(
launchApi.isSupportedShellSessionHandoffSummary(shellSessionHandoffSummary),
true,
"shell session handoff summary supported",
);
assertEqual(
launchApi.isSupportedShellSessionHandoffSummary({ ...shellSessionHandoffSummary, summaryVersion: 2 }),
false,
"shell session handoff summary rejects version",
);
assertEqual(
shellSessionHandoffCompatibilityReport.compatible,
true,
"shell session handoff compatibility report",
);
assertEqual(
shellSessionHandoffCompatibilityReport.summarySupported,
true,
"shell session handoff summary support report",
);
assertEqual(
shellSessionHandoffCompatibilityReport.missingFields.join(","),
"",
"shell session handoff compatibility missing fields",
);
assertEqual(
shellSessionHandoffDisplayViewModel.statusText,
"Ready",
"shell session handoff display status",
);
assertEqual(
shellSessionHandoffDisplayViewModel.rows.length,
5,
"shell session handoff display rows",
);
assertEqual(
shellSessionHandoffSnapshot.snapshotVersion,
1,
"shell session handoff snapshot version",
);
assertEqual(
shellSessionHandoffSnapshot.ready,
true,
"shell session handoff snapshot readiness",
);
assertEqual(
JSON.stringify(shellSessionHandoffSnapshot.readiness),
JSON.stringify(shellIntegrationReadiness),
"shell session handoff snapshot readiness object",
);
assertEqual(
JSON.stringify(shellSessionHandoffSnapshot.summary),
JSON.stringify(shellSessionHandoffSummary),
"shell session handoff snapshot summary object",
);
assertEqual(
JSON.stringify(shellSessionHandoffSnapshot.displayViewModel),
JSON.stringify(shellSessionHandoffDisplayViewModel),
"shell session handoff snapshot display object",
);
assertEqual(
launchDoc.querySelector("[data-handoff-status]").textContent,
"Ready: No blocking reasons",
"shell session handoff DOM status",
);
assertEqual(
launchDoc.querySelector('[data-handoff-value="missing-fields"]').textContent,
"none",
"shell session handoff DOM missing fields",
);
assertEqual(
launchDoc.querySelector('[data-handoff-value="blocking-reasons"]').textContent,
"none",
"shell session handoff DOM blocking reasons",
);
assertEqual(
shellSessionHandoffSummary.targetPage.href,
"./control-page.html",

View File

@@ -64,14 +64,36 @@ TOOL_TABLE = browser-shell-tool.tbl
if (
!launchApi?.getShellIntegrationManifest ||
!launchApi?.getShellIntegrationReadiness ||
!launchApi?.getShellSessionHandoffSummary
!launchApi?.getShellSessionHandoffSummarySchema ||
!launchApi?.getShellSessionHandoffSummary ||
!launchApi?.isSupportedShellSessionHandoffSummary ||
!launchApi?.getShellSessionHandoffCompatibilityReport ||
!launchApi?.getShellSessionHandoffDisplayViewModel ||
!launchApi?.getShellSessionHandoffSnapshot
) {
throw new Error("launch API namespace did not expose shell integration helpers");
}
const integrationManifest = launchApi.getShellIntegrationManifest();
const readiness = launchApi.getShellIntegrationReadiness();
const handoffSummarySchema = launchApi.getShellSessionHandoffSummarySchema();
const handoffSummary = launchApi.getShellSessionHandoffSummary();
const compatibilityReport = launchApi.getShellSessionHandoffCompatibilityReport();
const handoffDisplay = launchApi.getShellSessionHandoffDisplayViewModel();
const handoffSnapshot = launchApi.getShellSessionHandoffSnapshot();
assertEqual(handoffSummarySchema.summaryVersion, 1, "shell handoff summary schema version");
assertEqual(
launchApi.isSupportedShellSessionHandoffSummary(handoffSummary),
true,
"shell handoff summary supported",
);
assertEqual(compatibilityReport.compatible, true, "shell handoff compatibility report");
assertEqual(compatibilityReport.summarySupported, true, "shell handoff summary report support");
assertEqual(compatibilityReport.blockingReasons.join(","), "", "shell handoff report blocking reasons");
assertEqual(handoffDisplay.statusText, "Ready", "shell handoff display status");
assertEqual(handoffDisplay.detailText, "No blocking reasons", "shell handoff display detail");
assertEqual(handoffSnapshot.ready, true, "shell handoff snapshot readiness");
assertEqual(handoffSnapshot.displayViewModel.statusText, "Ready", "shell handoff snapshot display status");
assertEqual(readiness.phase, "ready", "shell integration readiness phase");
assertEqual(readiness.ready, true, "shell integration readiness");
assertEqual(readiness.missing.join(","), "", "shell integration readiness missing checks");

View File

@@ -18,7 +18,11 @@ import {
createIniPanelShellIntegrationReadiness,
createIniPanelShellIntegrationSchema,
createIniPanelShellIntegrationWorkflowPlan,
createIniPanelShellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSummary,
createIniPanelShellSessionHandoffSummarySchema,
createIniPanelShellViewModel,
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
@@ -29,6 +33,7 @@ import {
isSupportedIniPanelControlPageApiManifest,
isSupportedIniPanelLaunchApiManifest,
isSupportedIniPanelShellIntegrationManifest,
isSupportedIniPanelShellSessionHandoffSummary,
} from "../../../runtime/ui/ini-panel/ui-shell.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -66,13 +71,18 @@ const requiredShellExports = [
"createIniPanelShellIntegrationReadiness",
"createIniPanelShellIntegrationSchema",
"createIniPanelShellIntegrationWorkflowPlan",
"createIniPanelShellSessionHandoffCompatibilityReport",
"createIniPanelShellSessionHandoffDisplayViewModel",
"createIniPanelShellSessionHandoffSnapshot",
"createIniPanelShellSessionHandoffSummary",
"createIniPanelShellSessionHandoffSummarySchema",
"createIniPanelShellViewModel",
"getIniPanelEntryByHref",
"getVisibleIniPanelEntries",
"isSupportedIniPanelControlPageApiManifest",
"isSupportedIniPanelLaunchApiManifest",
"isSupportedIniPanelShellIntegrationManifest",
"isSupportedIniPanelShellSessionHandoffSummary",
"createMachineSessionControlPageController",
"createMachineSessionReadonlyStatus",
"createMachineSessionReadonlyStatusApiManifest",
@@ -152,6 +162,28 @@ assert.deepEqual(
workflowPlan: createIniPanelShellViewModel().shellIntegrationWorkflowPlan,
}),
);
assert.deepEqual(
createIniPanelShellViewModel().shellSessionHandoffSummarySchema,
createIniPanelShellSessionHandoffSummarySchema(),
);
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(createIniPanelShellViewModel().shellSessionHandoffSummary), true);
assert.deepEqual(
createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellViewModel().shellSessionHandoffSummary),
);
assert.deepEqual(
createIniPanelShellViewModel().shellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffDisplayViewModel(createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport),
);
assert.deepEqual(
createIniPanelShellViewModel().shellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSnapshot({
readiness: createIniPanelShellViewModel().shellIntegrationReadiness,
summary: createIniPanelShellViewModel().shellSessionHandoffSummary,
compatibilityReport: createIniPanelShellViewModel().shellSessionHandoffCompatibilityReport,
displayViewModel: createIniPanelShellViewModel().shellSessionHandoffDisplayViewModel,
}),
);
assert.equal(isSupportedIniPanelShellIntegrationManifest(createIniPanelShellViewModel().shellIntegrationManifest), true);
assert.deepEqual(createIniPanelShellViewModel().launchApiSchema, createIniPanelLaunchApiSchema());
assert.deepEqual(createIniPanelShellViewModel().launchApiManifest, createIniPanelLaunchApiManifest());
@@ -206,10 +238,15 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationSchema\
assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifest\b/);
assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/);
assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSnapshot\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummary\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummarySchema\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelControlPageApiManifest\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelLaunchApiManifest\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelShellSessionHandoffSummary\b/);
assert.match(controlPageText, /\bisSupportedControlPageApiManifest\b/);
assert.match(controlPageText, /\bgetControlPageApiSchema\b/);
assert.match(controlPageText, /\bgetControlPageApiManifest\b/);
@@ -221,7 +258,14 @@ assert.match(launchText, /\bgetLaunchApiManifest\b/);
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummarySchema\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummary\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffSummary\b/);
assert.match(launchText, /\bgetShellSessionHandoffCompatibilityReport\b/);
assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/);
assert.match(launchText, /\bdata-handoff-status\b/);
assert.match(launchText, /\bdata-handoff-rows\b/);
assert.match(launchText, /\bgetControlPageApiMethods\b/);
assert.match(controlPageText, /\bgetControlPageContract\b/);
assert.match(controlPageText, /\breadControlPageStatus\b/);
@@ -240,22 +284,38 @@ assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationSchema\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/);
assert.match(docText, /\bisSupportedIniPanelControlPageApiManifest\b/);
assert.match(docText, /\bisSupportedIniPanelLaunchApiManifest\b/);
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedLaunchApiManifest\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getLaunchApiSchema\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getLaunchApiManifest\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationSchema\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationManifest\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellIntegrationReadiness\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSummarySchema\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSummary\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedShellSessionHandoffSummary\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffCompatibilityReport\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffDisplayViewModel\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getShellSessionHandoffSnapshot\b/);
assert.match(docText, /\bdata-handoff-status\b/);
assert.match(docText, /\bdata-handoff-rows\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/);
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellIntegrationReadiness\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSummary\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bisSupportedShellSessionHandoffSummary\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffCompatibilityReport\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffDisplayViewModel\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bgetShellSessionHandoffSnapshot\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bhandoffSummary\.handoffMethods\.readStatus\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\breadControlPageStatus\b/);
assert.match(shellIntegrationWorkflowSmokeText, /\bbrowser_ini_shell_integration_workflow_smoke=ok\b/);

View File

@@ -46,7 +46,12 @@ assert.deepEqual(manifest, {
"getShellIntegrationSchema",
"getShellIntegrationManifest",
"getShellIntegrationReadiness",
"getShellSessionHandoffSummarySchema",
"getShellSessionHandoffSummary",
"isSupportedShellSessionHandoffSummary",
"getShellSessionHandoffCompatibilityReport",
"getShellSessionHandoffDisplayViewModel",
"getShellSessionHandoffSnapshot",
"getLauncherLinks",
"getControlPageApiMethods",
],
@@ -147,7 +152,12 @@ assert.match(launchText, /\bgetLaunchApiManifest\b/);
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummarySchema\b/);
assert.match(launchText, /\bgetShellSessionHandoffSummary\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffSummary\b/);
assert.match(launchText, /\bgetShellSessionHandoffCompatibilityReport\b/);
assert.match(launchText, /\bgetShellSessionHandoffDisplayViewModel\b/);
assert.match(launchText, /\bgetShellSessionHandoffSnapshot\b/);
assert.match(launchText, /\blinuxCncIniPanelLaunchApi\b/);
console.log("ini_panel_launch_api_manifest_node_smoke=ok");

View File

@@ -14,9 +14,14 @@ import {
createIniPanelShellIntegrationReadiness,
createIniPanelShellIntegrationSchema,
createIniPanelShellIntegrationWorkflowPlan,
createIniPanelShellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSummary,
createIniPanelShellSessionHandoffSummarySchema,
getVisibleIniPanelEntries,
isSupportedIniPanelShellIntegrationManifest,
isSupportedIniPanelShellSessionHandoffSummary,
} from "../../../runtime/ui/ini-panel/ui-shell.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -30,6 +35,15 @@ const manifest = createIniPanelShellIntegrationManifest();
const readiness = createIniPanelShellIntegrationReadiness(manifest);
const workflowPlan = createIniPanelShellIntegrationWorkflowPlan({ manifest, readiness });
const handoffSummary = createIniPanelShellSessionHandoffSummary({ manifest, readiness, workflowPlan });
const handoffSummarySchema = createIniPanelShellSessionHandoffSummarySchema();
const handoffCompatibilityReport = createIniPanelShellSessionHandoffCompatibilityReport(handoffSummary);
const handoffDisplayViewModel = createIniPanelShellSessionHandoffDisplayViewModel(handoffCompatibilityReport);
const handoffSnapshot = createIniPanelShellSessionHandoffSnapshot({
readiness,
summary: handoffSummary,
compatibilityReport: handoffCompatibilityReport,
displayViewModel: handoffDisplayViewModel,
});
assert.deepEqual(schema, {
apiName: "ini-panel-shell-integration",
@@ -85,7 +99,7 @@ assert.deepEqual(readiness, {
counts: {
pages: 2,
launcherLinks: 2,
launchMethods: 9,
launchMethods: 14,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -133,6 +147,8 @@ assert.deepEqual(workflowPlan, {
},
});
assert.deepEqual(handoffSummary, {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 1,
phase: "ready",
ready: true,
targetPage: {
@@ -145,7 +161,7 @@ assert.deepEqual(handoffSummary, {
counts: {
pages: 2,
launcherLinks: 2,
launchMethods: 9,
launchMethods: 14,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -189,6 +205,149 @@ assert.deepEqual(handoffSummary, {
},
blockingReasons: [],
});
assert.deepEqual(handoffSummarySchema, {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 1,
fields: [
"apiName",
"summaryVersion",
"phase",
"ready",
"targetPage",
"readiness",
"persistenceCapabilities",
"readonlyStatusFields",
"handoffMethods",
"blockingReasons",
],
});
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(handoffSummary), true);
assert.equal(
isSupportedIniPanelShellSessionHandoffSummary({ ...handoffSummary, summaryVersion: 2 }),
false,
);
assert.equal(
isSupportedIniPanelShellSessionHandoffSummary({ ...handoffSummary, apiName: "other" }),
false,
);
const missingSummaryField = { ...handoffSummary };
delete missingSummaryField.readonlyStatusFields;
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(missingSummaryField), false);
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(null), false);
assert.deepEqual(handoffCompatibilityReport, {
apiName: "ini-panel-shell-session-handoff-compatibility-report",
reportVersion: 1,
phase: "ready",
compatible: true,
summarySupported: true,
handoffReady: true,
schema: {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 1,
fields: [
"apiName",
"summaryVersion",
"phase",
"ready",
"targetPage",
"readiness",
"persistenceCapabilities",
"readonlyStatusFields",
"handoffMethods",
"blockingReasons",
],
},
summary: {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 1,
phase: "ready",
ready: true,
},
missingFields: [],
mismatchFields: [],
blockingReasons: [],
});
assert.deepEqual(handoffDisplayViewModel, {
phase: "ready",
title: "Shell handoff compatibility",
statusText: "Ready",
detailText: "No blocking reasons",
rows: [
{
id: "summary-supported",
label: "Summary schema",
value: "supported",
},
{
id: "handoff-ready",
label: "Handoff readiness",
value: "ready",
},
{
id: "missing-fields",
label: "Missing fields",
value: "none",
},
{
id: "mismatch-fields",
label: "Mismatched fields",
value: "none",
},
{
id: "blocking-reasons",
label: "Blocking reasons",
value: "none",
},
],
});
assert.deepEqual(handoffSnapshot, {
apiName: "ini-panel-shell-session-handoff-snapshot",
snapshotVersion: 1,
phase: "ready",
ready: true,
readiness,
summary: handoffSummary,
compatibilityReport: handoffCompatibilityReport,
displayViewModel: handoffDisplayViewModel,
});
assert.equal(createIniPanelShellSessionHandoffSnapshot().displayViewModel.rows.length, 5);
assert.deepEqual(
createIniPanelShellSessionHandoffDisplayViewModel(
createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }),
).rows.find((row) => row.id === "mismatch-fields"),
{
id: "mismatch-fields",
label: "Mismatched fields",
value: "summaryVersion",
},
);
assert.deepEqual(
createIniPanelShellSessionHandoffCompatibilityReport({ ...handoffSummary, summaryVersion: 2 }),
{
...handoffCompatibilityReport,
phase: "blocked",
compatible: false,
summarySupported: false,
handoffReady: false,
summary: {
apiName: "ini-panel-shell-session-handoff-summary",
summaryVersion: 2,
phase: "ready",
ready: true,
},
mismatchFields: ["summaryVersion"],
},
);
const missingFieldReportInput = { ...handoffSummary };
delete missingFieldReportInput.readonlyStatusFields;
assert.deepEqual(
createIniPanelShellSessionHandoffCompatibilityReport(missingFieldReportInput).missingFields,
["readonlyStatusFields"],
);
assert.deepEqual(
createIniPanelShellSessionHandoffCompatibilityReport(null).missingFields,
handoffSummarySchema.fields,
);
const blockedManifest = {
...createIniPanelShellIntegrationManifest(),
compatibility: {
@@ -210,7 +369,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), {
counts: {
pages: 2,
launcherLinks: 2,
launchMethods: 9,
launchMethods: 14,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -239,6 +398,22 @@ assert.deepEqual(
}).blockingReasons,
["launchCompatibility"],
);
assert.deepEqual(
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellSessionHandoffSummary({
manifest: blockedManifest,
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
workflowPlan: blockedWorkflowPlan,
})).blockingReasons,
["launchCompatibility"],
);
assert.equal(
createIniPanelShellSessionHandoffCompatibilityReport(createIniPanelShellSessionHandoffSummary({
manifest: blockedManifest,
readiness: createIniPanelShellIntegrationReadiness(blockedManifest),
workflowPlan: blockedWorkflowPlan,
})).compatible,
false,
);
const missingTargetPlan = createIniPanelShellIntegrationWorkflowPlan({
manifest,
controlEntryId: "missing-entry",
@@ -337,7 +512,12 @@ assert.match(shellText, /\bexport function createIniPanelShellIntegrationSchema\
assert.match(shellText, /\bexport function createIniPanelShellIntegrationManifest\b/);
assert.match(shellText, /\bexport function createIniPanelShellIntegrationReadiness\b/);
assert.match(shellText, /\bexport function createIniPanelShellIntegrationWorkflowPlan\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffCompatibilityReport\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffDisplayViewModel\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSnapshot\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummary\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffSummarySchema\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelShellSessionHandoffSummary\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
assert.match(launchText, /\bgetShellIntegrationSchema\b/);
assert.match(launchText, /\bgetShellIntegrationManifest\b/);
@@ -345,7 +525,12 @@ assert.match(launchText, /\bgetShellIntegrationReadiness\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationManifest\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationReadiness\b/);
assert.match(docText, /\bcreateIniPanelShellIntegrationWorkflowPlan\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffCompatibilityReport\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffDisplayViewModel\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSnapshot\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummary\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffSummarySchema\b/);
assert.match(docText, /\bisSupportedIniPanelShellSessionHandoffSummary\b/);
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
assert.doesNotMatch(shellText, /\bparseGcode\b|\bcanonicalEvents\b|\btoolTable\b|\bplanner\b/);

View File

@@ -14,7 +14,11 @@ import {
createIniPanelShellIntegrationReadiness,
createIniPanelShellIntegrationSchema,
createIniPanelShellIntegrationWorkflowPlan,
createIniPanelShellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSummary,
createIniPanelShellSessionHandoffSummarySchema,
createIniPanelShellViewModel,
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
@@ -27,6 +31,7 @@ import {
isSupportedIniPanelControlPageApiManifest,
isSupportedIniPanelLaunchApiManifest,
isSupportedIniPanelShellIntegrationManifest,
isSupportedIniPanelShellSessionHandoffSummary,
loadMachineSessionForControlPageWorkflow,
readMachineSessionReadonlyStatus,
refreshMachineSessionControlPage,
@@ -67,7 +72,11 @@ assert.equal(typeof createIniPanelShellIntegrationManifest, "function");
assert.equal(typeof createIniPanelShellIntegrationReadiness, "function");
assert.equal(typeof createIniPanelShellIntegrationSchema, "function");
assert.equal(typeof createIniPanelShellIntegrationWorkflowPlan, "function");
assert.equal(typeof createIniPanelShellSessionHandoffCompatibilityReport, "function");
assert.equal(typeof createIniPanelShellSessionHandoffDisplayViewModel, "function");
assert.equal(typeof createIniPanelShellSessionHandoffSnapshot, "function");
assert.equal(typeof createIniPanelShellSessionHandoffSummary, "function");
assert.equal(typeof createIniPanelShellSessionHandoffSummarySchema, "function");
assert.equal(typeof loadMachineSessionForControlPageWorkflow, "function");
assert.equal(typeof readMachineSessionReadonlyStatus, "function");
assert.equal(typeof refreshMachineSessionControlPage, "function");
@@ -75,6 +84,7 @@ assert.equal(typeof renderMachineSessionControlView, "function");
assert.equal(typeof isSupportedIniPanelControlPageApiManifest, "function");
assert.equal(typeof isSupportedIniPanelLaunchApiManifest, "function");
assert.equal(typeof isSupportedIniPanelShellIntegrationManifest, "function");
assert.equal(typeof isSupportedIniPanelShellSessionHandoffSummary, "function");
const shellManifest = getIniPanelEntryManifest();
shellManifest[0].title = "changed";
@@ -132,6 +142,58 @@ assert.deepEqual(
workflowPlan: shellViewModel.shellIntegrationWorkflowPlan,
}),
);
assert.deepEqual(shellViewModel.shellSessionHandoffSummarySchema, createIniPanelShellSessionHandoffSummarySchema());
assert.equal(isSupportedIniPanelShellSessionHandoffSummary(shellViewModel.shellSessionHandoffSummary), true);
assert.deepEqual(
shellViewModel.shellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffCompatibilityReport(shellViewModel.shellSessionHandoffSummary),
);
assert.deepEqual(
shellViewModel.shellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffDisplayViewModel(shellViewModel.shellSessionHandoffCompatibilityReport),
);
assert.deepEqual(
shellViewModel.shellSessionHandoffSnapshot,
createIniPanelShellSessionHandoffSnapshot({
readiness: shellViewModel.shellIntegrationReadiness,
summary: shellViewModel.shellSessionHandoffSummary,
compatibilityReport: shellViewModel.shellSessionHandoffCompatibilityReport,
displayViewModel: shellViewModel.shellSessionHandoffDisplayViewModel,
}),
);
assert.deepEqual(shellViewModel.shellSessionHandoffDisplayViewModel, {
phase: "ready",
title: "Shell handoff compatibility",
statusText: "Ready",
detailText: "No blocking reasons",
rows: [
{
id: "summary-supported",
label: "Summary schema",
value: "supported",
},
{
id: "handoff-ready",
label: "Handoff readiness",
value: "ready",
},
{
id: "missing-fields",
label: "Missing fields",
value: "none",
},
{
id: "mismatch-fields",
label: "Mismatched fields",
value: "none",
},
{
id: "blocking-reasons",
label: "Blocking reasons",
value: "none",
},
],
});
assert.equal(
isSupportedIniPanelShellIntegrationManifest(shellViewModel.shellIntegrationManifest),
true,
@@ -164,7 +226,18 @@ assert.equal(shellViewModel.controlPage.createController, createMachineSessionCo
assert.equal(shellViewModel.isSupportedShellIntegrationManifest, isSupportedIniPanelShellIntegrationManifest);
assert.equal(shellViewModel.createShellIntegrationReadiness, createIniPanelShellIntegrationReadiness);
assert.equal(shellViewModel.createShellIntegrationWorkflowPlan, createIniPanelShellIntegrationWorkflowPlan);
assert.equal(shellViewModel.isSupportedShellSessionHandoffSummary, isSupportedIniPanelShellSessionHandoffSummary);
assert.equal(shellViewModel.createShellSessionHandoffSummarySchema, createIniPanelShellSessionHandoffSummarySchema);
assert.equal(shellViewModel.createShellSessionHandoffSummary, createIniPanelShellSessionHandoffSummary);
assert.equal(
shellViewModel.createShellSessionHandoffCompatibilityReport,
createIniPanelShellSessionHandoffCompatibilityReport,
);
assert.equal(
shellViewModel.createShellSessionHandoffDisplayViewModel,
createIniPanelShellSessionHandoffDisplayViewModel,
);
assert.equal(shellViewModel.createShellSessionHandoffSnapshot, createIniPanelShellSessionHandoffSnapshot);
assert.deepEqual(shellViewModel.controlPage.contract, createIniPanelShellControlPageContract());
assert.equal(shellViewModel.controlPage.isSupportedBrowserApiManifest, isSupportedIniPanelControlPageApiManifest);
assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);