Amp-Thread-ID: https://ampcode.com/threads/T-019f9d91-77c1-7206-a60f-ed6554ce92ab Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
83 lines
3.7 KiB
TypeScript
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" });
|
|
});
|