Skip to content

Commit 73bc433

Browse files
authored
Merge pull request #150 from jamdotdev/feat/migrate-har-from-canvas-to-html
feat: migrate har waterfall from canvas to html
2 parents 4dd9381 + 44fdcab commit 73bc433

File tree

6 files changed

+1075
-541
lines changed

6 files changed

+1075
-541
lines changed

__tests__/pages/utilities/har-file-viewer.test.tsx

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, screen, within } from "@testing-library/react";
1+
import { act, render, screen, within } from "@testing-library/react";
22
import { userEvent } from "@testing-library/user-event";
33
import HARFileViewer from "../../../pages/utilities/har-file-viewer";
44

@@ -50,6 +50,38 @@ const mockHarData = {
5050
};
5151

5252
describe("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: /table view/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

Comments
 (0)