Testing fabric.js mouse events using Testing Library’s fireEvent
When testing fabric.js you may want to trigger events based on inputs to make sure your components or other interactions work properly.
To do this you may have or create a canvas element and then try to run mouse
events on that element. The problem is the events should be triggered on the
upper canvas element that fabric.js use for interactions. To properly trigger
these events use canvas.upperCanvasEl
instead of your canvas element.
const canvasElement = document.createElement("canvas");
// Appending to the body may be necessary for it to exist on the canvas
document.body.appendChild(canvasElement);
const canvas = new fabric.Canvas(canvasElement, { width: 640, height: 480 });
// Now let say we have a component that register events for "mouse:down",
// "mouse:move", and "mouse:down" on the fabricjs canva
render(<LineShape onFinish={jest.fn()} onCancel={jest.fn()} />);
// Use the upper canva element as the target for fireEvent
const upperCanvasEl = canvas.upperCanvasEl;
fireEvent.mouseDown(upperCanvasEl, { clientX: 20, clientY: 20 });
fireEvent.mouseMove(upperCanvasEl, { clientX: 100, clientY: 100 });
fireEvent.mouseUp(upperCanvasEl, { clientX: 120, clientY: 120 });
// then you should see those event fired properly to the canvas
// in this example LineShape adds a line when we do
// "mouse:down" and when "mouse:up" we are done creating the line
const obj = canvas._objects[0];
expect(obj.x1).toBe(20);
expect(obj.y1).toBe(20);
expect(obj.x2).toBe(120);
expect(obj.y2).toBe(120);