import { render, screen } from '@testing-library/react'; import { WorkflowCanvas } from '../WorkflowCanvas'; import type { WorkflowGraph, WfExecutionView } from '../types'; // xyflow + DualPaneWorkspace consumers rely on browser APIs jsdom omits. beforeAll(() => { Object.defineProperty(window, 'matchMedia', { writable: true, value: (query: string) => ({ matches: false, media: query, onchange: null, addEventListener: () => {}, removeEventListener: () => {}, addListener: () => {}, removeListener: () => {}, dispatchEvent: () => false, }), }); // xyflow measures nodes via ResizeObserver. global.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as never; }); const graph: WorkflowGraph = { id: 'wf1', name: 'Sample', nodes: [ { id: 'a', name: 'Start run', type: 'trigger.event', position: { x: 0, y: 0 } }, { id: 'b', name: 'Email user', type: 'action.email', position: { x: 0, y: 120 } }, ], edges: [{ source: 'a', target: 'b' }], }; describe('WorkflowCanvas', () => { it('renders a node per graph node', () => { render(); expect(screen.getByText('Start run')).toBeInTheDocument(); expect(screen.getByText('Email user')).toBeInTheDocument(); }); it('applies a status overlay from a WfExecutionView', () => { const execution: WfExecutionView = { executionId: 'e1', status: 'running', nodes: { a: { nodeId: 'a', status: 'success' }, b: { nodeId: 'b', status: 'running' }, }, }; render(); // node b shows the running badge, node a shows success expect(screen.getByText('Running')).toBeInTheDocument(); expect(screen.getByText('Success')).toBeInTheDocument(); }); });