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

Version >= 9.12.0 breaks automatic InteractionOberserver setup with jest #699

Open
valleywood opened this issue Aug 21, 2024 · 14 comments · Fixed by #715 · May be fixed by #716
Open

Version >= 9.12.0 breaks automatic InteractionOberserver setup with jest #699

valleywood opened this issue Aug 21, 2024 · 14 comments · Fixed by #715 · May be fixed by #716
Labels

Comments

@valleywood
Copy link

We have a test environment where we've used mockAllIsIntersecting from react-intersection-observer/test-utils together with Jest
This has worked just fine until we updated to version 9.12.0 and beyond after that we've started to get type errors when running tests.

After that we got the error:

TypeError: observer.observe is not a function

      at observe (node_modules/react-intersection-observer/src/observe.ts:153:12)
      at node_modules/react-intersection-observer/src/useInView.tsx:66:19
      at commitHookEffectListMount (node_modules/react-dom/cjs/react-dom.development.js:23189:26)

The error could be resolved by manually adding this code to our Jest tests:

beforeEach(() => {
  setupIntersectionMocking(jest.fn);
});

afterEach(() => {
  resetIntersectionMocking();
});

So it seems like version 9.12.0 broke the automatic setup with Jest? 🤔

To Reproduce Try and recreate the issue in a Codesandbox:

Expected behavior
If react-intersection-observer should still be possible to run together with Jest without manually using setupIntersectionMocking and resetIntersectionMocking types should be fixed.

I suspect that this error comes from this update mentioned in the release notes for version 9.12.0

"Types cleanup in test-utils, getting rid of @types/jest (replaced with vitest)"

Screenshots
Skärmavbild 2024-08-21 kl  12 00 22

**Desktop **

  • OS: Mac OS Sonoma
  • Browser N/A (Jest tests)
  • Version >= 9.12.0
@thebuilder
Copy link
Owner

Can you verify that it's 9.12 it first happens? What if you run just one test? It could be Jest resets the observer after a run, so before All isn't working as expected.
Do you have something in your code that resets it after a test?

I unfortunately won't have a chance to look into it until September.

@valleywood
Copy link
Author

I've now verified that the error isn't there with version 9.11 it starts with 9.12.
I've also verified that the error doesn't occur if I run just one test.

The error occurs only when I have two or more tests that both contains a call to mockAllIsIntersecting(true);

I didn't have anything that resets between the test before I've added a the fix to circumvent this error (the setupIntersectionMocking/resetIntersectionMocking mentioned above)

@thebuilder
Copy link
Owner

Could be a difference between vitest and jest, and how they reset code. Might have to go back to beforeEach for Jest tests then.

@thebuilder thebuilder self-assigned this Sep 2, 2024
@thebuilder
Copy link
Owner

I've tried installing and running the hooks.test.tsx tests using Jest instead of Vitest - Using a default Jest configuration, it correctly does the mocking, so mockAllIsIntersecting works as expected.
CleanShot 2024-09-03 at 12 36 22@2x

Is there anything special in your setup or Jest configuration?

@thebuilder thebuilder removed their assignment Sep 3, 2024
@denchen
Copy link

denchen commented Sep 5, 2024

I just want to chime in and say I'm experiencing the same issue as well using Jest and starting with 9.12, though my error looks slightly different:

    TypeError: io.observe is not a function

@valleywood 's workaround solved the issue for me, but I only needed setupIntersectionMocking(jest.fn) in the beforeEach() hook. I did not need resetIntersectionMocking() in afterEach()

@Toolo
Copy link

Toolo commented Sep 11, 2024

We're running into the same issue, updating from 9.10.3 to 9.13.1 and getting the observer.observe is not a function error.

In terms of custom setup, the only thing that comes to mind is that we add a top-level

import "intersection-observer";

at the top of our test setup file.

@julian-jambit
Copy link

julian-jambit commented Jan 13, 2025

We experience the same issue. For us the problem is that setupIntersectionMocking(jest.fn) is called in the beforeAll step. However, since we use jest with resetMocks=true, the mocks are reset after each test, but only setup at the beginning.

Calling setupIntersectionMocking(jest.fn) in beforeEach fixes the error for us.

@thebuilder
Copy link
Owner

@julian-jambit that could explain the issue.
This change was made because of the issue in #689 - I'm thinking it might sense to just go back to beforeEach to be safe.

@thebuilder
Copy link
Owner

🎉 This issue has been resolved in version 9.15.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@julian-jambit
Copy link

Hi @thebuilder thank you for the quick fix. Unfortunately, the version 9.15.0 still doesn't solve the issue and even breaks our mentioned worarkound. The additional check for isMocking in setupIntersectionMocking does not work well together with resetMocks=true in jest. With resetMocks jest resets all mocks after each test, but it does not reset your isMocking variable, so the mock is never setup again.

@thebuilder
Copy link
Owner

Right. Okay. I should be able to determine the mock state without using a variable.

@thebuilder thebuilder linked a pull request Jan 14, 2025 that will close this issue
@thebuilder
Copy link
Owner

@julian-jambit could you try #716 - You should be able to install it before it's released with the pkg-pr-new bundle:

npm i https://pkg.pr.new/thebuilder/react-intersection-observer@716

@thebuilder thebuilder reopened this Jan 14, 2025
@julian-jambit
Copy link

This has the same error. From the documentation of resetMocks:

This will lead to any mocks having their fake implementations removed but does not restore their initial implementation.

So isMockFunction seems to still return true, even if the mock is reset. I don't know if there is a way to check if there is no mock implementation.

@thebuilder
Copy link
Owner

Jeez, what kind of pseudo reset is that. Seems like Vitest does the same.
Can't find an obvious way to determine if it has been reset. Maybe I have to skip that check then, and always create a new instance.

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