Search code examples
reactjsjestjsamchartsamcharts4

html container not found - AmCharts4, React and Jest Testing


I'm trying to run Jest test for React and AmCharts4, however I get the following failed test:

console.log node_modules/@amcharts/amcharts4/.internal/core/System.js:481
      html container not found
    console.error node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Uncaught [Error: html container not found]
          at reportException (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
          at invokeEventListeners (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
          at HTMLUnknownElementImpl._dispatch (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
          at HTMLUnknownElementImpl.dispatchEvent (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
          at HTMLUnknownElementImpl.dispatchEvent (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
          at HTMLUnknownElement.dispatchEvent (../project/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
          at Object.invokeGuardedCallbackDev (../project/node_modules/react-dom/cjs/react-dom.development.js:199:16)
          at invokeGuardedCallback (../project/node_modules/react-dom/cjs/react-dom.development.js:256:31)
          at commitRoot (../project/node_modules/react-dom/cjs/react-dom.development.js:18948:7)
          at ../project/node_modules/react-dom/cjs/react-dom.development.js:20418:5 Error: html container not found
          at createChild (../project//node_modules/src/.internal/core/utils/Instance.ts:156:9)
          at Object.createFromConfig (../project//node_modules/src/.internal/core/utils/Instance.ts:311:14)
          at BaseChart.createFromConfig (../project//src/components/features/amCharts/BaseChart.js:17:25)
          at BaseChart.createChart [as componentDidMount] (../project//src/components/features/amCharts/BaseChart.js:14:10)
          at commitLifeCycles (../project//node_modules/react-dom/cjs/react-dom.development.js:17334:22)
          at commitAllLifeCycles (../project//node_modules/react-dom/cjs/react-dom.development.js:18736:7)
....

The chart renders with no issues in browser and storybook.

I just can't get it to pass the test. The test is simple:

import App from './App';

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
  ReactDOM.unmountComponentAtNode(div);
});

and my BaseChart component is also very simple, just mapping the json chart config to createFromConfig:

class BaseChart extends Component {
  componentDidMount() {
    this.createChart();
  }
  componentDidUpdate(oldProps) {
    if (JSON.stringify(oldProps.chartConfig) !== JSON.stringify(this.props.chartConfig)) {
      this.createChart();
    }
    if (JSON.stringify(oldProps.data) !== JSON.stringify(this.props.data)) {
      this.chart.data = this.props.data;
    }
  }
  componentWillUnmount() {
    if (this.chart) {
      this.chart.dispose();
    }
  }
  createChart = () => {
    let chart = am4core.createFromConfig(this.props.chartConfig, `amchart_${this.props.feature._id}`, this.props.chartModule);
    chart.data = this.props.data;
    this.chart = chart;
  }
  render() {
    const { feature, width, height } = this.props;
    return (
      <div id={`amchart_${feature._id}`} style={{ width: width ? width : '100%', height: height ? height : '300px' }}></div>
    );
  }
}

Any ideas how to pass html container not found issue?


Solution

  • Your div container needs to be in the document.

    You are providing your chart code an id to render into. This div

    <div id={'amchart_${feature._id}'} />
    

    does not exist in the document because the component does not. The component does not exist in the document as the container you have created and provided to the render method is not in the document.

    document.body.appendChild(div)