1- import { render , screen , within } from "@testing-library/react" ;
1+ import { act , render , screen , within } from "@testing-library/react" ;
22import { userEvent } from "@testing-library/user-event" ;
33import HARFileViewer from "../../../pages/utilities/har-file-viewer" ;
44
@@ -50,6 +50,38 @@ const mockHarData = {
5050} ;
5151
5252describe ( "HARFileViewer" , ( ) => {
53+ beforeEach ( ( ) => {
54+ jest . useFakeTimers ( ) ;
55+ } ) ;
56+
57+ afterEach ( ( ) => {
58+ act ( ( ) => {
59+ jest . runOnlyPendingTimers ( ) ;
60+ } ) ;
61+ jest . useRealTimers ( ) ;
62+ } ) ;
63+
64+ const uploadHarFile = async ( user : ReturnType < typeof userEvent . setup > ) => {
65+ const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.har" , {
66+ type : "application/json" ,
67+ } ) ;
68+ const fileInput = screen . getByTestId ( "input" ) ;
69+ await user . upload ( fileInput , file ) ;
70+ } ;
71+
72+ const flushDebounce = async ( ) => {
73+ await act ( async ( ) => {
74+ jest . advanceTimersByTime ( 350 ) ;
75+ } ) ;
76+ } ;
77+
78+ const switchToTableView = async (
79+ user : ReturnType < typeof userEvent . setup >
80+ ) => {
81+ const tableTab = await screen . findByRole ( "tab" , { name : / t a b l e v i e w / i } ) ;
82+ await user . click ( tableTab ) ;
83+ } ;
84+
5385 test ( "should render the component and display the drop zone text" , ( ) => {
5486 render ( < HARFileViewer /> ) ;
5587
@@ -59,35 +91,23 @@ describe("HARFileViewer", () => {
5991 } ) ;
6092
6193 test ( "should list all requests after uploading a har file" , async ( ) => {
62- const user = userEvent . setup ( ) ;
94+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
6395 render ( < HARFileViewer /> ) ;
6496
65- // Create a mock file
66- const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.har" , {
67- type : "application/json" ,
68- } ) ;
69-
70- // Find the file input and upload the file
71- const fileInput = screen . getByTestId ( "input" ) ;
72- await user . upload ( fileInput , file ) ;
97+ await uploadHarFile ( user ) ;
98+ await switchToTableView ( user ) ;
7399
74100 // Wait for the requests to be displayed
75101 await screen . findByText ( "https://example.com/api/test" ) ;
76102 await screen . findByText ( "https://example.com/css/style.css" ) ;
77103 } ) ;
78104
79105 test ( "should list the status code for every request" , async ( ) => {
80- const user = userEvent . setup ( ) ;
106+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
81107 render ( < HARFileViewer /> ) ;
82108
83- // Create a mock file
84- const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.har" , {
85- type : "application/json" ,
86- } ) ;
87-
88- // Find the file input and upload the file
89- const fileInput = screen . getByTestId ( "input" ) ;
90- await user . upload ( fileInput , file ) ;
109+ await uploadHarFile ( user ) ;
110+ await switchToTableView ( user ) ;
91111
92112 // Get all rows
93113 const rows = await screen . findAllByTestId ( "table-row" ) ;
@@ -102,17 +122,15 @@ describe("HARFileViewer", () => {
102122 } ) ;
103123
104124 test ( "should accept and process .json file extension" , async ( ) => {
105- const user = userEvent . setup ( ) ;
125+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
106126 render ( < HARFileViewer /> ) ;
107127
108- // Create a mock file with .json extension
109128 const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.json" , {
110129 type : "application/json" ,
111130 } ) ;
112-
113- // Find the file input and upload the file
114131 const fileInput = screen . getByTestId ( "input" ) ;
115132 await user . upload ( fileInput , file ) ;
133+ await switchToTableView ( user ) ;
116134
117135 // Wait for the requests to be displayed - this verifies the file was accepted
118136 await screen . findByText ( "https://example.com/api/test" ) ;
@@ -125,15 +143,12 @@ describe("HARFileViewer", () => {
125143 } ) ;
126144
127145 test ( "should filter requests based on search query" , async ( ) => {
128- const user = userEvent . setup ( ) ;
146+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
129147 render ( < HARFileViewer /> ) ;
130148
131149 // Upload a HAR file
132- const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.har" , {
133- type : "application/json" ,
134- } ) ;
135- const fileInput = screen . getByTestId ( "input" ) ;
136- await user . upload ( fileInput , file ) ;
150+ await uploadHarFile ( user ) ;
151+ await switchToTableView ( user ) ;
137152
138153 // Wait for all requests to be displayed
139154 await screen . findByText ( "https://example.com/api/test" ) ;
@@ -148,7 +163,7 @@ describe("HARFileViewer", () => {
148163 await user . type ( searchInput , "api" ) ;
149164
150165 // Wait for debounce (300ms) + rendering time
151- await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
166+ await flushDebounce ( ) ;
152167
153168 // Should still see the api request
154169 const rows = screen . queryAllByTestId ( "table-row" ) ;
@@ -157,15 +172,12 @@ describe("HARFileViewer", () => {
157172 } ) ;
158173
159174 test ( "should clear search query when clear button is clicked" , async ( ) => {
160- const user = userEvent . setup ( ) ;
175+ const user = userEvent . setup ( { advanceTimers : jest . advanceTimersByTime } ) ;
161176 render ( < HARFileViewer /> ) ;
162177
163178 // Upload a HAR file
164- const file = new File ( [ JSON . stringify ( mockHarData ) ] , "test.har" , {
165- type : "application/json" ,
166- } ) ;
167- const fileInput = screen . getByTestId ( "input" ) ;
168- await user . upload ( fileInput , file ) ;
179+ await uploadHarFile ( user ) ;
180+ await switchToTableView ( user ) ;
169181
170182 // Wait for requests to be displayed
171183 await screen . findByText ( "https://example.com/api/test" ) ;
@@ -177,11 +189,12 @@ describe("HARFileViewer", () => {
177189 await user . type ( searchInput , "api" ) ;
178190
179191 // Wait for debounce
180- await new Promise ( ( resolve ) => setTimeout ( resolve , 400 ) ) ;
192+ await flushDebounce ( ) ;
181193
182194 // Find the clear button (it should appear when there's text)
183195 const clearButton = screen . getByTitle ( "Clear search" ) ;
184196 await user . click ( clearButton ) ;
197+ await flushDebounce ( ) ;
185198
186199 // Search input should be empty
187200 expect ( searchInput ) . toHaveValue ( "" ) ;
0 commit comments