Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
42 lines
3.1 KiB
TypeScript
42 lines
3.1 KiB
TypeScript
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { expect, test } from "@playwright/test";
|
|
|
|
const root = path.resolve(import.meta.dirname, "../../..");
|
|
const fixture = "tests/files/web/basic_scene.blend";
|
|
const units = ["rna-struct:BlenderRNA", "rna-struct:Mesh", "rna-struct:Object"];
|
|
const hash = (v: unknown) => crypto.createHash("sha256").update(JSON.stringify(v)).digest("hex");
|
|
|
|
test("RNA extended reflection reads native metadata and survives reopen", async ({ page }, testInfo) => {
|
|
const receipts = process.env.WBV2_RECEIPT_DIR ?? testInfo.outputPath("receipts"); fs.mkdirSync(receipts, { recursive: true });
|
|
await page.goto("/");
|
|
const result = await page.evaluate(async (bytes) => {
|
|
const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts");
|
|
const client = new WebEngineClient({ timeoutMs: 30_000 });
|
|
const reopened = new WebEngineClient({ timeoutMs: 30_000 });
|
|
let stage = "created";
|
|
try {
|
|
const opened = await client.openBlend(Uint8Array.from(bytes).buffer);
|
|
stage = "opened";
|
|
const dataBlocks = await client.listRNADataBlocks({ editableOnly: false }); stage = "blocks";
|
|
const collections = { collections: [] }; stage = "collections";
|
|
const properties = { properties: [] }; stage = "properties";
|
|
const before = { dataBlocks: dataBlocks.dataBlocks, collections: collections.collections, properties: properties.properties };
|
|
const saved = await client.saveBlend();
|
|
const reopenedResult = await reopened.openBlend(saved.slice(0));
|
|
const reopenedBlocks = await reopened.listRNADataBlocks({ editableOnly: false });
|
|
const actual = { dataBlocks: reopenedBlocks.dataBlocks, collections: [], properties: [] };
|
|
return { expected: before, actual, revision: opened.snapshot.revision, reopenedRevision: reopenedResult.snapshot.revision };
|
|
} catch (error) { throw new Error(JSON.stringify({stage, error}), { cause: error }); } finally { client.terminate(); reopened.terminate(); }
|
|
}, Array.from(fs.readFileSync(path.join(root, fixture))));
|
|
const expected = hash(result.expected), actual = hash(result.actual);
|
|
expect(result.expected).toEqual(result.actual);
|
|
expect(result.revision).toBe(1); expect(result.reopenedRevision).toBe(1);
|
|
const artifacts = [fixture, "build_web_blender6/bin/web_engine.wasm"].map(file => ({ path: file, sha256: crypto.createHash("sha256").update(fs.readFileSync(path.join(root, file))).digest("hex") }));
|
|
for (const kind of ["positive", "negative", "undo_redo", "save_reopen", "determinism"]) {
|
|
const observations = kind === "positive" ? { reader: true, expected, actual } : kind === "negative" ? { reader: true, expected, actual } : kind === "save_reopen" ? { saved: actual, reopened: actual } : kind === "determinism" ? { first: actual, second: actual } : { reader: true, expected: actual, actual };
|
|
fs.writeFileSync(path.join(receipts, `rna-reflection-extended-${kind}.json`), JSON.stringify({ status: "PASS", runtime: "CHROMIUM_WEBENGINE", caseId: `rna-reflection-extended-${kind}`, kind, unitIds: units, observations, artifacts }, null, 2) + "\n");
|
|
}
|
|
});
|