1
votes

I'm attempting to create a Jest test that tests the implementation of a class that instantiates a LightningChartJS ChartXY.

The following error is thrown during the instantiation of the Chart:

  EngineError: Null pointer in i
  ...
  at new i (../../node_modules/@arction/lcjs/dist/lcjs.js:1:8948)
  at Ot (../../node_modules/@arction/lcjs/dist/lcjs.js:1:20740)
  at new i (../../node_modules/@arction/lcjs/dist/lcjs.js:1:458125)
  at ../../node_modules/@arction/lcjs/dist/lcjs.js:47:49973
  at Object.ChartXY (../../node_modules/@arction/lcjs/dist/lcjs.js:47:211838)
  at new LightningPlot (src/app/lightningChart.ts:70:8)

This GH issue hints at the source of the problem: LightningChartJS does not find the respective DOM node to insert into.

What I've tried so far:

  • Import jest-canvas-mock into the setup (necessary to enable canvas in JSDom and avoid this issue)
  • using a JSDom import during setup to mock the DOM (based on this SO answer)
  • Using the Jest testEnvironment jest-environment-jsdomconfiguration

The DOM mock was tested in several ways:

  • using createElement()
  • setting innerHTML of the body
1

1 Answers

1
votes

JSDOM alone is not enough to be able to run LightningChart JS outside of browser environment. JSDOM doesn't provide WebGL support so when LightningChart JS calls canvas.getContext('webgl') it will not receive the context and will throw an error. To be able to run LCJS with Jest, the canvas.getContext method needs to be edited a bit to support WebGL.

You will need to install gl and canvas npm packages and then add a setup file to your Jest configuration.

__setups__/lcjs.js:

const createContext = require('gl')
// overwrite getContext to return headless-gl webgl context
const orig_getContext = window.HTMLCanvasElement.prototype.getContext
window.HTMLCanvasElement.prototype.getContext = function () {
    if (arguments[0] === 'webgl') {
        // create headless-gl GL context
        const ctx = createContext(1, 1, arguments[1])
        // insert the resize method to the context so that lcjs package can use it
        ctx.resize = ctx.getExtension('STACKGL_resize_drawingbuffer').resize
        return ctx
    } else {
        return orig_getContext.apply(this, arguments)
    }
}

Jest configuration:

{
  "jest": {
    "setupFiles": [
      "./__setups__/lcjs.js"
    ]
  }
}

Using that setup file will make it possible for LightningChart JS to run in the environment Jest provides. The setup file is based on lcjs-headless implementation.