import { expect, test } from "@playwright/test"; import fs from "node:fs"; import path from "node:path"; const root = path.resolve(import.meta.dirname, "../../.."); const expected = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/M10-08/shader-compile-key.json"), "utf8")); test("M10-08 compileKey changes with texture identity and color space", async ({ page }) => { await page.goto("/"); const result = await page.evaluate(async () => { const { createPBRMaterial } = await import("/src/three-adapter/pbr.ts"); const source = { id: "material:key", name: "Key", baseColor: [0.2, 0.3, 0.4, 1] as [number, number, number, number], roughness: 0.5, metallic: 0, emissionColor: [0, 0, 0, 1] as [number, number, number, number], alpha: 1, ior: 1.45, nodes: [ { id: "image", type: "IMAGE_TEXTURE" as const, name: "Image", imageId: "image:key" }, { id: "normal", type: "NORMAL_MAP" as const, name: "Normal" }, { id: "principled", type: "PRINCIPLED" as const, name: "Principled" }, { id: "output", type: "OUTPUT" as const, name: "Output" }, ], links: [ { fromNodeId: "image", fromSocket: "Color", toNodeId: "normal", toSocket: "Color" }, { fromNodeId: "normal", fromSocket: "Normal", toNodeId: "principled", toSocket: "Normal" }, { fromNodeId: "principled", fromSocket: "BSDF", toNodeId: "output", toSocket: "Surface" }, ], }; const identity = { assetId: "asset:key-v1", sha256: "d".repeat(64), colorSpace: "NON_COLOR" as const }; const first = createPBRMaterial(source, false, { imageIds: new Set(["image:key"]), textureIdentities: new Map([["image:key", identity]]) }); const changed = createPBRMaterial(source, false, { imageIds: new Set(["image:key"]), textureIdentities: new Map([["image:key", { ...identity, sha256: "e".repeat(64) }]]) }); const linear = createPBRMaterial(source, false, { imageIds: new Set(["image:key"]), textureIdentities: new Map([["image:key", { ...identity, colorSpace: "LINEAR" as const }]]) }); const firstReport = first.userData.shaderCompile; const changedReport = changed.userData.shaderCompile; const linearReport = linear.userData.shaderCompile; first.dispose(); changed.dispose(); linear.dispose(); return { status: firstReport.status, key: firstReport.compileKey, changed: changedReport.compileKey, linear: linearReport.compileKey }; }); expect(result.status).toBe("COMPILED"); expect(result.key).toMatch(/^[0-9a-f]{64}$/); expect(result.changed).not.toBe(result.key); expect(result.linear).not.toBe(result.key); expect(expected.keyDigest).toBe("sha256"); });