apexcharts / react-apexcharts

šŸ“Š React Component for ApexCharts
https://apexcharts.com
MIT License
1.31k stars 155 forks source link

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

Closed Amitkumarc closed 1 month ago

Amitkumarc commented 4 years ago

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 commented 4 years ago

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") }) }) }));
siruku6 commented 4 years ago

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.

saurabhnemade commented 3 years ago

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 commented 3 years ago

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.

two-pack commented 3 years ago

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.

saurabhnemade commented 2 years ago

@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.

rodpatulski commented 2 years ago

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?

Narven commented 1 year ago

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

github-actions[bot] commented 1 month ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.