1 year ago

#349303

test-img

Pinnci

How to test scrollHeight, scrollWidth, clientHeight and clientWidth with react-testing-library and jest

I just can't figure out, how I'm supposed to mock / get data from scrollHeight, scrollWidth, clientHeight and clientWidth in test.

For better introduction, my task is to detect whether table element is scrollable or not and if it is, then I have to add tabIndex attribute to it's wrapper.

In my component, I'm simply attaching ref to div, in which is table element.

const tableWrapperRef = useRef(null);

<div ref="tableWrapperRef">
  <table>
    //table content
  </table>
</div>

Then in useEffect I'm getting tableWrapperRef.current and searching for table element in it. Next, I will simply pick these values and I compare them to each other in isScrollable function. Result from this function is the key for me, because depending on that result I'm adding tabIndex attribute to div.

  function isScrollable(
    tableWrapper,
    tableElement
  ) {
    if (
      tableElement.scrollWidth > tableWrapper.clientWidth ||
      tableElement.scrollHeight > tableWrapper.clientHeight
    ) {
      return true;
    }
    return false;
  }

  React.useEffect(() => {
    if (tableWrapperRef.current) {
      const tableWrapper = tableWrapperRef.current;
      const tableElement = tableWrapperRef.current?.querySelector("table");

      if (isScrollable(tableWrapper, tableElement!)) {
        return tableWrapper.setAttribute("tabIndex", "0");
      }
    }
  }, [tableWrapperRef.current]);

It is working as it should, but I can't figure it out how to test it. Test always fails, because scrollWidth, scrollHeight, clientWidth and clientHeight values are always 0. I figured out that it's because jsdom doesn't have access to these values.

My test

In my test, to simulate smaller window and to force table to shrink and scroll I'm using resizeWindow function.

function resizeWindow(x: number, y: number) {
  // @ts-ignore
  window.innerWidth = x;
  // @ts-ignore
  window.innerHeight = y;
  window.dispatchEvent(new Event("resize"));
}

test.each([[175, 300]])("default render (%p x %p)", async (x, y) => {
  resizeWindow(x, y);

  render(
    <Table
      columns={columns}
      data={data}
      caption="Názov tabuľky"
      className="test-className"
      data-testid="table"
    />
  );

  const tableWrapper = await screen.getByTestId("table");

  expect(tableWrapper).toBeInTheDocument();
  expect(tableWrapper.getAttribute("tabIndex")).toBe("0");
});

I've also found this question here on stackoverflow, with reference on official jest docs, but I just don't understand how to use it in this case.. Can someone please help me with this?

reactjs

jestjs

react-testing-library

react-testing

0 Answers

Your Answer

Accepted video resources