react-apexcharts icon indicating copy to clipboard operation
react-apexcharts copied to clipboard

TypeError: r.node.getBBox is not a function , while running test cases

Open Amitkumarc opened this issue 5 years ago • 8 comments

hi @junedchhipa ,

I am getting the below errors while running test cases for PieChart react component. I am using Jest and Enzyme for testing.

While mounting the component: TypeError: r.node.getBBox is not a function

  33 |     it('should invoke useEffect ', () => {
  34 |         act(() => {
> 35 |             component = mount(<Chart {...props} />)
     |                         ^
  36 |             component.setProps({ compositionUnit: UNITS.VOLUME })
  37 |         })

  at new create (node_modules/apexcharts/dist/apexcharts.common.js:6:378800)
  at e.bbox (node_modules/apexcharts/dist/apexcharts.common.js:6:379007)
  at g (node_modules/apexcharts/dist/apexcharts.common.js:6:399056)
  at e.size (node_modules/apexcharts/dist/apexcharts.common.js:6:368332)
  at create.rect (node_modules/apexcharts/dist/apexcharts.common.js:6:391433)
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:6:15460)
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:6:155619)
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:14:39268)
  at t.create (node_modules/apexcharts/dist/apexcharts.common.js:6:3411)
  at node_modules/apexcharts/dist/apexcharts.common.js:14:37819
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:14:37312)
  at r.value (node_modules/react-apexcharts/dist/react-apexcharts.min.js:1:2760)
  at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:19814:22)

While calling ApexCharts.exec funtion:

TypeError: Cannot set property 'fillStyle' of null

117 | ApexCharts.exec("donut", "dataURI").then(({ imgURI }) => { | ^ 118 | uriArray.push(imgURI)

  at node_modules/apexcharts/dist/apexcharts.common.js:6:142365
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:6:142083)
  at t.value (node_modules/apexcharts/dist/apexcharts.common.js:14:47346)
  at Function.exec (node_modules/apexcharts/dist/apexcharts.common.js:14:48349)

Can you please tell, how to resolve these issues.

Amitkumarc avatar Jul 15 '20 16:07 Amitkumarc

The error goes away by mocking the library.

https://stackoverflow.com/questions/51957794/jest-typeerror-is-not-a-function-in-jest-mock

What I did is:

import ApexCharts from "apexcharts";
import ReactApexChart from "react-apexcharts";

jest.mock('react-apexcharts', () => jest.fn(() => { return null }));
jest.mock('apexcharts', () => ({ exec: jest.fn(() => { return new Promise((resolve, reject) => { resolve("uri") }) }) }));

Amitkumarc avatar Jul 17 '20 14:07 Amitkumarc

I was also caught in this error. But, thanks to ijayoa, @Amitkumarc, I could suppress this error.

# error message

(node:3677) UnhandledPromiseRejectionWarning: TypeError: Caught error after test environment was torn down

Cannot read property 'body' of null
(node:3677) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 23)
 FAIL  src/App.test.js (28.739s)
  ● renders hoge huga

    TypeError: r.node.getBBox is not a function

...

My App.js is below.

# App.js
import React, { Component } from 'react';
import ReactApexChart from 'react-apexcharts'

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      options: {
        chart: {
          type: 'candlestick',
          height: 350
        },
        title: {
          text: 'CandleStick Chart',
          align: 'left'
        },
        xaxis: {
          type: 'datetime'
        },
        yaxis: {
          tooltip: {
            enabled: true
          }
        }
      },
      series: [{
        name: 'series-1',
        data: [{
            x: new Date(1538778600000),
            y: [6629.81, 6650.5, 6623.04, 6633.33]
          },
          {
            x: new Date(1538780400000),
            y: [6632.01, 6643.59, 6620, 6630.11]
          },
          {
            x: new Date(1538782200000),
            y: [6630.71, 6648.95, 6623.34, 6635.65]
          },
          {
            x: new Date(1538784000000),
            y: [6635.65, 6651, 6629.67, 6638.24]
          },
          {
            x: new Date(1538785800000),
            y: [6638.24, 6640, 6620, 6624.47]
          },
          {
            x: new Date(1538787600000),
            y: [6624.53, 6636.03, 6621.68, 6624.31]
          },
          {
            x: new Date(1538789400000),
            y: [6624.61, 6632.2, 6617, 6626.02]
          },
          {
            x: new Date(1538791200000),
            y: [6627, 6627.62, 6584.22, 6603.02]
          },
          {
            x: new Date(1538793000000),
            y: [6605, 6608.03, 6598.95, 6604.01]
          },
          {
            x: new Date(1538794800000),
            y: [6604.5, 6614.4, 6602.26, 6608.02]
          },
          {
            x: new Date(1538796600000),
            y: [6608.02, 6610.68, 6601.99, 6608.91]
          },
        ]
      }]
    }
  }

  render() {
    return (
      <>
        <div id="chart">
          <ReactApexChart options={this.state.options} series={this.state.series} type="candlestick" width={800} height={350} />
        </div>
        <span>test hoge huga !</span>
      </>
    );
  }
}

