Files
workinf_Blender_Wasm/web/tests/e2e/viewport-consistency.spec.ts
mes123456 0fe8d2bb56
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

62 lines
3.8 KiB
TypeScript

import { expect, test } from "@playwright/test";
import path from "node:path";
const basicBlend = path.resolve(import.meta.dirname, "../../../tests/files/web/basic_scene.blend");
for (const offscreen of [false, true]) {
test(`M7-15 ${offscreen ? "Offscreen" : "main-thread"} viewport uses the shared camera and selection contract`, async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 720 });
await page.goto(offscreen ? "/?offscreen=1" : "/");
await page.setInputFiles("[data-testid=blend-file-input]", basicBlend);
await expect(page.getByText("BasicCube", { exact: true })).toBeVisible({ timeout: 20_000 });
const canvas = page.locator("canvas.viewport-canvas");
await expect(canvas).toHaveAttribute("data-renderer-backend", offscreen ? "offscreen-worker" : "webgl-pbr");
if (offscreen) await expect.poll(async () => Number(await canvas.getAttribute("data-renderer-pixels") ?? "0"), { timeout: 20_000 }).toBeGreaterThan(0);
const initial = await canvas.evaluate((element) => ({
position: element.getAttribute("data-camera-position"),
target: element.getAttribute("data-camera-target"),
yaw: element.getAttribute("data-camera-yaw"),
pitch: element.getAttribute("data-camera-pitch"),
distance: element.getAttribute("data-camera-distance"),
}));
expect(initial.position).toBe("4.219781,-4.219781,3.658811");
expect(initial.target).toBe("0,0,0");
expect(initial.yaw).toBe("-0.785398");
expect(initial.pitch).toBe("0.550000");
expect(initial.distance).toBe("7.000000");
await canvas.evaluate((element, useOffscreen) => {
const bounds = element.getBoundingClientRect();
const x = bounds.left + bounds.width / 2;
const y = bounds.top + bounds.height / 2;
element.dispatchEvent(new MouseEvent("click", { bubbles: true, clientX: x, clientY: y }));
if (useOffscreen) {
element.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, clientX: x, clientY: y, pointerId: 11, buttons: 1 }));
element.dispatchEvent(new PointerEvent("pointerup", { bubbles: true, clientX: x, clientY: y, pointerId: 11, buttons: 0 }));
}
}, offscreen);
await expect(page.locator(".blender-app")).toHaveAttribute("data-selected-object-ids", /.+/);
await canvas.evaluate((element) => element.dispatchEvent(new WheelEvent("wheel", { bubbles: true, cancelable: true, deltaY: 120 })));
await expect.poll(async () => await canvas.getAttribute("data-camera-distance"), { timeout: 5_000 }).not.toBe(initial.distance);
const zoomed = await canvas.getAttribute("data-camera-distance");
expect(Number(zoomed)).toBeCloseTo(7 * Math.exp(0.12), 4);
});
}
test("M7-15 main and Offscreen camera state stays identical for the same orbit input", async ({ browser }) => {
const states: Array<Record<string, string | null>> = [];
for (const offscreen of [false, true]) {
const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
await page.goto(offscreen ? "/?offscreen=1" : "/");
const canvas = page.locator("canvas.viewport-canvas");
if (offscreen) await expect.poll(async () => Number(await canvas.getAttribute("data-renderer-pixels") ?? "0"), { timeout: 20_000 }).toBeGreaterThan(0);
await canvas.evaluate((element) => element.dispatchEvent(new WheelEvent("wheel", { bubbles: true, cancelable: true, deltaY: -80 })));
await expect.poll(async () => await canvas.getAttribute("data-camera-distance"), { timeout: 5_000 }).not.toBe("7.000000");
states.push(await canvas.evaluate((element) => ({ position: element.getAttribute("data-camera-position"), target: element.getAttribute("data-camera-target"), yaw: element.getAttribute("data-camera-yaw"), pitch: element.getAttribute("data-camera-pitch"), distance: element.getAttribute("data-camera-distance") })));
await page.close();
}
expect(states[0]).toEqual(states[1]);
});