570ecbd1b0
Prioritize scheduled-task intent over page.generate for automation phrases, add run-wechat-gate-evidence.mjs for WX-01..13, and document 103 maintenance-window steps for Goose v1.49. Co-authored-by: Cursor <cursoragent@cursor.com>
159 lines
5.3 KiB
JavaScript
159 lines
5.3 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* WX-01..WX-13 release-gate evidence + optional live WeChat webhook smoke.
|
|
*
|
|
* Deterministic suites mirror release-gate/coverage.mjs:
|
|
* - wechat-channel-contract → WX-01..08 (+ FILE-08 overlap)
|
|
* - wechat-terminal-and-atomic → WX-09..13
|
|
* - wechat-native-image-delivery → WX-05
|
|
*
|
|
* Live smoke (optional): POST /webhooks/wechat-mp/messages via run-wechat-scenario-test.mjs
|
|
*/
|
|
import { spawnSync } from 'node:child_process';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
const DETERMINISTIC_SUITES = [
|
|
{
|
|
id: 'wechat-channel-contract',
|
|
scenarios: ['WX-01', 'WX-02', 'WX-03', 'WX-04', 'WX-06', 'WX-07', 'WX-08'],
|
|
command: [
|
|
'--test',
|
|
'wechat-mp.test.mjs',
|
|
'wechat-oauth.test.mjs',
|
|
'wechat-pay.test.mjs',
|
|
'wechat-media.test.mjs',
|
|
'wechat/wechat-channel.test.mjs',
|
|
'wechat/image-generation-policy.test.mjs',
|
|
'mindspace-chat-docx-package.test.mjs',
|
|
'mindspace-html-download-links.test.mjs',
|
|
'mindspace-public-asset-token.test.mjs',
|
|
'server/portal-mindspace-asset-routes.test.mjs',
|
|
],
|
|
},
|
|
{
|
|
id: 'wechat-terminal-and-atomic-delivery',
|
|
scenarios: ['WX-09', 'WX-10', 'WX-11', 'WX-12', 'WX-13'],
|
|
command: [
|
|
'--test',
|
|
'user-auth.test.mjs',
|
|
'wechat-mp.test.mjs',
|
|
'wechat-media.test.mjs',
|
|
'wechat/wechat-channel.test.mjs',
|
|
'chat-image-turn-scope.test.mjs',
|
|
'tkmind-proxy.test.mjs',
|
|
],
|
|
},
|
|
{
|
|
id: 'wechat-native-image-delivery',
|
|
scenarios: ['WX-05'],
|
|
command: ['--test', 'wechat-media.test.mjs'],
|
|
},
|
|
];
|
|
|
|
function runNode(args, label) {
|
|
const result = spawnSync(process.execPath, args, {
|
|
cwd: root,
|
|
encoding: 'utf8',
|
|
env: process.env,
|
|
});
|
|
if (result.status !== 0) {
|
|
const detail = result.stderr?.trim() || result.stdout?.trim() || `${label} exited ${result.status}`;
|
|
throw new Error(`${label} failed: ${detail.slice(-2000)}`);
|
|
}
|
|
return result.stdout?.trim() ?? '';
|
|
}
|
|
|
|
async function assertLiveEnv() {
|
|
const { loadH5Environment } = await import('./load-env.mjs');
|
|
loadH5Environment(import.meta.dirname);
|
|
const missing = ['H5_WECHAT_MP_TOKEN', 'H5_WECHAT_MP_APP_ID', 'DATABASE_URL']
|
|
.filter((key) => !String(process.env[key] ?? '').trim());
|
|
if (missing.length) {
|
|
throw new Error(
|
|
`live smoke 缺少环境变量: ${missing.join(', ')}。请在 .env.local 配置(见 docs/local-dev.md §公众号 Agent 调试)`,
|
|
);
|
|
}
|
|
}
|
|
|
|
function parseArgs(argv) {
|
|
const options = {
|
|
live: false,
|
|
liveOnly: false,
|
|
liveScenario: 'poem-page',
|
|
liveAll: false,
|
|
skipDeterministic: false,
|
|
};
|
|
for (let index = 2; index < argv.length; index += 1) {
|
|
const arg = argv[index];
|
|
if (arg === '--live') options.live = true;
|
|
else if (arg === '--live-only') {
|
|
options.live = true;
|
|
options.liveOnly = true;
|
|
options.skipDeterministic = true;
|
|
} else if (arg === '--live-all') {
|
|
options.live = true;
|
|
options.liveAll = true;
|
|
} else if (arg === '--live-scenario' && argv[index + 1]) {
|
|
options.live = true;
|
|
options.liveScenario = argv[++index];
|
|
} else if (arg === '--skip-deterministic') options.skipDeterministic = true;
|
|
else if (arg === '-h' || arg === '--help') {
|
|
console.log(`Usage:
|
|
node scripts/run-wechat-gate-evidence.mjs
|
|
node scripts/run-wechat-gate-evidence.mjs --live-only --live-scenario poem-page
|
|
node scripts/run-wechat-gate-evidence.mjs --live-only --live-all
|
|
node scripts/run-wechat-gate-evidence.mjs --skip-deterministic --live-only --live-scenario chat-general
|
|
|
|
Deterministic: WX-01..WX-13 unit/contract suites (no LLM).
|
|
Live smoke: Portal :8081 + DATABASE_URL + H5_WECHAT_MP_TOKEN + H5_WECHAT_MP_APP_ID.`);
|
|
process.exit(0);
|
|
} else {
|
|
throw new Error(`Unknown argument: ${arg}`);
|
|
}
|
|
}
|
|
return options;
|
|
}
|
|
|
|
async function main() {
|
|
const options = parseArgs(process.argv);
|
|
const covered = new Set();
|
|
|
|
if (!options.skipDeterministic) {
|
|
runNode(['--test', 'wechat-intent-router.test.mjs'], 'wechat-intent-router');
|
|
for (const suite of DETERMINISTIC_SUITES) {
|
|
runNode(suite.command, suite.id);
|
|
for (const scenarioId of suite.scenarios) covered.add(scenarioId);
|
|
console.log(`[wechat-gate] PASS ${suite.id} → ${suite.scenarios.join(', ')}`);
|
|
}
|
|
}
|
|
|
|
if (options.live) {
|
|
await assertLiveEnv();
|
|
const liveArgs = ['scripts/run-wechat-scenario-test.mjs'];
|
|
if (options.liveAll) liveArgs.push('--all');
|
|
else liveArgs.push('--scenario', options.liveScenario);
|
|
runNode(liveArgs, 'wechat-live-smoke');
|
|
console.log('[wechat-gate] PASS live smoke');
|
|
}
|
|
|
|
console.log('WECHAT_GATE_EVIDENCE_OK:');
|
|
console.log(` deterministic=${options.skipDeterministic ? 'skipped' : 'WX-01..WX-13'}`);
|
|
console.log(` live=${options.live ? (options.liveAll ? 'all-scenarios' : options.liveScenario) : 'not-run'}`);
|
|
if (covered.size) {
|
|
console.log(` scenarios=${[...covered].sort().join(',')}`);
|
|
}
|
|
if (!options.live) {
|
|
console.log(' note=add --live-only --live-scenario poem-page for WX-04/13 webhook E2E');
|
|
} else if (options.liveOnly) {
|
|
console.log(' mode=live-only');
|
|
}
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(`WECHAT_GATE_EVIDENCE_FAIL: ${error.message}`);
|
|
process.exit(1);
|
|
});
|