Reputation: 6368
I have built a wrapper around react-toastify, so that I can call it at multiple places.
Here is the code for wrapper:
import { ReactText } from 'react';
import { toast } from 'react-toastify';
export const showNotification: (
message: string,
type?: 'info' | 'success' | 'warning' | 'error',
timeOut?: number,
) => ReactText
= (message, type = 'success', timeOut = 5000) => toast(
message, { type, autoClose: timeOut },
);
export const dismissNotification = (toastId: ReactText) => toast.dismiss(toastId);
Now, I am testing my dismissNotification function.
I have written this test case:
it('dismisses notification when called', async () => {
render(<ToastContainer />);
const notificationId = showNotification('Test Notification', 'success', 2000);
await waitFor(() => {
expect(screen.getByText('Test Notification')).toBeInTheDocument();
});
dismissNotification(notificationId);
await waitForElementToBeRemoved(() => {
expect(screen.queryByText('Test Notification')).not.toBeInTheDocument();
});
});
But last test case always fails saying that a dom node with text Test Notification
is present.
Actual Error:
dismisses notification when called
expect(element).not.toBeInTheDocument()
expected document not to contain element, found <div class="Toastify__toast-body" role="alert">Test Notification</div> instead
Upvotes: 2
Views: 4497
Reputation: 1901
It looks like you are using waitForElementToBeRemoved
incorrectly. According to the documentation, "the first argument must be an element, array of elements, or a callback which returns an element or array of elements."
In addition, it looks like you are facing some issue with the timeout. It seems the animation is causing the element to remain in the DOM for longer than you expect. You can perform two quick tests to confirm this is an issue.
First, inspect the DOM in your browser. When you dismiss the notification, you can see that the element is not removed right away.
Second, try setting a custom transition so we can play around with the duration. When you set the collapseDuration
to something like 5000
, the toast takes a long time to disappear, and the test fails. When you set the collapseDuration
to 0
, the toast disappears immediately, and the test passes.
const Zoom = cssTransition({
enter: 'zoomIn',
exit: 'zoomOut',
collapseDuration: 0,
//duration: 5000,
});
toast(message, {
type,
autoClose: timeOut,
transition: Zoom,
});
So I think you need to both fix how you are using waitForElementToBeRemoved
and also apply a custom timeout
. Try this code:
await waitForElementToBeRemoved(screen.queryByText('Test Notification'), { timeout: 5000 });
Upvotes: 4