Files
workinf_Blender_Wasm/web/tests/e2e/wbv2-convex-hull-native-production.spec.ts
mes123456 d1e6b63d54
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender feature-gap work, docs and tests
- 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>
2026-11-11 10:46:55 +08:00

41 lines
2.6 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"));
const receiptDir = path.join(root, "tests/golden/WBV2-P1425-001/verification");
test("mesh.convex_hull runs through the native operator channel", 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 steps: Record<string, unknown>[] = [];
try {
const open = await client.openBlend(Uint8Array.from(bytes).buffer);
const node = open.snapshot.nodes.find((n) => n.type === "MESH");
if (!node) throw new Error("mesh fixture is missing");
let revision = open.snapshot.revision;
const invoke = async (operator: string, properties: Record<string, unknown>, mode: string) => {
const payload = JSON.stringify({ operator, properties, baseRevision: revision, sceneName: open.snapshot.scenes?.[0]?.name ?? "Scene", areaType: "VIEW_3D", mode, 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 out = await client.executeEmbeddedPython(source, "ConvexHullOperator.py", false);
revision = out.snapshot.revision;
steps.push({ operator, state: out.python.state, error: out.python.error ?? null, revision });
};
await invoke("object.mode_set", { mode: "EDIT", toggle: false }, "OBJECT");
await invoke("mesh.select_all", { action: "SELECT" }, "EDIT");
await invoke("mesh.convex_hull", {}, "EDIT");
return { ok: true, steps };
} catch (error) {
const e = error as { message?: string; code?: string };
return { ok: false, steps, message: e?.message, code: e?.code };
} finally { client.terminate(); }
}, { bytes: Array.from(fixture) });
fs.mkdirSync(receiptDir, { recursive: true });
fs.writeFileSync(path.join(receiptDir, "convex-hull-native-production.json"), JSON.stringify({ schemaVersion: 1, browser: "chromium", scope: "Edit mode -> mesh.select_all -> desktop_operator(mesh.convex_hull) -> Main/SceneIR", ...result }, null, 2));
expect(result.ok).toBe(true);
expect(result.steps.at(-1)).toMatchObject({ operator: "mesh.convex_hull", state: "DONE", error: null });
});