import { expect, test } from "@playwright/test"; import { expectFiniteCanvasObservation, expectInfiniteCanvasObservation, expectToolcraftInfinityCanvasBackgroundEvidence, expectToolcraftInfinityCanvasVideoExportEvidence, observeInfinityCanvas, } from "./browser-infinity-canvas-evidence"; import { expectToolcraftInfinityCanvasSvgExportEvidence } from "./browser-infinity-canvas-svg-evidence"; import { createToolcraftSvgFixtureDownload } from "./svg-download-test-fixtures"; import { inspectToolcraftSvgDownload } from "./svg-artifact-inspection"; import { readToolcraftCanvasViewport, zoomToolcraftCanvasViewport, } from "./performance-canvas-helpers"; const partialFiniteControlPresence = [ { aspectRatio: true, height: false, width: false }, { aspectRatio: false, height: true, width: false }, { aspectRatio: false, height: false, width: true }, { aspectRatio: true, height: true, width: false }, { aspectRatio: true, height: false, width: true }, { aspectRatio: false, height: true, width: true }, ] as const; test("Infinity canvas evidence rejects every partial finite-control presence", async ({ page, }) => { const common = { finiteControlSize: { height: 200, width: 320 }, overflow: "visible", productScene: { output: null, viewportRect: null, worldRect: null, }, productSceneStatus: "empty" as const, viewport: { offsetX: 0, offsetY: 0, zoom: 100 }, }; for (const finiteControlsPresent of partialFiniteControlPresence) { const controls = Object.entries({ "canvas.aspectRatio": finiteControlsPresent.aspectRatio, "canvas.size.height": finiteControlsPresent.height, "canvas.size.width": finiteControlsPresent.width, }) .filter(([, present]) => present) .map( ([target]) => ``, ) .join(""); await page.setContent(`${controls}
`); const observed = await observeInfinityCanvas(page); expect(observed.finiteControlsPresent).toEqual(finiteControlsPresent); expect(() => expectInfiniteCanvasObservation(observed)).toThrow(); expect(() => expectFiniteCanvasObservation({ ...common, artboardPresent: true, canvasMode: "finite", finiteCanvasSize: { height: 200, width: 320 }, finiteControlsPresent, overflow: "hidden", }), ).toThrow(); } }); test("toolcraft Infinity canvas observation reads runtime-owned geometry", async ({ page, }) => { await page.setContent(`
`); const observation = await observeInfinityCanvas(page); expect(observation.finiteControlsPresent).toEqual({ aspectRatio: false, height: false, width: false, }); expectInfiniteCanvasObservation(observation, { height: 400, width: 640, x: -320, y: -200, }); expect(observation.viewport).toEqual({ offsetX: 12, offsetY: -8, zoom: 125, }); expect(observation.productScene).toEqual({ output: { kind: "canvas", backingHeight: 400, backingWidth: 640 }, viewportRect: { height: 500, width: 800, x: 12, y: 42, }, worldRect: { height: 400, width: 640, x: -320, y: -200 }, }); }); test("toolcraft canvas viewport observation reads the runtime world transform", async ({ page, }) => { await page.setContent(`
`); await expect(readToolcraftCanvasViewport(page)).resolves.toEqual({ offsetX: 96, offsetY: -64, zoom: 125, }); }); test("toolcraft canvas zoom helper performs only the requested direction", async ({ page, }) => { await page.setContent(` `); await zoomToolcraftCanvasViewport(page, { direction: "in", repetitions: 2, }); await expect(page.locator("body")).toHaveAttribute("data-zoom-in", "2"); await expect(page.locator("body")).not.toHaveAttribute("data-zoom-out"); await zoomToolcraftCanvasViewport(page, { direction: "out" }); await expect(page.locator("body")).toHaveAttribute("data-zoom-out", "1"); }); test("toolcraft Infinity canvas video evidence compares decoded envelopes", async () => { await expectToolcraftInfinityCanvasVideoExportEvidence( { finite: { byteLength: 1024, durationMs: 1000, height: 1350, width: 1080, }, infinite: { byteLength: 768, durationMs: 1000, height: 640, width: 640, }, }, { expectedFiniteSize: { height: 1350, width: 1080 }, expectedInfiniteSize: { height: 640, width: 640 }, requirementId: "fixture.infinity.video", target: "canvas.infinity", }, ); }); test("toolcraft Infinity canvas SVG evidence compares inspected vector envelopes", async ({ page, }) => { const source = (width: number, height: number, x: number, y: number) => ``; const finite = await inspectToolcraftSvgDownload({ download: await createToolcraftSvgFixtureDownload( page, source(1080, 1350, 0, 0), "finite.svg", ), page, }); const infinite = await inspectToolcraftSvgDownload({ download: await createToolcraftSvgFixtureDownload( page, source(640, 400, -320, -200), "infinite.svg", ), page, }); await expectToolcraftInfinityCanvasSvgExportEvidence( { finite: finite.inspection, infinite: infinite.inspection, }, { expectedFiniteSize: { height: 1350, width: 1080 }, expectedInfiniteSize: { height: 400, width: 640 }, requirementId: "fixture.infinity.svg", target: "canvas.infinity", }, ); }); test("toolcraft Infinity canvas background evidence proves viewport color and dependency", async () => { await expectToolcraftInfinityCanvasBackgroundEvidence( { backgroundExcluded: { backgroundEnabled: false, canvasMode: "finite", infinityDisabled: true, runtimeBackgroundColor: null, viewportBackgroundColor: "rgb(20, 20, 20)", viewportMatchesRuntimeColor: false, }, backgroundRestored: { backgroundEnabled: true, canvasMode: "finite", infinityDisabled: false, runtimeBackgroundColor: null, viewportBackgroundColor: "rgb(20, 20, 20)", viewportMatchesRuntimeColor: false, }, infinite: { backgroundEnabled: true, canvasMode: "infinite", infinityDisabled: false, runtimeBackgroundColor: "#D4CECA", viewportBackgroundColor: "rgb(212, 206, 202)", viewportMatchesRuntimeColor: true, }, }, { expectedBackgroundColor: "#D4CECA", requirementId: "fixture.background", target: "export.includeBackground", }, ); });