Files

83 lines
3.7 KiB
TypeScript

import { expect, test } from "@playwright/test";
test("@visual deterministic example canvas", async ({ page }) => {
await page.goto("/examples/blender/");
await page.evaluate(() => window.fxnodeExample.ready);
await page.evaluate(() => window.fxnodeExample.rendered);
const canvas = page.locator("#graph");
await expect(canvas).toHaveAttribute("width", "1200");
await expect(canvas).toHaveAttribute("height", "640");
const evidence = await canvas.evaluate((element) => {
const context = (element as HTMLCanvasElement).getContext("2d");
if (!context) throw new Error("Canvas context missing");
const data = context.getImageData(0, 0, 1200, 640).data;
let background = 0,
nodePixels = 0,
linkPixels = 0;
for (let index = 0; index < data.length; index += 4) {
const r = data[index],
g = data[index + 1],
b = data[index + 2],
a = data[index + 3];
if (r === 29 && g === 31 && b === 35 && a === 255) background++;
if (r === 53 && g === 56 && b === 62 && a === 255) nodePixels++;
if ((r === 168 && g === 168 && b === 168) || (r === 98 && g === 179 && b === 79)) linkPixels++;
}
return { background, nodePixels, linkPixels };
});
expect(evidence.background).toBeGreaterThan(300_000);
expect(evidence.nodePixels).toBeGreaterThan(20_000);
expect(evidence.linkPixels).toBeGreaterThan(100);
const first = await canvas.screenshot();
const second = await canvas.screenshot();
expect(second.equals(first)).toBe(true);
await expect(canvas).toHaveScreenshot("phase-4-example.png", { animations: "disabled" });
await canvas.click({ position: { x: 380, y: 160 } });
await canvas.click({ position: { x: 560, y: 140 }, modifiers: ["Shift"] });
await page.evaluate(() => window.fxnodeExample.view!.whenRendered());
const selection = await canvas.evaluate((element) => {
const context = (element as HTMLCanvasElement).getContext("2d")!;
const pixels = context.getImageData(0, 0, 1200, 640).data;
let selected = 0,
expanded = 0;
for (let y = 150; y < 260; y++)
for (let x = 295; x < 485; x++) {
const index = (y * 1200 + x) * 4;
if (pixels[index] === 237 && pixels[index + 1] === 87 && pixels[index + 2] === 0 && pixels[index + 3] === 255) {
selected++;
if (x < 299) expanded++;
}
}
const socketIndex = (234 * 1200 + 300) * 4;
return { selected, expanded, socket: Array.from(pixels.slice(socketIndex, socketIndex + 4)) };
});
expect(selection.selected).toBeGreaterThan(100);
expect(selection.expanded).toBe(0);
expect(selection.socket).toEqual([168, 168, 168, 255]);
});
test("@visual distant zoom keeps text inside scaled nodes", async ({ page }) => {
await page.goto("/examples/blender/");
await page.evaluate(() => window.fxnodeExample.ready);
const canvas = page.locator("#graph");
await canvas.hover({ position: { x: 600, y: 320 } });
await page.mouse.wheel(0, 900);
await page.evaluate(() => window.fxnodeExample.view!.whenRendered());
await expect(canvas).toHaveScreenshot("zoomed-out-lod.png", { animations: "disabled" });
});
test("@visual Blender-style numeric fields and text editing", async ({ page }) => {
await page.goto("/examples/blender/control-test/");
await page.evaluate(() => window.controlTest.ready);
const canvas = page.locator("#controls");
await expect(canvas).toHaveScreenshot("numeric-fields.png", { animations: "disabled" });
await canvas.click({ position: { x: 196, y: 147 } });
await expect(canvas).toHaveScreenshot("numeric-editing.png", { animations: "disabled" });
await canvas.press("Escape");
await canvas.click({ position: { x: 1003, y: 147 } });
await expect(canvas).toHaveScreenshot("color-picker.png", { animations: "disabled" });
});