105 lines
8.5 KiB
JavaScript
105 lines
8.5 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
const readJson = (relative) => JSON.parse(fs.readFileSync(path.join(root, relative), "utf8"));
|
|
const writeJson = (relative, value) => {
|
|
const target = path.join(root, relative);
|
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
fs.writeFileSync(target, `${JSON.stringify(value, null, 2)}\n`);
|
|
};
|
|
|
|
const report = readJson("tests/golden/WBV2-P1424-001/product-implementation-report.json");
|
|
const catalog = readJson("web/app/src/capabilities/blender-feature-route-catalog.json");
|
|
const wasmManifest = readJson("web/app/public/wasm-module-manifest.json");
|
|
|
|
// One representative production check per implementation task. The selector is
|
|
// deliberately explicit: the runner groups selectors by file, but never retries
|
|
// a case or runs a second selector for the same feature.
|
|
const selectors = {
|
|
"WEBUI-NONMESH-ADVANCED": ["playwright", "tests/e2e/wbv2-nonmesh-delete-production.spec.ts", "WBV2-P1101-000 preserves deleteNonMeshData Main recovery semantics"],
|
|
"WEBUI-FONT-ASSETS": ["playwright", "tests/e2e/wbv2-font-advanced-production.spec.ts", "WBV2-P1136-001 preserves Font advanced fields and links through Main recovery"],
|
|
"WEBUI-SCULPT": ["playwright", "tests/e2e/wbv2-sculpt-stroke-production.spec.ts", "WBV2-P1121-000 preserves bounded Sculpt stroke Main mutation"],
|
|
"WEBUI-NLA-STRIP": ["playwright", "tests/e2e/wbv2-nla-stack-production.spec.ts", "WBV2-P1112-000 preserves setNLAStack Main submission and rejects invalid actions"],
|
|
"NATIVE-OPERATOR-BRIDGE": ["playwright", "tests/e2e/wbv2-native-engine-production.spec.ts", "WBV2-P10-002 reaches the compiled Blender WASM Main through Chromium"],
|
|
"WEBUI-OPERATOR-PALETTE": ["playwright", "tests/e2e/smoke.spec.ts", "operator search executes context-filtered workspace, mode and Main commands"],
|
|
"MESH-EXTENDED-AUTHORING": ["playwright", "tests/e2e/wbv2-primitive-cube-batch-production.spec.ts", "native primitive cube batch preserves Main mutation and recovery"],
|
|
"MODIFIER-STACK-AUTHORING": ["playwright", "tests/e2e/wbv2-modifier-production.spec.ts", "WBV2-P9-002 production Chromium Modifier receipt is exact and fail-closed"],
|
|
"NODE-GRAPH-AUTHORING": ["playwright", "tests/e2e/wbv2-geometry-nodes-production.spec.ts", "WBV2-P13-002 binds Geometry Nodes graph evidence to compiled WASM Main"],
|
|
"RIG-POSE-AUTHORING": ["playwright", "tests/e2e/wbv2-rig-pose-production.spec.ts", "WBV2-P13-003 binds rig pose and skin evidence to compiled WASM Main"],
|
|
"ACTION-MARKER-AUTHORING": ["playwright", "tests/e2e/wbv2-action-pose-markers-production.spec.ts", "WBV2 Action pose markers are read from Blender Main and survive recovery/reopen"],
|
|
"SEQUENCER-AUTHORING": ["playwright", "tests/e2e/sequencer-codec-probe.spec.ts", "M11-09 probes IMAGE, SOUND and MOVIE bytes at runtime without extension guessing"],
|
|
"IO-ROUTE-COMPLETION": ["playwright", "tests/e2e/io-format-operator-production.spec.ts", "WBV2-P1109 binds Blender 5.2 IO operators to Chromium format behavior"],
|
|
"SCULPT-ADVANCED-AUTHORING": ["playwright", "tests/e2e/wbv2-paint-attributes-production.spec.ts", "WBV2-P16-002 binds paint attributes to compiled WASM Main"],
|
|
"OBJECT-EDITOR-COVERAGE": ["playwright", "tests/e2e/wbv2-object-transform-production.spec.ts", "WBV2-P23-002 binds applyObjectTransform to compiled WASM Main"],
|
|
"MESH-EDITOR-COVERAGE": ["playwright", "tests/e2e/wbv2-mesh-production.spec.ts", "WBV2-P9-001 production Chromium Mesh receipt is exact and fail-closed"],
|
|
"CURVE-SURFACE-COVERAGE": ["playwright", "tests/e2e/wbv2-surface-topology-production.spec.ts", "WBV2-P1134-001 preserves Surface topology transactions through Main recovery and reopen"],
|
|
"ARMATURE-EDITOR-COVERAGE": ["playwright", "tests/e2e/nla-operator.spec.ts", "M10-12 moves one NLA strip through Main, undo, redo and save/reopen"],
|
|
"ANIMATION-FCURVE-DRIVER-COVERAGE": ["playwright", "tests/e2e/wbv2-driver-reader-production.spec.ts", "WBV2 driver data is read from Blender Main and survives recovery/reopen"],
|
|
"SEQUENCER-COMPOSITOR-COVERAGE": ["playwright", "tests/e2e/compositor-main-reader-production.spec.ts", "WBV2-P1104-000 reads compositor NodeTree and links from Blender Main without JS execution"],
|
|
"PHYSICS-SIMULATION-COVERAGE": ["playwright", "tests/e2e/wbv2-physics-manifest-production.spec.ts", "WBV2-P1117-000 preserves Physics manifest Main persistence and validation"],
|
|
"TRACKING-MASK-COVERAGE": ["playwright", "tests/e2e/tracking-mask-production.spec.ts", "WBV2-P1127 reads Blender Mask data and selection context in Chromium"],
|
|
"GREASE-PENCIL-COVERAGE": ["playwright", "tests/e2e/wbv2-grease-pencil-strokes-production.spec.ts", "WBV2-P1114-000 preserves Grease Pencil stroke edits through recovery and reopen"],
|
|
"RENDER-CAMERA-LIGHT-COVERAGE": ["playwright", "tests/e2e/wbv2-lighting-fields-production.spec.ts", "WBV2-P15-002 binds camera, light, and world fields to compiled WASM Main"],
|
|
"ASSET-LIBRARY-COVERAGE": ["playwright", "tests/e2e/wbv2-asset-link-override-production.spec.ts", "WBV2-P11-003 enforces linked ownership and local append through compiled WASM Main"],
|
|
"RNA-DATABLOCK-REFLECTION": ["playwright", "tests/e2e/main-datablocks-reader-production.spec.ts", "WBV2 source reader exposes Blender Main datablock collections without JS simulation"],
|
|
"SERVER-OPERATOR-JOB": ["command", "node --test web/tests/unit/server-job-result-binding.test.mjs"],
|
|
"OPERATOR-ROUTE-PALETTE": ["playwright", "tests/e2e/io-format-ui-gate.spec.ts", "M12-05C exposes only matrix-declared file and operator routes"],
|
|
"OPERATOR-MACRO-COMPOSER": ["command", "node tools/web/check-web-engine-command-registry.mjs"],
|
|
"RNA-REFLECTION-EXTENDED": ["playwright", "tests/e2e/wbv2-scene-settings-expanded-production.spec.ts", "WBV2-P1129-001 covers the remaining Scene settings Main commands"],
|
|
"FEATURE-COVERAGE-DASHBOARD": ["command", "python3 my-tools/show_blender_web_scheduler.py"],
|
|
"SERVER-OPERATOR-HTTP-PROVIDER": ["command", "node --check tools/web/server-operator-job-server.mjs && python3 -m py_compile tools/web/server-operator-job.py"],
|
|
"SERVER-OPERATOR-SCHEMA-PALETTE": ["playwright", "tests/e2e/wbv2-texture-properties-production.spec.ts", "WBV2-P1139-001 preserves Texture properties through Main recovery and reopen"],
|
|
"BROWSER-EQUIVALENT-RUNTIME": ["command", "node tools/web/check-blender-feature-route-catalog.mjs"],
|
|
};
|
|
|
|
if (report.status !== "implemented" || report.implementationTasks.length !== 34) {
|
|
throw new Error("product implementation report is not the closed 34-task report");
|
|
}
|
|
const cases = report.implementationTasks.map((task, index) => {
|
|
const selector = selectors[task.id];
|
|
if (!selector) throw new Error(`missing one-pass smoke selector for ${task.id}`);
|
|
const [kind, fileOrCommand, title] = selector;
|
|
const route = task.commands?.some((command) => /ServerOperator|serverOperator|renderFrame|renderAnimation/u.test(command))
|
|
? "SERVER_NATIVE"
|
|
: task.id === "BROWSER-EQUIVALENT-RUNTIME" ? "BROWSER_EQUIVALENT" : "WEB_MAIN";
|
|
return {
|
|
ordinal: index + 1,
|
|
smokeId: `WBV2-SMOKE-${task.id}`,
|
|
featureId: task.id,
|
|
module: task.module,
|
|
representativeCommand: task.commands?.[0] ?? null,
|
|
route,
|
|
kind,
|
|
...(kind === "playwright" ? { testFile: fileOrCommand, testTitle: title } : { command: fileOrCommand }),
|
|
runOnce: true,
|
|
maxAttempts: 1,
|
|
status: "PLANNED",
|
|
};
|
|
});
|
|
const smokePlan = {
|
|
schemaVersion: 1,
|
|
planId: "WBV2-FEATURE-SMOKE-001",
|
|
operation: "ONE_PASS_FEATURE_SMOKE",
|
|
policy: {
|
|
browser: "chromium-only",
|
|
oneSmokePerFeature: true,
|
|
retryFailedFeature: false,
|
|
failureAction: "stop-after-report-and-create-focused-fix-task",
|
|
scope: "one representative positive/reachability smoke per implemented product feature; negative gates remain assertions of the selected production test",
|
|
excluded: ["full API matrix", "performance soak", "security/fuzz matrix", "cross-browser", "repeat of already passed feature"],
|
|
},
|
|
inventory: {
|
|
productFeatures: cases.length,
|
|
workflowModules: report.workflowModules.length,
|
|
sourceUnits: catalog.unitCount,
|
|
routeCounts: catalog.counts,
|
|
behavioralEvidence: catalog.behavioralEvidence,
|
|
wasmModules: wasmManifest.modules.map(({ id, lifecycle, preload }) => ({ id, lifecycle, preload })),
|
|
},
|
|
cases,
|
|
};
|
|
writeJson("tests/golden/WBV2/feature-smoke-plan.json", smokePlan);
|
|
process.stdout.write(`wbv2-feature-smoke-plan-written cases=${cases.length} modules=${report.workflowModules.length} sourceUnits=${catalog.unitCount}\n`);
|