pixijs / pixi-react

Write PIXI apps using React declarative style
https://pixijs.io/pixi-react/
MIT License
2.33k stars 177 forks source link

Using Jest with React Pixi results in a TypeError #336

Closed milofultz closed 2 years ago

milofultz commented 2 years ago

Description

I'm looking to implement the Jest testing framework with React Pixi and am unable to get past this TypeError:

 FAIL  src/Stage.test.js
  ● Test suite failed to run

    TypeError: Image or Canvas expected

      at canUseNewCanvasBlendModes (./pixi-jest-test/node_modules/@pixi/canvas-renderer/src/utils/canUseNewCanvasBlendModes.ts:47:13)

Before this, I tried using forceCanvas and the canvas NPM library, but I couldn't get past a WebGL error despite using that forceCanvas option (not sure if opening a separate issue for that would be beneficial; if so let me know and I'll do that as well). This is why I end up mocking the WebGL canvas later.

I'm not an expert in canvas nor GL, so where it is showing an error in the Pixi code doesn't lead me to any good answers. The couple relevant Stack Overflow questions regarding this mention needing something to be async, but ¯\_(ツ)_/¯.

Steps to reproduce

  1. Start a new project using npx create-react-app pixi-jest-test
  2. Install the following libraries:
    • react@17.0.0
    • react-dom@17.0.0
    • @inlet/react-pixi
    • canvas
    • gl
    • @testing-library/react
    • pixi.js-legacy
  3. Update the ./src/setupTests.js file to match as below.
  4. Create Stage.test.js in the src folder using the contents below.
  5. Run npm test. You should get the above error.

setupTests.js

import React from 'react';
import { Stage } from '@inlet/react-pixi/legacy';
import { render } from '@testing-library/react';

describe('Test', () => {
  it('should test', () => {
    render(
      <Stage
        options={ { forceCanvas: true } }
      />
    );
  });
});

Stage.test.js

import '@testing-library/jest-dom';
import { createCanvas } from 'canvas';

const WIDTH = 800;
const HEIGHT = 600;

const myCanvas = createCanvas(WIDTH, HEIGHT);
const ctx = myCanvas.getContext('2d');
const gl = require('gl')(WIDTH, HEIGHT, { preserveDrawingBuffer: true })

HTMLCanvasElement.prototype.getContext = (type) => {
  let context;

  switch (type) {
    case 'webgl':
      context = gl;
      break;
    case '2d':
      context = ctx;
      break;
    default:
      console.log(`Unknown type invoked: ${type}`);
      break
  }

  return context;
};

Additional info

Thank you so much for your help, your repo is wonderful <3

milofultz commented 2 years ago

Realizing as I'm going through again that I believe this is an issue with Pixi and not your repo, so I'll go ahead and close this. Sorry for the trouble!