Files
claw/tests/generated_scene_full_direct_mock_runner.js

340 lines
10 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const repoRoot = path.resolve(__dirname, '..');
const finalRoot = path.join(
repoRoot,
'examples',
'scene_skill_102_runtime_semantics_rematerialization_2026-04-21',
);
const skillRoot = path.join(finalRoot, 'skills');
const indexPath = path.join(finalRoot, 'scene_skill_102_index.json');
const outputPath = path.join(
repoRoot,
'tests',
'fixtures',
'generated_scene',
'scene_skill_102_runtime_semantics_full_direct_mock_execution_2026-04-21.json',
);
const reportPath = path.join(
repoRoot,
'docs',
'superpowers',
'reports',
'2026-04-21-generated-scene-runtime-semantics-full-direct-mock-execution-report.md',
);
function readJson(file) {
return JSON.parse(fs.readFileSync(file, 'utf8'));
}
function writeJson(file, value) {
fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
}
function findScript(sceneId) {
const scriptsDir = path.join(skillRoot, sceneId, 'scripts');
const scripts = fs
.readdirSync(scriptsDir)
.filter((name) => name.endsWith('.js') && !name.endsWith('.test.js'))
.sort();
if (scripts.length === 0) throw new Error(`no runtime script found for ${sceneId}`);
return path.join(scriptsDir, scripts[0]);
}
function createResponse(payload) {
return {
ok: true,
status: 200,
async json() {
return payload;
},
};
}
function parseBody(body) {
if (!body || typeof body !== 'string') return {};
try {
return JSON.parse(body);
} catch (_) {
return Object.fromEntries(
body
.split('&')
.filter(Boolean)
.map((part) => {
const [key, value = ''] = part.split('=');
return [decodeURIComponent(key), decodeURIComponent(value)];
}),
);
}
}
function makeRichRow() {
return {
id: 'row-1',
wkOrderNo: 'WK-1',
appNo: 'WK-1',
countyCodeName: 'COUNTY-1',
countyName: 'COUNTY-1',
orgNo: 'ORG-1',
orgName: 'ORG-NAME',
ORG_NAME: 'ORG-NAME',
YGDL: '100',
LINE_LOSS_RATE: '1.23',
PPQ: '10',
UPQ: '9',
LOSS_PQ: '1',
dyfjmZs: '1',
dyfjmHgZs: '1',
dyfjmHgl: '100%',
gyxzzrZs: '1',
gyxzzrHgZs: '1',
gyxzzrHgl: '100%',
dyjmZs: '1',
dyjmHgZs: '1',
dyjmHgl: '100%',
assetId: 'ASSET-1',
devId: 'DEV-1',
deviceName: 'DEVICE-1',
dataStatus: 'ok',
status: 5,
value: 'ok',
};
}
function installGlobals(archetype, expectedDomain, requestLog) {
delete global.$;
global.location = { hostname: expectedDomain || '' };
global.window = global;
global.document = {
title: 'mock page',
body: {},
querySelector() {
return null;
},
querySelectorAll() {
return [];
},
};
global.fetch = async (url, options = {}) => {
requestLog.push({
via: 'fetch',
url: String(url),
method: options.method || 'GET',
});
const body = parseBody(options.body);
const row = makeRichRow();
if (archetype === 'paginated_enrichment') {
if (body.page && Number(body.page) > 1) return createResponse({ data: [] });
if (String(url).includes('yx.gs.sgcc.com.cn')) {
return createResponse({ data: { enrichmentField: 'detail', ...row } });
}
return createResponse({ data: [row], rows: [row], content: [row] });
}
if (archetype === 'multi_mode_request') {
return createResponse({ content: [row], data: [row], rows: [row] });
}
if (archetype === 'single_request_enrichment') {
return createResponse({ data: [row], rows: [row], content: [row] });
}
if (archetype === 'multi_endpoint_inventory') {
return createResponse({ rows: [row], data: [row], content: [row] });
}
if (archetype === 'local_doc_pipeline') {
return createResponse({ ok: true, data: [row], rows: [row] });
}
if (archetype === 'page_state_eval') {
return createResponse({ data: [row], rows: [row] });
}
return createResponse({ data: [row], rows: [row], content: [row] });
};
}
function makeDeps(archetype, requestLog) {
const validatePageContext = () => ({ ok: true });
if (archetype === 'host_bridge_workflow') {
return {
validatePageContext,
async invokeHostBridge(action, args) {
requestLog.push({ via: 'host-bridge', action });
return { ok: true, action, callbackId: 'mock-callback' };
},
async queryCallbackEndpoint(endpoint, args) {
requestLog.push({ via: 'callback', endpoint: endpoint.name });
return { data: [makeRichRow()], rows: [makeRichRow()] };
},
};
}
if (archetype === 'page_state_eval') {
return {
validatePageContext,
async queryState(args) {
requestLog.push({ via: 'page-state' });
return { data: [makeRichRow()] };
},
};
}
return undefined;
}
async function runScene(row) {
const started = Date.now();
const { sceneId, sceneName, archetype } = row;
let scriptPath = '';
const requestLog = [];
try {
scriptPath = findScript(sceneId);
const report = readJson(
path.join(skillRoot, sceneId, 'references', 'generation-report.json'),
);
const expectedDomain = report.bootstrap?.expectedDomain || '';
installGlobals(archetype, expectedDomain, requestLog);
delete require.cache[require.resolve(scriptPath)];
const mod = require(scriptPath);
if (typeof mod.buildBrowserEntrypointResult !== 'function') {
return {
sceneId,
sceneName,
archetype,
directMockStatus: 'direct-mock-fail',
scriptLoadStatus: 'script-load-pass',
failureReason: 'missing_buildBrowserEntrypointResult_export',
durationMs: Date.now() - started,
requestCount: requestLog.length,
};
}
const args = {
expected_domain: expectedDomain,
target_url: report.bootstrap?.targetUrl || '',
org_label: 'MOCK_ORG',
org_code: 'MOCK_ORG_CODE',
period_mode: report.defaultMode || 'month',
period_mode_code: report.defaultMode || 'month',
period_value: '2026-04',
period_payload: {},
};
const deps = makeDeps(archetype, requestLog);
const artifact = deps
? await mod.buildBrowserEntrypointResult(args, deps)
: await mod.buildBrowserEntrypointResult(args);
const artifactStatus = artifact?.status || 'missing';
const passStatuses = new Set(['ok', 'empty']);
const partialStatuses = new Set(['partial']);
const directMockStatus = passStatuses.has(artifactStatus)
? 'direct-mock-pass'
: partialStatuses.has(artifactStatus)
? 'direct-mock-partial'
: 'direct-mock-fail';
return {
sceneId,
sceneName,
archetype,
directMockStatus,
scriptLoadStatus: 'script-load-pass',
mockDependencyStatus: 'mock-dependency-ready',
artifactStatus,
artifactType: artifact?.type || null,
rowCount: Array.isArray(artifact?.rows) ? artifact.rows.length : null,
counts: artifact?.counts || {},
failureReason:
directMockStatus === 'direct-mock-fail' ? `artifact_status_${artifactStatus}` : null,
durationMs: Date.now() - started,
requestCount: requestLog.length,
scriptPath: path.relative(repoRoot, scriptPath).replace(/\\/g, '/'),
};
} catch (error) {
return {
sceneId,
sceneName,
archetype,
directMockStatus: 'direct-mock-fail',
scriptLoadStatus: scriptPath ? 'script-load-pass' : 'script-load-fail',
failureReason: error.message,
durationMs: Date.now() - started,
requestCount: requestLog.length,
scriptPath: scriptPath ? path.relative(repoRoot, scriptPath).replace(/\\/g, '/') : null,
};
}
}
async function main() {
const index = readJson(indexPath);
const scenes = Array.isArray(index) ? index : index.scenes;
const results = [];
for (const row of scenes) {
results.push(await runScene(row));
}
const byStatus = {};
const byArchetype = {};
for (const result of results) {
byStatus[result.directMockStatus] = (byStatus[result.directMockStatus] || 0) + 1;
byArchetype[result.archetype] = byArchetype[result.archetype] || {};
byArchetype[result.archetype][result.directMockStatus] =
(byArchetype[result.archetype][result.directMockStatus] || 0) + 1;
}
const asset = {
runDate: '2026-04-21',
plan: '2026-04-21-generated-scene-runtime-semantics-validation-refresh-execution-plan.md',
execution: 'full-direct-mock-only-no-browser-no-network',
summary: {
totalScenes: results.length,
byStatus,
byArchetype,
productionNetworkUsed: false,
realBrowserUsed: false,
generatedSkillsModified: false,
},
results,
};
writeJson(outputPath, asset);
const lines = [];
lines.push('# Scene Skill 102 Full Direct Mock Execution Report');
lines.push('');
lines.push('> Date: 2026-04-21');
lines.push('> Plan: `2026-04-21-generated-scene-runtime-semantics-validation-refresh-execution-plan.md`');
lines.push('');
lines.push('## Scope');
lines.push('');
lines.push('This run executed all 102 generated scene skill scripts in a local mock runtime. It did not use a real browser, real network, production credentials, or business systems. It did not modify generated skill packages.');
lines.push('');
lines.push('## Summary');
lines.push('');
lines.push('| Status | Count |');
lines.push('| --- | ---: |');
for (const [status, count] of Object.entries(byStatus).sort()) {
lines.push(`| \`${status}\` | ${count} |`);
}
lines.push('');
lines.push('## By Archetype');
lines.push('');
lines.push('| Archetype | Result |');
lines.push('| --- | --- |');
for (const [archetype, statuses] of Object.entries(byArchetype).sort()) {
const summary = Object.entries(statuses)
.map(([status, count]) => `${status}: ${count}`)
.join(', ');
lines.push(`| \`${archetype}\` | ${summary} |`);
}
lines.push('');
lines.push('## Interpretation');
lines.push('');
lines.push('Direct mock execution passing means every generated skill entrypoint can load and complete against controlled fake dependencies. It still does not mean production execution passed.');
lines.push('');
lines.push('## Next Step');
lines.push('');
lines.push('If this full direct mock run is acceptable, the next bounded stage is pseudo-production batch selection. That stage should choose a small, archetype-balanced batch for real or quasi-real environment execution planning.');
lines.push('');
fs.writeFileSync(reportPath, `${lines.join('\n')}\n`, 'utf8');
console.log(JSON.stringify(asset.summary, null, 2));
}
main().catch((error) => {
console.error(error);
process.exit(1);
});