1

I'm running into problems when testing a component that uses the react-flow package. In the actual implementation, the selected elements get passed to my onSelectionChange handler perfectly, but when testing it through react-testing-library, the elements are always empty. This is what its currently console logging when running the test Selection changed { nodes: [], edges: [] }.

Is there any way to get around this problem?

Here is my code:

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import ReactFlow from 'reactflow';
import { mockReactFlow } from '../../setupTests';

function MyComponent() {
  const onSelectionChange = (elements: any) => {
    console.log('Selection changed', elements);
  };

  const nodes = [
    { id: 'node-1', type: 'default', data: { label: 'Node 1' }, position: { x: 0, y: 0 } },
    { id: 'node-2', type: 'default', data: { label: 'Node 2' }, position: { x: 200, y: 0 } },
  ];

  return <ReactFlow nodes={nodes} onSelectionChange={onSelectionChange} />;
}

describe('ReactFlow', () => {
  beforeEach(() => {
    mockReactFlow()
})
  test('should trigger onSelectionChange event', async () => {
    render(<MyComponent />);
  
    const node = await screen.findByText('Node 1');
  
    fireEvent.click(node);
  });
});

You may be wondering what mockReactFlow does. That was a recommendation by the react-flow documentation itself to help test react-flow components. Here is that implementation straight from the documentation:

export const mockReactFlow = () => {
    if (init) return
    init = true

    global.ResizeObserver = ResizeObserver

    global.DOMMatrixReadOnly = DOMMatrixReadOnly

    Object.defineProperties(global.HTMLElement.prototype, {
        offsetHeight: {
            get() {
                return parseFloat(this.style.height) || 1
            },
        },
        offsetWidth: {
            get() {
                return parseFloat(this.style.width) || 1
            },
        },
    })
    ;(global.SVGElement as any).prototype.getBBox = () => ({
        x: 0,
        y: 0,
        width: 0,
        height: 0,
    })
}
stacker
  • 233
  • 1
  • 5
  • 14

0 Answers0