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

Compatibility issue: Jest mock works in React / fails in Preact when using ForwardRef in a component #4332

Closed
DanielMaczak opened this issue Mar 31, 2024 · 2 comments

Comments

@DanielMaczak
Copy link

I am using Preact 10.19.6 (should be the latest).

The bug

Jest does not call event handler in ForwardRef component when using Preact.
This behavior does not happen in both of the following cases:

  • I use React in place of Preact and I keep ForwardRef in my component.
  • I use Preact and I don't use ForwardRef in my component.

It seems the onChange event does not trigger at all in tests while using forwardRef because I never reach it, even when putting a breakpoint directly inside the event:

...
      <input                      // <-- breakpoint here does trigger
        type="date"
        value={value}
        id="test-id"
        onChange={e => {
          storeValue(e);          // <-- breakpoint here does not trigger
        }}
        ref={ref as Ref<HTMLInputElement>}
      />
...

To Reproduce

Preact repo where you can see the error: https://github.com/DanielMaczak/testing-jest-forwardref-bug
React repo where the test passes: https://github.com/DanielMaczak/testing-react-forwardref-bug
I did my best to make both as close to each other as possible:

  • Using the latest version of Preact and React
  • Using the same version of Jest
  • Using raw Jest instead to Vitest to ensure it is not Vitest issue
  • Scaling the code to minimum and using virtually identical code in both repos

Steps to verify the behavior (in both repos):

  1. Run npm i
  2. Run npm run test

You will see that one of the repos throws error on the mocked function not being called once while the other does not complain and the test passes.

Expected behavior

Both repos use the same code for the component and for the test, thus results in both should be the same.

@DanielMaczak
Copy link
Author

DanielMaczak commented Apr 13, 2024

Further information on this bug:

It occurs even when the forwardRef is used in the tested module like this, e.g. not referencing the tested component and not even imported in the tests at all:

export const Test= forwardRef(() => {
  return <div></div>;
});

I also pinpointed where the tests diverge between the two scenarios when forwardRef is used and isn't in the tested module:

node_modules / jsdom / lib / jsdom / living / events / EventTarget-impl.js > innerInvokeEventListeners :

  if (!listeners || !listeners[type]) {
    return found; // the code exits here when using forwardRef()
  }

EDIT: I found the compat piece of code causing this. I will try to come up with a solution and submit a pull request.

@DanielMaczak
Copy link
Author

This is an issue with preact-testing-library. It does not translate event names to React version when preact/compat is imported. I will submit a fix there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant