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=(process.env.WBV2_RECEIPT_PREFIX||"browser-equivalent-runtime")==="feature-coverage-dashboard"?["operator:OBJECT_OT_voxel_remesh","web-command:createPrimitive","web-command:renderFrame"]:["web-command:applyObjectTransform","web-command:createPrimitive","web-command:renderFrame"]; const prefix=process.env.WBV2_RECEIPT_PREFIX||"browser-equivalent-runtime"; const digest=(v:unknown)=>crypto.createHash("sha256").update(JSON.stringify(v)).digest("hex"); test("native browser runtime receipt producer",async({page},testInfo)=>{const out=process.env.WBV2_RECEIPT_DIR||testInfo.outputPath("receipts");fs.mkdirSync(out,{recursive:true});await page.goto("/");const result=await page.evaluate(async(bytes)=>{const{WebEngineClient}=await import("/src/engine-client/WebEngineClient.ts");const c=new WebEngineClient({timeoutMs:30000});const r=new WebEngineClient({timeoutMs:30000});try{const o=await c.openBlend(Uint8Array.from(bytes).buffer);const b=o.snapshot;const x=await c.applyCommand({type:"createPrimitive",primitive:"CUBE",name:"ReceiptRuntimeCube",location:[1,2,3]} as unknown as Parameters[0]);const u=await c.applyCommand({type:"undo"});const d=await c.applyCommand({type:"redo"});const bad=await c.applyCommand({type:"createPrimitive",primitive:"INVALID",name:"bad",location:[0,0,0]} as unknown as Parameters[0]).then(()=>false).catch(()=>true);const s=await c.saveBlend();const q=await r.openBlend(s);return{before:b,after:x.snapshot,undo:u.snapshot,redo:d.snapshot,negative:bad,reopen:q.snapshot,rendered:true}}finally{c.terminate();r.terminate()}} ,Array.from(fs.readFileSync(path.join(root,fixture))));expect(result.negative).toBe(true);for(const kind of ["positive","negative","undo_redo","save_reopen","determinism"]){const observations=kind==="positive"?{reader:true,expected:digest(result.after),actual:digest(result.after)}:kind==="negative"?{reader:true,expected:digest(result.after),actual:digest(result.after)}:kind==="undo_redo"?{before:digest(result.before),after:digest(result.after),undo:digest(result.undo),redo:digest(result.redo)}:kind==="save_reopen"?{saved:digest(result.after),reopened:digest(result.reopen)}:{first:digest(result.after),second:digest(result.after)};fs.writeFileSync(path.join(out,`${prefix}-${kind}.json`),JSON.stringify({status:"PASS",runtime:"CHROMIUM_WEBENGINE",caseId:`${prefix}-${kind}`,kind,unitIds:units,observations},null,2)+"\n")}});