diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx
index 63be975e26953..9a99a3a9a921f 100644
--- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx
+++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx
@@ -150,7 +150,7 @@ const HeadersTab: React.FunctionComponent<{
Object.entries({
'URL': resource.request.url,
'Method': resource.request.method,
- 'Status Code': resource.response.status !== -1 && {resource.response.status} {resource.response.statusText},
+ 'Status Code': resource.response.status === -1 ? 'canceled' : resource.response.status > 0 && {resource.response.status} {resource.response.statusText},
'Start': msToString(startTimeOffset),
'Duration': msToString(resource.time),
}).map(([name, value]) => ({ name, value })),
diff --git a/packages/trace-viewer/src/ui/networkTab.tsx b/packages/trace-viewer/src/ui/networkTab.tsx
index 4d02cc558e710..f3c32a97489ff 100644
--- a/packages/trace-viewer/src/ui/networkTab.tsx
+++ b/packages/trace-viewer/src/ui/networkTab.tsx
@@ -196,8 +196,8 @@ const renderCell = (entry: RenderedEntry, column: ColumnName): RenderedGridCell
return { body: entry.method };
if (column === 'status') {
return {
- body: entry.status.code > 0 ? entry.status.code : '',
- title: entry.status.text
+ body: entry.status.code === -1 ? 'canceled' : entry.status.code > 0 ? entry.status.code : '',
+ title: entry.status.code === -1 ? 'canceled' : entry.status.text,
};
}
if (column === 'contentType')
diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts
index b4e1478132633..661a9dafe06aa 100644
--- a/tests/library/trace-viewer.spec.ts
+++ b/tests/library/trace-viewer.spec.ts
@@ -556,10 +556,28 @@ test('should have network request overrides', async ({ page, server, runAndTrace
await traceViewer.selectAction('Navigate');
await traceViewer.showNetworkTab();
await expect(traceViewer.networkRequests).toContainText([/frame.htmlGET200text\/html/]);
- await expect(traceViewer.networkRequests).toContainText([/style.cssGETx-unknown.*aborted/]);
+ await expect(traceViewer.networkRequests).toContainText([/style.cssGETcanceledx-unknown.*aborted/]);
await expect(traceViewer.networkRequests).not.toContainText([/continued/]);
});
+test('should show canceled status for requests canceled by navigation', async ({ page, server, runAndTrace }) => {
+ server.setRoute('/slow', (_req, _res) => {
+ // Never respond so the request stays in-flight until navigation cancels it.
+ });
+ const traceViewer = await runAndTrace(async () => {
+ await page.goto(server.PREFIX + '/empty.html');
+ const requestPromise = page.waitForRequest(server.PREFIX + '/slow');
+ page.evaluate(url => fetch(url).catch(() => {}), server.PREFIX + '/slow').catch(() => {});
+ await requestPromise;
+ // Navigate away to cancel the in-flight request.
+ await page.goto(server.PREFIX + '/empty.html?navigated=1');
+ });
+ await traceViewer.showNetworkTab();
+ const slowRequest = traceViewer.networkRequests.filter({ hasText: 'slow' });
+ await expect(slowRequest).toContainText([/GETcanceled/]);
+ await expect(slowRequest).toHaveCSS('background-color', 'rgb(242, 222, 222)');
+});
+
test('should have network request overrides 2', async ({ page, server, runAndTrace }) => {
const traceViewer = await runAndTrace(async () => {
await page.route('**/script.js', route => route.continue());