绑定原生壳能力真实链路

桌面壳门禁拒绝声明能力落入 fallback-only 分支

根级原生壳门禁登记 H5 受控原生路由链路

项目文档同步宿主能力声明验收约定
This commit is contained in:
2026-06-20 16:23:55 +08:00
parent 6f12b48ce1
commit 3661ca69ee
4 changed files with 178 additions and 1 deletions
+99
View File
@@ -239,6 +239,47 @@ const wechatCapabilityFlowContracts = [
],
},
];
const h5NativeAppRouteFlowContracts = [
{
route: '/child-motion-demo',
label: 'child motion demo',
files: [
'src/components/platform-entry/PlatformEntryFlowShellImpl.tsx',
'src/routing/appRoutes.tsx',
'src/routing/appRoutes.test.ts',
'src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx',
],
snippets: [
[
'src/components/platform-entry/PlatformEntryFlowShellImpl.tsx',
"navigateHostNativePage('/child-motion-demo')",
],
[
'src/components/platform-entry/PlatformEntryFlowShellImpl.tsx',
"window.location.assign('/child-motion-demo')",
],
['src/routing/appRoutes.tsx', "normalizedPath === '/child-motion-demo'"],
['src/routing/appRoutes.test.ts', "matchAppRoute('/child-motion-demo')"],
[
'src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx',
"request.method === 'navigation.openNativePage'",
],
[
'src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx',
"url === '/child-motion-demo'",
],
],
tests: [
'src/routing/appRoutes.test.ts',
],
targetedTests: [
{
filePath: 'src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx',
name: 'native app opens child motion demo through host navigation bridge',
},
],
},
];
const expectedWechatHostBridgeFiles = [
'dispatch.js',
'payment.js',
@@ -503,12 +544,21 @@ const h5HostBridgeTests = [
'src/components/platform-entry/platformDraftGenerationShelfModel.test.ts',
'src/components/platform-entry/platformHostBridgeSync.test.ts',
'src/components/platform-entry/platformHostNotificationModel.test.ts',
'src/routing/appRoutes.test.ts',
'src/services/runtimeAudioFeedback.test.ts',
'src/services/clipboard.test.ts',
'src/services/appTitle.test.ts',
];
const h5PlatformHostBridgeIntegrationTest =
'native app jump hop draft completion sends host notification and badge from platform shell';
const h5NativeAppRouteFlowTestSteps = h5NativeAppRouteFlowContracts.flatMap(
(contract) =>
(contract.targetedTests ?? []).map((test) => ({
label: `h5-native-app-route-${contract.route}`,
command: npmCommand,
args: ['run', 'test', '--', test.filePath, '-t', test.name],
})),
);
const wechatShellTests = [
'miniprogram/host-bridge/protocol.test.js',
@@ -543,6 +593,7 @@ const steps = [
h5PlatformHostBridgeIntegrationTest,
],
},
...h5NativeAppRouteFlowTestSteps,
{
label: 'wechat-shell-tests',
command: npmCommand,
@@ -1926,6 +1977,51 @@ function assertWechatMiniProgramCapabilityFlows() {
}
}
function assertH5NativeAppRouteFlows() {
const h5HostBridgeTestSet = new Set(h5HostBridgeTests);
for (const contract of h5NativeAppRouteFlowContracts) {
for (const filePath of contract.files) {
if (!fs.existsSync(filePath)) {
throw new Error(
`H5 native app ${contract.label} route flow file is missing: ${filePath}`,
);
}
}
for (const [filePath, snippet] of contract.snippets) {
assertFileIncludesSnippet(
filePath,
snippet,
`H5 native app ${contract.label} route flow`,
);
}
for (const testPath of contract.tests) {
if (!h5HostBridgeTestSet.has(testPath)) {
throw new Error(
`H5 native app ${contract.label} route flow test is not part of check:native-shells: ${testPath}`,
);
}
}
for (const test of contract.targetedTests ?? []) {
assertFileIncludesSnippet(
test.filePath,
`test('${test.name}'`,
`H5 native app ${contract.label} route flow test`,
);
const stepRunsTest = h5NativeAppRouteFlowTestSteps.some(
(step) => step.args.includes(test.filePath) && step.args.includes(test.name),
);
if (!stepRunsTest) {
throw new Error(
`H5 native app ${contract.label} route flow targeted test is not part of check:native-shells: ${test.filePath}`,
);
}
}
}
}
function assertWechatPaymentResultBoundaries() {
const paymentSource = fs.readFileSync(
'miniprogram/host-bridge/payment.js',
@@ -2316,6 +2412,9 @@ assertWechatMiniProgramRouteParity();
console.log('[check:native-shells] wechat-mini-program-capability-flows');
assertWechatMiniProgramCapabilityFlows();
console.log('[check:native-shells] h5-native-app-route-flows');
assertH5NativeAppRouteFlows();
console.log('[check:native-shells] wechat-payment-result-boundaries');
assertWechatPaymentResultBoundaries();