- update native web_engine sources and rebuilt wasm artifacts - add task cards, status notes and tooling scripts - add web e2e specs, tutorial UI sources and tutorial assets - sync golden task manifests and audit records Co-Authored-By: Claude Code <noreply@anthropic.com>
61 lines
4.0 KiB
TypeScript
61 lines
4.0 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
const root = path.resolve(import.meta.dirname, "../../..");
|
|
const fixture = fs.readFileSync(path.join(root, "tests/files/web/basic_scene.blend"));
|
|
test("collection instances publish their collection and render member copies", async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
await page.goto("/?engine=manual");
|
|
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 });
|
|
try {
|
|
const open = await client.openBlend(Uint8Array.from(bytes).buffer);
|
|
const node = open.snapshot.nodes.find((n) => n.name === "BasicCube");
|
|
const collection = open.snapshot.collections.find((item) => item.name === "Collection");
|
|
if (!node || !collection) throw new Error("fixture collection or mesh is missing");
|
|
const payload = JSON.stringify({ operator: "object.collection_instance_add", properties: { name: collection.name }, baseRevision: open.snapshot.revision, sceneName: open.snapshot.scenes?.[0]?.name ?? "Scene", areaType: "VIEW_3D", mode: "OBJECT", native: true, selectedObjects: [node.name], activeObject: node.name, meshSelection: null, nonMeshSelection: null });
|
|
const source = `import json, web_blender\nweb_blender.desktop_operator(json.loads(${JSON.stringify(payload)}))`;
|
|
const added = await client.executeEmbeddedPython(source, "CollectionInstance.py", false);
|
|
const instance = added.snapshot.nodes.find((item) => item.instanceCollectionId);
|
|
if (!instance) throw new Error("collection instance field was not published");
|
|
const members = added.snapshot.nodes.filter((item) => collection.objectIds.includes(item.id));
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = 320;
|
|
canvas.height = 240;
|
|
document.body.appendChild(canvas);
|
|
const { ViewportRenderer } = await import("/src/three-adapter/viewport.ts");
|
|
const renderer = new ViewportRenderer(canvas);
|
|
renderer.setSnapshot(added.snapshot, [], []);
|
|
const renderedCopies = Number(canvas.dataset.collectionInstanceObjects ?? "0");
|
|
const renderedHelpers = Number(canvas.dataset.renderHelpers ?? "0");
|
|
renderer.dispose();
|
|
canvas.remove();
|
|
const saved = await client.saveBlend();
|
|
client.terminate();
|
|
const reopen = await reopened.openBlend(saved);
|
|
const reopenedInstance = reopen.snapshot.nodes.find((item) => item.instanceCollectionId);
|
|
return {
|
|
state: added.python.state,
|
|
collectionId: collection.id,
|
|
instance: { id: instance.id, name: instance.name, type: instance.type, instanceCollectionId: instance.instanceCollectionId, worldMatrix: instance.worldMatrix },
|
|
memberIds: members.map((item) => item.id),
|
|
renderedCopies,
|
|
renderedHelpers,
|
|
reopenedCollectionId: reopenedInstance?.instanceCollectionId ?? null,
|
|
};
|
|
} catch (error) { const e = error as { message?: string; code?: string }; return { error: e?.message, code: e?.code }; }
|
|
finally { client.terminate(); reopened.terminate(); }
|
|
}, { bytes: Array.from(fixture) });
|
|
fs.writeFileSync(path.join(root, "tests/golden/WBV2-P1425-001/verification/collection-instance-production.json"), JSON.stringify({ schemaVersion: 1, browser: "chromium", scope: "collection instance SceneIR reference + Web viewport display copies + save/reopen", ...result }, null, 2));
|
|
expect(result.error).toBeUndefined();
|
|
expect(result.state).toBe("DONE");
|
|
expect(result.instance?.instanceCollectionId).toBe(result.collectionId);
|
|
expect(result.instance?.type).toBe("EMPTY");
|
|
expect(result.memberIds?.length).toBeGreaterThan(0);
|
|
expect(result.renderedCopies).toBeGreaterThanOrEqual(3);
|
|
expect(result.renderedHelpers).toBeGreaterThan(0);
|
|
expect(result.reopenedCollectionId).toBe(result.collectionId);
|
|
});
|