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

Unable to test with React Testing Library #107

Closed
SimeonRolev opened this issue Aug 5, 2021 · 9 comments
Closed

Unable to test with React Testing Library #107

SimeonRolev opened this issue Aug 5, 2021 · 9 comments

Comments

@SimeonRolev
Copy link

Hi, guys,
I work on a project where this library fits pretty well, but I want to test my end product. However, I wasn't able to do so, for some reason. I've used React Testing Library for tons of tests, so I guess it's something in the way these toasts work that I don't understand. Does the disappearance of the toasts depend on something that 'jsdom' can't handle?

Made a minimal reproduction repository with some simple explanations here: https://github.com/SimeonRolev/test-react-hot-toast. It has a single test for the "Close button".

Testing example:
https://testing-library.com/docs/guide-disappearance

Thanks in advance!

@SimeonRolev
Copy link
Author

https://github.com/SimeonRolev/test-react-hot-toast/tree/jest-fake-timers
Created a new branch that I try to advance mocked jest timers. I get leaks.

@silvenon
Copy link
Contributor

silvenon commented Jan 20, 2022

The problem is in the Toaster component:

const ref = t.height
? undefined
: createRectRef((rect) => {
handlers.updateHeight(t.id, rect.height);
});

In jsdom getBoundingClientRect used in createRectRef always returns an object of zeros, so the ref created createRectRef just gets created and run over and over again because t.height is always 0. In browser this would stop immediately because t.height would not be 0 after the first run.

I'm not sure what to do about this, though.

@silvenon
Copy link
Contributor

The solution is basically to memoize the ref created by createRectRef instead of the ternary above, which requires creating an additional component for rendering toast messages. You can see the linked PR, we already had that in Orbit.

Would a PR be welcome? I can send one next week.

@timolins
Copy link
Owner

Wow, thanks @silvenon for your investigations! A PR would be very welcome.

@CodeZea1ot
Copy link

Will silvenon's PR be merged for this project? Would love to use react-hot-toast in RTL 😁

@sharmabharti195
Copy link

@silvenon's PR will be merged?

timolins added a commit that referenced this issue Jul 10, 2022
* Toast height will be re-calculated `onLayoutEffect` - #133
* Memoize height ref - #107 - inspired by #154
* Restructure handlers for better memoization

Not entirely happy with the internal API yet. Might need to rework.
@pipboy3000
Copy link
Contributor

I forked the code in the document and added a test.
The test shows as successful, but I got an Infinit loop error.

https://codesandbox.io/s/react-hot-toast-usetoaster-headless-example-forked-j2ods8?file=/src/App.test.js

@silvenon and @ahuth code works fine.

@silvenon
Copy link
Contributor

silvenon commented Sep 22, 2022

@pipboy3000 yep, the useToaster example has the same problem as the Toaster component, so I think it's enough to edit the condition to be el && typeof toast.height !== "number" instead of el && !toast.height. Note that the infinite loop you're seeing is happening in your test, not in the browser, but the test is falsely passing because you're not awaiting the click action, which is asynchronous. This is the fixed test, I also replaced getBy + waitFor with findBy queries:

test("show Toast", async () => {
  render(<App />);
  const addButton = await screen.findByText("Add Toast");
  await userEvent.click(addButton); // notice the await here!
  await screen.findByText(/Hello World/)
});

The reason why we know this fixes the test is that without the typeof fix the test no longer passes, it fails, as it should. Would you care to submit a PR to update the documentation? And see if there are any other code examples which need to be updated with the typeof fix.

One more thing regarding the test, I'm not entirely sure why the lack of await causes the test to falsely pass, considering that you're waiting for the toast message to appear anyway. I guess it has something to do with how @testing-library/user-event works, or maybe it's precisely the infinite loop that screws it up. 🤷 As for why you're seeing the infinite loop error in the Browser tab, I guess that's how CodeSandbox handles test errors that happen after tests finish running.

Btw, in case the reason for the infinite loop is not clear, it's same as in the Toaster component,
in unit tests toast.height ends up being 0 so the condition el && !toast.height remains true, which causes updateHeight to get called infinitely.

@silvenon
Copy link
Contributor

@timolins this can be closed.

AMagicHarry added a commit to AMagicHarry/react-hot-toast that referenced this issue Mar 11, 2024
HappyCodingWizard added a commit to HappyCodingWizard/react-hot-toast that referenced this issue Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants