22 * Toast Component Tests
33 */
44
5- import { describe , it , expect , vi , beforeEach } from 'vitest' ;
6- import { render , screen , waitFor } from '@testing-library/react' ;
5+ import { describe , it , expect , vi , afterEach } from 'vitest' ;
6+ import { render , waitFor } from '@testing-library/react' ;
77import userEvent from '@testing-library/user-event' ;
88import { ToastProvider , useToast } from './Toast' ;
99
1010// Test component that uses the toast hook
1111const ToastTrigger = ( ) => {
12- const { showSuccess, showError, showWarning, showInfo } = useToast ( ) ;
12+ const { showToast } = useToast ( ) ;
13+
14+ const showSuccess = ( message : string ) => showToast ( 'success' , message ) ;
15+ const showError = ( message : string ) => showToast ( 'error' , message ) ;
16+ const showWarning = ( message : string ) => showToast ( 'warning' , message ) ;
17+ const showInfo = ( message : string ) => showToast ( 'info' , message ) ;
1318
1419 return (
1520 < div >
@@ -22,142 +27,147 @@ const ToastTrigger = () => {
2227} ;
2328
2429describe ( 'Toast System' , ( ) => {
25- beforeEach ( ( ) => {
26- vi . useFakeTimers ( ) ;
27- } ) ;
28-
30+ // Don't use fake timers by default
2931 afterEach ( ( ) => {
30- vi . restoreAllMocks ( ) ;
32+ vi . clearAllMocks ( ) ;
33+ vi . useRealTimers ( ) ; // Ensure timers are real
3134 } ) ;
3235
3336 it ( 'should render ToastProvider without crashing' , ( ) => {
34- render (
37+ const { getByText } = render (
3538 < ToastProvider >
3639 < div > Content</ div >
3740 </ ToastProvider >
3841 ) ;
3942
40- expect ( screen . getByText ( 'Content' ) ) . toBeInTheDocument ( ) ;
43+ expect ( getByText ( 'Content' ) ) . toBeInTheDocument ( ) ;
4144 } ) ;
4245
4346 it ( 'should show success toast' , async ( ) => {
44- const user = userEvent . setup ( { delay : null } ) ;
45- render (
47+ const user = userEvent . setup ( ) ;
48+ const { getByText , getByRole } = render (
4649 < ToastProvider >
4750 < ToastTrigger />
4851 </ ToastProvider >
4952 ) ;
5053
51- await user . click ( screen . getByText ( 'Show Success' ) ) ;
54+ await user . click ( getByText ( 'Show Success' ) ) ;
5255
53- expect ( screen . getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
54- expect ( screen . getByRole ( 'alert' ) ) . toBeInTheDocument ( ) ;
56+ expect ( getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
57+ expect ( getByRole ( 'alert' ) ) . toBeInTheDocument ( ) ;
5558 } ) ;
5659
5760 it ( 'should show error toast' , async ( ) => {
58- const user = userEvent . setup ( { delay : null } ) ;
59- render (
61+ const user = userEvent . setup ( ) ;
62+ const { getByText } = render (
6063 < ToastProvider >
6164 < ToastTrigger />
6265 </ ToastProvider >
6366 ) ;
6467
65- await user . click ( screen . getByText ( 'Show Error' ) ) ;
68+ await user . click ( getByText ( 'Show Error' ) ) ;
6669
67- expect ( screen . getByText ( 'Error message' ) ) . toBeInTheDocument ( ) ;
70+ expect ( getByText ( 'Error message' ) ) . toBeInTheDocument ( ) ;
6871 } ) ;
6972
7073 it ( 'should show warning toast' , async ( ) => {
71- const user = userEvent . setup ( { delay : null } ) ;
72- render (
74+ const user = userEvent . setup ( ) ;
75+ const { getByText } = render (
7376 < ToastProvider >
7477 < ToastTrigger />
7578 </ ToastProvider >
7679 ) ;
7780
78- await user . click ( screen . getByText ( 'Show Warning' ) ) ;
81+ await user . click ( getByText ( 'Show Warning' ) ) ;
7982
80- expect ( screen . getByText ( 'Warning message' ) ) . toBeInTheDocument ( ) ;
83+ expect ( getByText ( 'Warning message' ) ) . toBeInTheDocument ( ) ;
8184 } ) ;
8285
8386 it ( 'should show info toast' , async ( ) => {
84- const user = userEvent . setup ( { delay : null } ) ;
85- render (
87+ const user = userEvent . setup ( ) ;
88+ const { getByText } = render (
8689 < ToastProvider >
8790 < ToastTrigger />
8891 </ ToastProvider >
8992 ) ;
9093
91- await user . click ( screen . getByText ( 'Show Info' ) ) ;
94+ await user . click ( getByText ( 'Show Info' ) ) ;
9295
93- expect ( screen . getByText ( 'Info message' ) ) . toBeInTheDocument ( ) ;
96+ expect ( getByText ( 'Info message' ) ) . toBeInTheDocument ( ) ;
9497 } ) ;
9598
9699 it ( 'should close toast when close button is clicked' , async ( ) => {
97- const user = userEvent . setup ( { delay : null } ) ;
98- render (
100+ const user = userEvent . setup ( ) ;
101+ const { getByText , getByRole , queryByText } = render (
99102 < ToastProvider >
100103 < ToastTrigger />
101104 </ ToastProvider >
102105 ) ;
103106
104- await user . click ( screen . getByText ( 'Show Success' ) ) ;
105- expect ( screen . getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
107+ await user . click ( getByText ( 'Show Success' ) ) ;
108+ expect ( getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
106109
107- const closeButton = screen . getByRole ( 'button' , { name : / c l o s e / i } ) ;
110+ const closeButton = getByRole ( 'button' , { name : / c l o s e / i } ) ;
108111 await user . click ( closeButton ) ;
109112
113+ // Wait a tick for state update
110114 await waitFor ( ( ) => {
111- expect ( screen . queryByText ( 'Success message' ) ) . not . toBeInTheDocument ( ) ;
115+ expect ( queryByText ( 'Success message' ) ) . not . toBeInTheDocument ( ) ;
112116 } ) ;
113117 } ) ;
114118
115119 it ( 'should auto-dismiss toast after duration' , async ( ) => {
116- render (
120+ const { getByText , queryByText } = render (
117121 < ToastProvider >
118122 < ToastTrigger />
119123 </ ToastProvider >
120124 ) ;
121125
122- const user = userEvent . setup ( { delay : null } ) ;
123- await user . click ( screen . getByText ( 'Show Success' ) ) ;
124-
125- expect ( screen . getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
126+ const user = userEvent . setup ( ) ;
127+ await user . click ( getByText ( 'Show Success' ) ) ;
126128
127- // Fast-forward time by 5 seconds (default duration)
128- vi . advanceTimersByTime ( 5000 ) ;
129+ expect ( getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
129130
130- await waitFor ( ( ) => {
131- expect ( screen . queryByText ( 'Success message' ) ) . not . toBeInTheDocument ( ) ;
132- } ) ;
131+ // Wait for auto-dismiss (default duration is 3000ms)
132+ await waitFor (
133+ ( ) => {
134+ expect ( queryByText ( 'Success message' ) ) . not . toBeInTheDocument ( ) ;
135+ } ,
136+ { timeout : 4000 }
137+ ) ;
133138 } ) ;
134139
135140 it ( 'should have accessible ARIA attributes' , async ( ) => {
136- const user = userEvent . setup ( { delay : null } ) ;
137- render (
141+ const user = userEvent . setup ( ) ;
142+ const { getByText , getByRole } = render (
138143 < ToastProvider >
139144 < ToastTrigger />
140145 </ ToastProvider >
141146 ) ;
142147
143- await user . click ( screen . getByText ( 'Show Success' ) ) ;
148+ await user . click ( getByText ( 'Show Success' ) ) ;
149+
150+ const alert = getByRole ( 'alert' ) ;
151+ expect ( alert ) . toBeInTheDocument ( ) ;
144152
145- const toast = screen . getByRole ( 'alert' ) ;
146- expect ( toast ) . toHaveAttribute ( 'aria-live' , 'polite' ) ;
153+ // Check if toast container has ARIA region
154+ const region = getByRole ( 'region' , { name : / n o t i f i c a t i o n s / i } ) ;
155+ expect ( region ) . toBeInTheDocument ( ) ;
156+ expect ( region ) . toHaveAttribute ( 'aria-live' , 'polite' ) ;
147157 } ) ;
148158
149159 it ( 'should display multiple toasts' , async ( ) => {
150- const user = userEvent . setup ( { delay : null } ) ;
151- render (
160+ const user = userEvent . setup ( ) ;
161+ const { getByText } = render (
152162 < ToastProvider >
153163 < ToastTrigger />
154164 </ ToastProvider >
155165 ) ;
156166
157- await user . click ( screen . getByText ( 'Show Success' ) ) ;
158- await user . click ( screen . getByText ( 'Show Error' ) ) ;
167+ await user . click ( getByText ( 'Show Success' ) ) ;
168+ await user . click ( getByText ( 'Show Error' ) ) ;
159169
160- expect ( screen . getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
161- expect ( screen . getByText ( 'Error message' ) ) . toBeInTheDocument ( ) ;
170+ expect ( getByText ( 'Success message' ) ) . toBeInTheDocument ( ) ;
171+ expect ( getByText ( 'Error message' ) ) . toBeInTheDocument ( ) ;
162172 } ) ;
163173} ) ;
0 commit comments