1

I am writing Ui tests for my app using Jest/Testing Library.

I am using ResponsiveLine component from @nivo/line

However, it never renders in jsdom.

I have confirmed the conditional of tableData is met, by putting a div inside of the conditional.

It's just the Responsive Line that is not rendered.

How can I make this to work?

useEffect(() => {
    if (process.env.NEXT_PUBLIC_IS_TESING) {
      const data = [ // *** this is accurate ***
        {
          id: 'Net Income',
          lineStyle: 'dotted',
          lineColor: '#e5b122',
          data: [
            { x: 'Jan 2016', y: 88278.24 },
            { x: 'Mar 2016', y: -9110.28 },
            { x: 'May 2016', y: -12446.832 },
            { x: 'Jul 2016', y: -1979.005714 },
            { x: 'Sep 2016', y: 6513.386667 },
          ],
        },
        {
          id: 'EBITDA',
          lineStyle: 'solid',
          lineColor: '#e5b122',
          data: [
            { x: 'Jan 2016', y: 88278.24 },
            { x: 'Mar 2016', y: -9110.28 },
            { x: 'May 2016', y: -12446.832 },
            { x: 'Jul 2016', y: -1979.005714 },
            { x: 'Sep 2016', y: 6513.386667 },
          ],
        },
        {
          id: 'Total Expenses',
          lineStyle: 'solid',
          lineColor: '#E8664E',
          data: [
            { x: 'Jan 2016', y: 88278.24 },
            { x: 'Mar 2016', y: -9110.28 },
            { x: 'May 2016', y: -12446.832 },
            { x: 'Jul 2016', y: -1979.005714 },
            { x: 'Sep 2016', y: 6513.386667 },
          ],
        },
        {
          id: 'Total COGS',
          lineStyle: 'solid',
          lineColor: '#a5a5a5',
          data: [
            { x: 'Jan 2016', y: 88278.24 },
            { x: 'Mar 2016', y: -9110.28 },
            { x: 'May 2016', y: -12446.832 },
            { x: 'Jul 2016', y: -1979.005714 },
            { x: 'Sep 2016', y: 6513.386667 },
          ],
        },
        {
          id: 'Total Revenue',
          lineStyle: 'solid',
          lineColor: '#6ac5a9',
          data: [
            { x: 'Jan 2016', y: 88278.24 },
            { x: 'Mar 2016', y: -9110.28 },
            { x: 'May 2016', y: -12446.832 },
            { x: 'Jul 2016', y: -1979.005714 },
            { x: 'Sep 2016', y: 6513.386667 },
          ],
        },
      ];
      setTableData(data);
    }
  }, []);

  return (
    <Box width={1} height={600}>
      {tableData && ( // **** conditionals are met 100 % ****
        <ResponsiveLine // **** here is the component never rendered ***
          data-testid="responsive-line"
          data={tableData}
          margin={{ top: 20, right: 40, bottom: 80, left: 70 }}
          xScale={{ type: 'point' }}
          yScale={{
            type: 'linear',
            reverse: false,
            min,
            max,
          }}
          yFormat=" >-$,.0f"
          axisTop={null}
          axisRight={null}
          axisBottom={{
            tickSize: 5,
            tickPadding: 5,
            tickRotation: -50,
          }}
          axisLeft={{
            tickSize: 5,
            tickPadding: 5,
            tickRotation: 0,
            format: ' >-$,.0f',
          }}
          enablePoints={false}
          useMesh={true}
          colors={plots.map((plot) => {
            return plot.lineColor;
          })}
          layers={[
            'grid',
            'markers',
            'axes',
            'areas',
            'crosshair',
            Line,
            'points',
            'slices',
            'mesh',
            'legends',
          ]}
          enableSlices="x"
          sliceTooltip={({ slice }) => {
            return (
              <Paper
                sx={{
                  fontFamily: 'Arial',
                  padding: '20px !important',
                }}
                elevation={5}
              >
                <Box width={1} mb={1}>
                  Month: {slice.points[0].data.xFormatted}
                </Box>
                {slice.points.map((point) => (
                  <Box width={1} pb={1} key={point.id}>
                    <Grid container alignItems="center">
                      <Box
                        mr={1}
                        height={10}
                        width={10}
                        style={{ backgroundColor: point.serieColor }}
                      ></Box>{' '}
                      {point.serieId}
                      {' -'}
                      <Box ml={1}>
                        <strong>{point.data.yFormatted}</strong>
                      </Box>
                    </Grid>
                  </Box>
                ))}
              </Paper>
            );
          }}
          legends={[
            {
              anchor: 'bottom',
              direction: 'row',
              justify: false,
              translateX: 0,
              translateY: 80,
              itemsSpacing: 0,
              itemDirection: 'left-to-right',
              itemWidth: legendItemWidth,
              itemHeight: 20,
              itemOpacity: 0.75,
              symbolSize: 40,
              symbolShape: (props) => {
                const plot = plots.find((plot) => {
                  return plot.name === props.id;
                });
                if (plot) {
                  if (plot.lineStyle === 'dotted') {
                    return <SymbolDottedDash {...props} />;
                  } else if (plot.lineStyle === 'dotted-small') {
                    return <SymbolDottedSmallDash {...props} />;
                  }
                }

                return <SymbolDash {...props} />;
              },

              effects: [
                {
                  on: 'hover',
                  style: {
                    itemBackground: 'rgba(0, 0, 0, .03)',
                    itemOpacity: 1,
                  },
                },
              ],
            },
          ]}
        />
      )}
    </Box>
  );
};

export default React.memo(DataTable);
porFavor
  • 293
  • 4
  • 12

2 Answers2

0

If i am not wrong; nivo doesnt render custom data-* props. So giving it a data-testid might not work. https://github.com/plouc/nivo/blob/master/packages/line/src/Line.js

Check how nivo tests Line graph components. https://github.com/plouc/nivo/blob/master/packages/line/tests/Line.test.js

Emre A
  • 240
  • 1
  • 6
0

After debugging the Nivo core library, the responsive wrapper caused the issue by consuming the ResizeObserver browser API. Because you cannot use the ResizeObserver in jest-dom since it is not supported yet.

I have found the workaround for the scenario to mock ResizeObserver and supply the contentRect values from the test.

Here's working example

Yogi Mayi
  • 11
  • 5
  • @Yunnosch, I agree, I didn't have enough reputation to ask through comments. thought any help would be received since I am facing the exact issue. – Yogi Mayi Jul 26 '22 at 07:00
  • @Yunnosch, Thanks for your clarification, I will do the necessary actions. – Yogi Mayi Jul 26 '22 at 16:43
  • Yogi Mayi, a link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](//meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it is there, then quote the most relevant part of the page you are linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted.](/help/deleted-answers) – Yunnosch Sep 23 '22 at 14:03