Files
webeditor3d/tests/e2e/whitebox-component-selection.e2e.ts

186 lines
5.9 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { createBoxBrush } from "../../src/document/brushes";
import { createEmptySceneDocument } from "../../src/document/scene-document";
import {
clickViewportAtRatio,
getEditorStoreSnapshot,
replaceSceneDocument
} from "./viewport-test-helpers";
test("whitebox component selection modes keep object picking intentional across perspective and orthographic panes", async ({ page }) => {
const pageErrors: string[] = [];
const consoleErrors: string[] = [];
page.on("pageerror", (error) => {
pageErrors.push(error.message);
});
page.on("console", (message) => {
if (message.type() === "error") {
consoleErrors.push(message.text());
}
});
await page.goto("/");
await page.evaluate((storageKey) => {
window.localStorage.removeItem(storageKey);
}, "webeditor3d.scene-document-draft");
await page.reload();
test.skip((await page.getByText("Viewport Unavailable").count()) > 0, "WebGL is unavailable in this Playwright environment.");
const brush = createBoxBrush({
id: "brush-selection-modes-main",
name: "Selection Fixture",
center: {
x: 0,
y: 1,
z: 0
},
size: {
x: 2,
y: 2,
z: 2
}
});
await replaceSceneDocument(page, {
...createEmptySceneDocument({ name: "Selection Modes Scene" }),
brushes: {
[brush.id]: brush
}
});
await page.evaluate(({ target }) => {
const store = (window as Window & {
__webeditor3dEditorStore?: {
getState(): {
viewportPanels: {
topLeft: {
cameraState: {
target: { x: number; y: number; z: number };
perspectiveOrbit: { radius: number; theta: number; phi: number };
orthographicZoom: number;
};
};
};
};
setViewportPanelCameraState(panelId: "topLeft", cameraState: {
target: { x: number; y: number; z: number };
perspectiveOrbit: { radius: number; theta: number; phi: number };
orthographicZoom: number;
}): void;
};
}).__webeditor3dEditorStore;
if (store === undefined) {
throw new Error("Editor store debug hook is unavailable.");
}
const topLeftCameraState = store.getState().viewportPanels.topLeft.cameraState;
store.setViewportPanelCameraState("topLeft", {
...topLeftCameraState,
target,
perspectiveOrbit: {
radius: 4.5,
theta: 0.72,
phi: 1.08
}
});
}, { target: brush.center });
await expect(page.getByTestId("whitebox-selection-mode-object")).toHaveAttribute("aria-pressed", "true");
await clickViewportAtRatio(page, "topLeft", 0.5, 0.52);
let snapshot = await getEditorStoreSnapshot(page);
expect(snapshot.whiteboxSelectionMode).toBe("object");
expect(snapshot.selection).toMatchObject({
kind: "brushes",
ids: [brush.id]
});
await page.getByTestId("viewport-layout-quad").click();
await page.evaluate(({ target }) => {
const store = (window as Window & {
__webeditor3dEditorStore?: {
getState(): {
viewportPanels: {
topRight: {
cameraState: {
target: { x: number; y: number; z: number };
perspectiveOrbit: { radius: number; theta: number; phi: number };
orthographicZoom: number;
};
};
};
};
setViewportPanelViewMode(panelId: "topRight", viewMode: "top"): void;
setViewportPanelCameraState(panelId: "topRight", cameraState: {
target: { x: number; y: number; z: number };
perspectiveOrbit: { radius: number; theta: number; phi: number };
orthographicZoom: number;
}): void;
};
}).__webeditor3dEditorStore;
if (store === undefined) {
throw new Error("Editor store debug hook is unavailable.");
}
const topRightCameraState = store.getState().viewportPanels.topRight.cameraState;
store.setViewportPanelViewMode("topRight", "top");
store.setViewportPanelCameraState("topRight", {
...topRightCameraState,
target,
orthographicZoom: 8
});
}, { target: brush.center });
await page.getByTestId("whitebox-selection-mode-face").click();
await expect(page.getByTestId("whitebox-selection-mode-face")).toHaveAttribute("aria-pressed", "true");
await clickViewportAtRatio(page, "topRight", 0.5, 0.5);
snapshot = await getEditorStoreSnapshot(page);
expect(snapshot.whiteboxSelectionMode).toBe("face");
expect(snapshot.selection).toMatchObject({
kind: "brushFace",
brushId: brush.id,
faceId: "posY"
});
await page.getByTestId("whitebox-selection-mode-edge").click();
await expect(page.getByTestId("whitebox-selection-mode-edge")).toHaveAttribute("aria-pressed", "true");
await clickViewportAtRatio(page, "topRight", 0.5, 0.12);
snapshot = await getEditorStoreSnapshot(page);
expect(snapshot.whiteboxSelectionMode).toBe("edge");
expect(snapshot.selection).toMatchObject({
kind: "brushEdge",
brushId: brush.id,
edgeId: "edgeX_posY_negZ"
});
await page.getByTestId("whitebox-selection-mode-vertex").click();
await expect(page.getByTestId("whitebox-selection-mode-vertex")).toHaveAttribute("aria-pressed", "true");
await clickViewportAtRatio(page, "topRight", 0.88, 0.12);
snapshot = await getEditorStoreSnapshot(page);
expect(snapshot.whiteboxSelectionMode).toBe("vertex");
expect(snapshot.selection).toMatchObject({
kind: "brushVertex",
brushId: brush.id,
vertexId: "posX_posY_negZ"
});
await page.getByTestId("whitebox-selection-mode-object").click();
await clickViewportAtRatio(page, "topRight", 0.5, 0.5);
snapshot = await getEditorStoreSnapshot(page);
expect(snapshot.whiteboxSelectionMode).toBe("object");
expect(snapshot.selection).toMatchObject({
kind: "brushes",
ids: [brush.id]
});
expect(pageErrors).toEqual([]);
expect(consoleErrors).toEqual([]);
});