Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple testing example of canvas element using Jest

I am trying to create a jest test for the example found in this sandbox: https://codesandbox.io/s/r3f-basic-demo-forked-297k3?file=/src/App.js

Basically I would like to test the onClick functionality on each box. I have already come across with the fact that jest tests don't run in a real browser. Jest uses jsdom for mocking the necessary parts of the DOM. Consequently I may need canvas support for jsdom, yet I am not quite sure exactly what to do.

App.js

import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'

function Box(props) {
  // This reference will give us direct access to the mesh
  const mesh = useRef()
  // Set up state for the hovered and active state
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)
  // Rotate mesh every frame, this is outside of React without overhead
  useFrame(() => {
    mesh.current.rotation.x = mesh.current.rotation.y += 0.01
  })
  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={(e) => setActive(!active)}
      onPointerOver={(e) => setHover(true)}
      onPointerOut={(e) => setHover(false)}>
      <boxBufferGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

export const App = () => {
  return (
    <>
      <Canvas>
        <ambientLight intensity={0.5} />
        <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
        <pointLight position={[-10, -10, -10]} />
        <Box position={[-1.2, 0, 0]} />
        <Box position={[1.2, 0, 0]} />
      </Canvas>
    </>
  )
}
like image 440
Dimitra Mavroforaki Avatar asked Dec 28 '25 16:12

Dimitra Mavroforaki


1 Answers

Solution 1

install

yarn add --dev jest-canvas-mock

or

npm i --save-dev jest-canvas-mock

and just import jest-canvas-mock in your test file

import 'jest-canvas-mock';

or

Solution 2

If you can`t install the library as common approach.

Try mock canvas in that way

window.HTMLCanvasElement.prototype.getContext = function () {
    return {
        fillRect() {},
        clearRect() {},
        getImageData(x, y, w, h) {
            return {
                data: new Array(w * h * 4)
            };
        },
        putImageData() {},
        createImageData() { return [] },
        setTransform() {},
        drawImage() {},
        save() {},
        fillText() {},
        restore() {},
        beginPath() {},
        moveTo() {},
        lineTo() {},
        closePath() {},
        stroke() {},
        translate() {},
        scale() {},
        rotate() {},
        arc() {},
        fill() {},
        measureText() {
            return { width: 0 };
        },
        transform() {},
        rect() {},
        clip() {}
    };
}

window.HTMLCanvasElement.prototype.toDataURL = function () {
    return '';
}
like image 190
Ivan K. Avatar answered Dec 31 '25 17:12

Ivan K.