From d9f72c266e66a49297536908ead4ceddf99a3089 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Sun, 15 Jun 2025 03:29:51 +0530 Subject: [PATCH 1/9] Make request tab sections collapsible with visual hierarchy --- .../src/ui/networkResourceDetails.css | 54 ++++++++ .../src/ui/networkResourceDetails.tsx | 118 +++++++++++++++--- 2 files changed, 152 insertions(+), 20 deletions(-) diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.css b/packages/trace-viewer/src/ui/networkResourceDetails.css index b3f7a5c04f01f..05d02f092fae0 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.css +++ b/packages/trace-viewer/src/ui/networkResourceDetails.css @@ -65,6 +65,60 @@ text-align: center; } +.network-collapsible-section { + margin-bottom: 12px; +} + +.network-collapsible-header { + font-weight: bold; + cursor: pointer; + display: flex; + align-items: center; + margin-bottom: 4px; + position: relative; +} + +.network-collapsible-header::before { + content: ''; + position: absolute; + inset: 0; + background-color: currentColor; + opacity: 0.07; + pointer-events: none; + border-radius: 4px; +} + +.network-collapsible-content { + padding-left: 16px; + white-space: pre-wrap; + font-family: monospace; +} + +.network-collapsible-suffix { + margin-left: 6px; + opacity: 0.7; + font-size: 14px; /* 90% of 16px default font size */ +} + +.network-key-value { + display: flex; + margin-bottom: 4px; /* 0.25rem ≈ 4px */ + align-items: center; +} + +.network-key { + font-weight: 400; + margin-right: 8px; /* 0.5rem ≈ 8px */ + min-width: 144px; /* 9rem ≈ 144px */ + white-space: nowrap; +} + +.network-value { + font-weight: 600; + word-break: break-word; + flex: 1; +} + .tab-network .toolbar { min-height: 30px !important; background-color: initial !important; diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index 5c87cb8d75faa..b914af4452e38 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -103,33 +103,111 @@ const CopyDropdown: React.FC<{ ); }; +const CollapsibleSection: React.FC<{ + title: string; + children: React.ReactNode; + defaultOpen?: boolean; + collapsedSuffix?: React.ReactNode; +}> = ({ title, children, defaultOpen = true, collapsedSuffix }) => { + const [isOpen, setIsOpen] = React.useState(defaultOpen); + + return ( +
+
setIsOpen(!isOpen)} + style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }} + > + + {title} + {!isOpen && collapsedSuffix && ( + + {collapsedSuffix} + + )} +
+ {isOpen &&
{children}
} +
+ ); +}; + const RequestTab: React.FunctionComponent<{ resource: ResourceSnapshot; startTimeOffset: number; requestBody: RequestBody, }> = ({ resource, startTimeOffset, requestBody }) => { return
-
General
-
{`URL: ${resource.request.url}`}
-
{`Method: ${resource.request.method}`}
- {resource.response.status !== -1 &&
- Status Code: - {`${resource.response.status} ${resource.response.statusText}`} -
} - {resource.request.queryString.length ? <> -
Query String Parameters
-
- {resource.request.queryString.map(param => `${param.name}: ${param.value}`).join('\n')} + +
+
URL
+
{resource.request.url}
+
+
+
Method
+
{resource.request.method}
+
+ {resource.response.status !== -1 && ( +
+
Status Code
+
+ + {`${resource.response.status} ${resource.response.statusText}`} + +
+
+ )} +
+ + {resource.request.queryString.length > 0 && ( + + {resource.request.queryString.map(param => ( +
+
{param.name}
+
{param.value}
- : null} -
Request Headers
-
{resource.request.headers.map(pair => `${pair.name}: ${pair.value}`).join('\n')}
-
Time
-
{`Start: ${msToString(startTimeOffset)}`}
-
{`Duration: ${msToString(resource.time)}`}
- - {requestBody &&
Request Body
} - {requestBody && } + ))} +
+)} + + + {resource.request.headers.map(header => ( +
+
{header.name}
+
{header.value}
+
+ ))} +
+ + +
+
Start
+
{msToString(startTimeOffset)}
+
+
+
Duration
+
{msToString(resource.time)}
+
+
+ +{requestBody && ( + + + +)}
; }; From d3708e77183082d444c063860e57beb2ee9ebc7c Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Sun, 15 Jun 2025 20:19:39 +0530 Subject: [PATCH 2/9] networkResourceDetails lintfix --- .../src/ui/networkResourceDetails.tsx | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index b914af4452e38..d9a82f6ec86f5 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -142,72 +142,72 @@ const RequestTab: React.FunctionComponent<{ requestBody: RequestBody, }> = ({ resource, startTimeOffset, requestBody }) => { return
- -
-
URL
-
{resource.request.url}
-
-
-
Method
-
{resource.request.method}
-
+ +
+
URL
+
{resource.request.url}
+
+
+
Method
+
{resource.request.method}
+
{resource.response.status !== -1 && (
-
Status Code
-
- - {`${resource.response.status} ${resource.response.statusText}`} - +
Status Code
+
+ + {`${resource.response.status} ${resource.response.statusText}`} + +
-
)}
{resource.request.queryString.length > 0 && ( - - {resource.request.queryString.map(param => ( -
-
{param.name}
-
{param.value}
+ + {resource.request.queryString.map(param => ( +
+
{param.name}
+
{param.value}
+
+ ))} +
+ )} + + + {resource.request.headers.map(header => ( +
+
{header.name}
+
{header.value}
+
+ ))} +
+ + +
+
Start
+
{msToString(startTimeOffset)}
- ))} -
-)} - - - {resource.request.headers.map(header => ( -
-
{header.name}
-
{header.value}
-
- ))} -
- - -
-
Start
-
{msToString(startTimeOffset)}
-
-
-
Duration
-
{msToString(resource.time)}
-
-
- -{requestBody && ( - - - -)} +
+
Duration
+
{msToString(resource.time)}
+
+ + + {requestBody && ( + + + + )}
; }; From bfc2a2f811b2254a99f7615027875a8ee0bee874 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Tue, 17 Jun 2025 15:02:08 +0530 Subject: [PATCH 3/9] Move inline styles to the stylesheet --- packages/trace-viewer/src/ui/networkResourceDetails.css | 5 +++++ packages/trace-viewer/src/ui/networkResourceDetails.tsx | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.css b/packages/trace-viewer/src/ui/networkResourceDetails.css index 05d02f092fae0..bbfaaf5e7bac8 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.css +++ b/packages/trace-viewer/src/ui/networkResourceDetails.css @@ -65,6 +65,10 @@ text-align: center; } +.codicon-chevron { + margin-right: 4px; +} + .network-collapsible-section { margin-bottom: 12px; } @@ -117,6 +121,7 @@ font-weight: 600; word-break: break-word; flex: 1; + display: 'inline-flex'; } .tab-network .toolbar { diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index d9a82f6ec86f5..9750ba7d747d4 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -116,11 +116,9 @@ const CollapsibleSection: React.FC<{
setIsOpen(!isOpen)} - style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }} > {title} {!isOpen && collapsedSuffix && ( @@ -155,7 +153,7 @@ const RequestTab: React.FunctionComponent<{
Status Code
- + {`${resource.response.status} ${resource.response.statusText}`}
From 9dff53a78d21a9d8afeaf2618460a8e56fc8544a Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Tue, 17 Jun 2025 15:04:50 +0530 Subject: [PATCH 4/9] Code Cleanup --- packages/trace-viewer/src/ui/networkResourceDetails.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.css b/packages/trace-viewer/src/ui/networkResourceDetails.css index bbfaaf5e7bac8..665dd66ffe68e 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.css +++ b/packages/trace-viewer/src/ui/networkResourceDetails.css @@ -101,19 +101,19 @@ .network-collapsible-suffix { margin-left: 6px; opacity: 0.7; - font-size: 14px; /* 90% of 16px default font size */ + font-size: 14px; } .network-key-value { display: flex; - margin-bottom: 4px; /* 0.25rem ≈ 4px */ + margin-bottom: 4px; align-items: center; } .network-key { font-weight: 400; - margin-right: 8px; /* 0.5rem ≈ 8px */ - min-width: 144px; /* 9rem ≈ 144px */ + margin-right: 8px; + min-width: 144px; white-space: nowrap; } From c551099a1c88bc0b9b3027de76deb850e04a30e3 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Tue, 17 Jun 2025 19:38:36 +0530 Subject: [PATCH 5/9] Test Fixes --- tests/playwright-test/ui-mode-test-network-tab.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright-test/ui-mode-test-network-tab.spec.ts b/tests/playwright-test/ui-mode-test-network-tab.spec.ts index 30c63494c1f2a..4c4173bcd2d6d 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -156,9 +156,9 @@ test('should display list of query parameters (only if present)', async ({ runUI await page.getByText('call-with-query-params').click(); await expect(page.getByText('Query String Parameters')).toBeVisible(); - await expect(page.getByText('param1: value1')).toBeVisible(); - await expect(page.getByText('param1: value2')).toBeVisible(); - await expect(page.getByText('param2: value2')).toBeVisible(); + await expect(page.getByText('param1 value1')).toBeVisible(); + await expect(page.getByText('param1 value2')).toBeVisible(); + await expect(page.getByText('param2 value2')).toBeVisible(); await page.getByText('endpoint').click(); From 429093ac7ff22af5ae4d7d2369963ec29a45dcc0 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Tue, 17 Jun 2025 22:10:27 +0530 Subject: [PATCH 6/9] Query String Test Script Fix --- .../ui-mode-test-network-tab.spec.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/playwright-test/ui-mode-test-network-tab.spec.ts b/tests/playwright-test/ui-mode-test-network-tab.spec.ts index 4c4173bcd2d6d..bcabd47bfbff4 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -156,9 +156,17 @@ test('should display list of query parameters (only if present)', async ({ runUI await page.getByText('call-with-query-params').click(); await expect(page.getByText('Query String Parameters')).toBeVisible(); - await expect(page.getByText('param1 value1')).toBeVisible(); - await expect(page.getByText('param1 value2')).toBeVisible(); - await expect(page.getByText('param2 value2')).toBeVisible(); + await expect( + page.locator('.network-key-value', { hasText: 'param1' }).nth(0).locator('.network-value') + ).toHaveText('value1'); + + await expect( + page.locator('.network-key-value', { hasText: 'param1' }).nth(1).locator('.network-value') + ).toHaveText('value2'); + + await expect( + page.locator('.network-key-value', { hasText: 'param2' }).locator('.network-value') + ).toHaveText('value2'); await page.getByText('endpoint').click(); From 029deed787c2afb7066ab2a56f3a521a79d2ed2f Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Wed, 18 Jun 2025 01:12:38 +0530 Subject: [PATCH 7/9] Script fix --- tests/playwright-test/ui-mode-test-network-tab.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright-test/ui-mode-test-network-tab.spec.ts b/tests/playwright-test/ui-mode-test-network-tab.spec.ts index bcabd47bfbff4..5630d883f5039 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -157,15 +157,15 @@ test('should display list of query parameters (only if present)', async ({ runUI await expect(page.getByText('Query String Parameters')).toBeVisible(); await expect( - page.locator('.network-key-value', { hasText: 'param1' }).nth(0).locator('.network-value') + page.locator('.network-key-value:has(.network-key:text("param1"))').nth(0).locator('.network-value') ).toHaveText('value1'); await expect( - page.locator('.network-key-value', { hasText: 'param1' }).nth(1).locator('.network-value') + page.locator('.network-key-value:has(.network-key:text("param1"))').nth(1).locator('.network-value') ).toHaveText('value2'); await expect( - page.locator('.network-key-value', { hasText: 'param2' }).locator('.network-value') + page.locator('.network-key-value:has(.network-key:text("param2"))').locator('.network-value') ).toHaveText('value2'); await page.getByText('endpoint').click(); From 1b250174074f398f5316f724e708d2e15e64e878 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Wed, 18 Jun 2025 01:15:18 +0530 Subject: [PATCH 8/9] Script fix --- tests/playwright-test/ui-mode-test-network-tab.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/playwright-test/ui-mode-test-network-tab.spec.ts b/tests/playwright-test/ui-mode-test-network-tab.spec.ts index 5630d883f5039..cd29092f1e4b0 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -156,6 +156,7 @@ test('should display list of query parameters (only if present)', async ({ runUI await page.getByText('call-with-query-params').click(); await expect(page.getByText('Query String Parameters')).toBeVisible(); + await expect( page.locator('.network-key-value:has(.network-key:text("param1"))').nth(0).locator('.network-value') ).toHaveText('value1'); From f442c2f48194fd927d8d0910ae898cde71d591b3 Mon Sep 17 00:00:00 2001 From: Nihal Kumar Date: Thu, 19 Jun 2025 01:26:26 +0530 Subject: [PATCH 9/9] Update script to support enhancement --- tests/playwright-test/ui-mode-test-network-tab.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/playwright-test/ui-mode-test-network-tab.spec.ts b/tests/playwright-test/ui-mode-test-network-tab.spec.ts index cd29092f1e4b0..5bddcfaa6ca31 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -156,7 +156,8 @@ test('should display list of query parameters (only if present)', async ({ runUI await page.getByText('call-with-query-params').click(); await expect(page.getByText('Query String Parameters')).toBeVisible(); - + await page.getByText('Query String Parameters').click(); + await expect( page.locator('.network-key-value:has(.network-key:text("param1"))').nth(0).locator('.network-value') ).toHaveText('value1');