Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing custom hooks that needs the DOM #947

Open
kaiofelipejs opened this issue Jan 24, 2023 · 0 comments
Open

Testing custom hooks that needs the DOM #947

kaiofelipejs opened this issue Jan 24, 2023 · 0 comments
Labels
question Further information is requested

Comments

@kaiofelipejs
Copy link

kaiofelipejs commented Jan 24, 2023

What is your question:

I have a custom hook that checks the document using querySelector to get some information (like width, height, x, y, etc...) about a component.

function search(Component) {
  const name =
    typeof Component === 'string' ? Component : Component?.displayName;

  if (!name) return null;

  const element = global.document?.querySelector(
    `[${NAME_ATTRIBUTE}="${name}"]`
  );

  if (!element) return null;

  const { top, right, bottom, left, width, height, x, y } =
    element.getBoundingClientRect();

  return {
    element,
    top,
    right,
    bottom,
    left,
    width,
    height,
    x,
    y
  };
}

function useComponentSearch(Component) {
  const [data, setData] = useState(null);
  const reload = useCallback(() => setData(search(Component)), [Component]);

  useEffect(() => {
    setData(search(Component));
  }, [Component]);

  return [data, reload];
}

I would like to test this hook using react-hooks, but this hook needs the DOM to work. So I try a test using a wrapper:

 describe('...', () => {
    const displayName = 'Component';
    const Component = () => <div data-component-name={displayName}>test</div>;
    Component.displayName = displayName;

    const Wrapper = ({ children }) => (
      <>
        <Component />
        {children}
      </>
    );

    it('...', async () => {
      const { result, waitForValueToChange } = renderHook(
        () => useDataAttributes(ComponentWithDataAttributes),
        {
          wrapper: Wrapper
        }
      );

      await waitForValueToChange(() => result.current);

      expect(result.current).toEqual([{}, expect.any(Function)]);
    });
});

But when I check the document.body.children.length the value is 0 (no elements). I check the createTestHarness and understood that is not possible to test this way, but I want to confirm this.

I will test with @testing-library/react using a dummy component but is not too good to my case.

Thanks!

@kaiofelipejs kaiofelipejs added the question Further information is requested label Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant