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",
},
);
});