// @vitest-environment jsdom import React, { act } from "react"; import { createRoot } from "react-dom/client"; import { describe, it, expect, beforeAll, beforeEach, afterEach } from "vitest"; import { FlowCanvas } from "@/shared/components/flow/FlowCanvas"; beforeAll(() => { // ReactFlow relies on ResizeObserver, which jsdom does not implement. globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as unknown as typeof ResizeObserver; }); const containers: HTMLElement[] = []; function mount(ui: React.ReactElement): HTMLElement { const container = document.createElement("div"); document.body.appendChild(container); containers.push(container); const root = createRoot(container); act(() => { root.render(ui); }); return container; } beforeEach(() => { ( globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean } ).IS_REACT_ACT_ENVIRONMENT = true; }); afterEach(() => { while (containers.length > 0) { containers.pop()?.remove(); } document.body.innerHTML = ""; }); const nodes = [ { id: "a", position: { x: 0, y: 0 }, data: { label: "A" } }, { id: "b", position: { x: 120, y: 0 }, data: { label: "B" } }, ]; const edges = [{ id: "a-b", source: "a", target: "b" }]; describe("FlowCanvas (U0 — shared ReactFlow wrapper)", () => { it("renders the canvas with Controls and hides the attribution", () => { const container = mount(); expect(container.querySelector(".react-flow")).toBeTruthy(); expect(container.querySelector(".react-flow__controls")).toBeTruthy(); // proOptions.hideAttribution => the attribution element must not render. expect(container.querySelector(".react-flow__attribution")).toBeNull(); }); it("applies the provided container className for sizing/theming", () => { const container = mount( ); expect(container.querySelector(".omni-test-canvas")).toBeTruthy(); }); });