fkhadra / react-toastify

React notification made easy 🚀 !
https://fkhadra.github.io/react-toastify/introduction
MIT License
12.75k stars 700 forks source link

autoClose not working when testing using @testing-library/react #1010

Open shehan-mark opened 1 year ago

shehan-mark commented 1 year ago

Do you want to request a feature or report a bug?

What is the current behavior? I am testing toast que functionality in my project. I have a requirement where I want to display only one toast at a time. For that I have limited the toast count from the ToastContainer. but in order to test this I want first test each toast's open and close feature so that I can check on the next consecutive toast's that is in the que.
But I am unable move further after the first toast. Meaning first toast won't disappear after the timeout. For better understanding I have provided a CodeSandbox below. also I noticed that animation-play-state: is always set to paused when I log the DOM structure using screen.debug() image

CodeSandbox

What is the expected behavior? Toast to disappear after the specified timeout in Unit testing.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? These are the exact local versions that I use. They may differ from the versions used in the sandbox. But the issue was reproducable.

react - 17.0.2 react-toastify - 9.1.3 jest-environment-jsdom - 29.6.1

It seemed like a bug in the library but please let me know if this is on my side.

shehan-mark commented 1 year ago

Pinging here to keep this active.

davidgonzalezfx commented 1 year ago

Have you tried adding this at the beginning of your tests

jest.useFakeTimers();

beforeEach(() => {
  jest.spyOn(window, 'requestAnimationFrame').mockImplementation((callback) => {
    callback(1);
    return 1;
  });
});

afterEach(() => {
  (window.requestAnimationFrame as jest.Mock).mockRestore();
});

and

fireEvent.animationEnd(...)
jest.runAllTimers();

before your expect(within(toastOneSeconQ).getByText("ToastMessage - 1")).not.toBeVisible(); ?

framitdavid commented 5 months ago

Have you tried adding this at the beginning of your tests

jest.useFakeTimers();

beforeEach(() => {
  jest.spyOn(window, 'requestAnimationFrame').mockImplementation((callback) => {
    callback(1);
    return 1;
  });
});

afterEach(() => {
  (window.requestAnimationFrame as jest.Mock).mockRestore();
});

and

fireEvent.animationEnd(...)
jest.runAllTimers();

before your expect(within(toastOneSeconQ).getByText("ToastMessage - 1")).not.toBeVisible(); ?

Hi, I wanted to verify that the toast would be removed (auto-closed) after 5000ms, but it never disappeared. I followed the steps you described, yet the toast still remains in the DOM within my jest unit-tests using react-testing-library. Any new update on this issue? It's simple to test that it appears, but not disappear.😊

gillesbouvier-qz commented 4 months ago

Encountering the same issue. A solution would be appreciated.

gillesbouvier-qz commented 4 months ago

This is what works for me:

      await screen.findByText('text displayed on toast');

      const progressBar = screen.getByLabelText('notification timer');
      fireEvent.animationEnd(progressBar);

      const toastContainer =
        container.getElementsByClassName('Toastify__toast')[0];
      fireEvent.animationEnd(toastContainer);

      expect(
        screen.queryByText('text displayed on toast')
      ).not.toBeInTheDocument();