export default App;

And, as @ijayoa, @Amitkumarc says, mocks helped me to avoid this error.

# App.test.js

import React from 'react';
import { render } from '@testing-library/react';
import App from './App';

// I added only the following two mocks.
jest.mock("react-apexcharts", () => jest.fn(() => { return null; }) );
jest.mock("apexcharts", () => (
  {
    exec: jest.fn(() => {
      return new Promise(
        (resolve, reject) => { resolve("uri"); }
      );
    }) 
  }
));


test('renders hoge huga', () => {
  const { getByText } = render(<App />);
  const linkElement = getByText(/hoge huga/i);
  expect(linkElement).toBeInTheDocument();
});

# result
=>  PASS  src/App.test.js (15.903s)

Thank you.

siruku6 avatar Aug 10 '20 06:08 siruku6

I did managed to get few functionality working by adding mocks to SVGElement. Any idea on how can I import this library from source rather than dist? I might be able to get it working. I did managed to get one simple chart working by following mock & adding "jest-canvas-mock": "^2.3.1",:

  beforeEach(() => {
    window.SVGElement.prototype.getBBox = () => ({
      x: 0,
      y: 0
    });
    window.SVGElement.prototype.getScreenCTM = () => new DOMMatrix([1, 2, 3, 4, 5, 6]);
    window.SVGElement.prototype.createSVGMatrix = () => ({
      x: 28,
      y: 20,
      inverse: () => {},
      multiply: () => {}
    });
  });

  afterEach(() => {
    delete window.SVGElement.prototype.getBBox;
  });

Right now I am getting error as s[t] is not a function error. If I have this lib imported from source I might get the function name and I can mock it.

saurabhnemade avatar Feb 27 '21 10:02 saurabhnemade

Guys if anyone is tracking is, here is quick update. I reached to an error which is like s[t] is not a function. I dig a lot into it. Found out that is bug in svg.js https://github.com/apexcharts/apexcharts.js/blob/4b46d339ca16c70751952e6b0f2facb8812fe643/src/svgjs/svg.js#L463

in latest version of svg.js https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.0.16/svg.js the missing function A is added in pathHandlers.

saurabhnemade avatar Apr 29 '21 17:04 saurabhnemade

I reached to an error which is like s[t] is not a function. I dig a lot into it. Found out that is bug in svg.js https://github.com/apexcharts/apexcharts.js/blob/4b46d339ca16c70751952e6b0f2facb8812fe643/src/svgjs/svg.js#L463

in latest version of svg.js https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.0.16/svg.js the missing function A is added in pathHandlers.

I got same one. The missing function was removed following commit for down package size. https://github.com/apexcharts/apexcharts.js/commit/42b84d7dfc4b1dffe511b8d67d8f878971d1c2b5#diff-160a469199931ab18c3e9119104abc910c395564c52f7d26f2b4608623c511bd

My case works with reverting pathHandlers in svg.js.

two-pack avatar May 14 '21 13:05 two-pack

@two-pack I moved to cypress completely for unit testing of chart based components. It was easier to test them with rendering them in browser with cypress and quickly write test for them.

saurabhnemade avatar Jan 12 '22 21:01 saurabhnemade

The error goes away by mocking the library.

https://stackoverflow.com/questions/51957794/jest-typeerror-is-not-a-function-in-jest-mock

What I did is:

import ApexCharts from "apexcharts";
import ReactApexChart from "react-apexcharts";

jest.mock('react-apexcharts', () => jest.fn(() => { return null }));
jest.mock('apexcharts', () => ({ exec: jest.fn(() => { return new Promise((resolve, reject) => { resolve("uri") }) }) }));

Doesn't that mock the whole library to do nothing? How are your renders still working?

rodpatulski avatar Sep 30 '22 03:09 rodpatulski

Is there a fix for this? In 2023 I'm still having problem with this. What can we do related to this?

Narven avatar Apr 28 '23 11:04 Narven