diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.css b/packages/trace-viewer/src/ui/networkResourceDetails.css index 9310a6c553894..fff88aa577f5e 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.css +++ b/packages/trace-viewer/src/ui/networkResourceDetails.css @@ -23,20 +23,9 @@ flex: none; } -.network-request-details-url { - white-space: normal; - word-wrap: break-word; - margin-left: 10px; -} - -.network-request-details-headers { - white-space: pre; - overflow: hidden; - margin-left: 10px; -} - .network-request-details-tab .expandable-title { padding-left: 3px; + background-color: var(--vscode-sideBar-background); } .network-request-details-tab .expandable-content { @@ -50,9 +39,22 @@ font-weight: bold; } -.network-request-details-general { - white-space: pre; - margin-left: 10px; +.network-request-details-table { + width: 100%; + line-height: 18px; + padding: 8px 0 8px 8px; + white-space: pre-wrap; +} + +.network-request-details-table td:first-of-type { + width: 30%; + min-width: 160px; + vertical-align: top; +} + +.network-request-details-table td:nth-of-type(2) { + word-break: break-all; + vertical-align: center; } .network-request-details-tab .cm-wrapper { diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index 50f4a9eb42340..cab1d9c3e212a 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -108,9 +108,10 @@ const CopyDropdown: React.FC<{ const ExpandableSection: React.FC<{ title: string; + data?: { name: string, value: React.ReactNode }[], children?: React.ReactNode className?: string; -}> = ({ title, children, className }) => { +}> = ({ title, data, children, className }) => { const [expanded, setExpanded] = useSetting(`trace-viewer-network-details-${title.replaceAll(' ', '-')}`, true); return {title}} className={className} > + {data && + + {data.map(({ name, value }, index) => ( + value !== null && + ( + + + ) + ))} + +
{name}{value}
} {children}
; }; @@ -128,33 +140,26 @@ const RequestTab: React.FunctionComponent<{ startTimeOffset: number; requestBody: RequestBody, }> = ({ resource, startTimeOffset, requestBody }) => { - return
- -
{`URL: ${resource.request.url}`}
-
{`Method: ${resource.request.method}`}
- {resource.response.status !== -1 &&
- Status Code: - {`${resource.response.status} ${resource.response.statusText}`} -
} -
- - {resource.request.queryString.length ? - -
- {resource.request.queryString.map(param => `${param.name}: ${param.value}`).join('\n')} -
-
- : null} + const generalData = React.useMemo(() => + Object.entries({ + 'URL': resource.request.url, + 'Method': resource.request.method, + 'Status Code': resource.response.status !== -1 && {resource.response.status} {resource.response.statusText}, + }).map(([name, value]) => ({ name, value })), + [resource]); - -
{resource.request.headers.map(pair => `${pair.name}: ${pair.value}`).join('\n')}
-
- - -
{`Start: ${msToString(startTimeOffset)}`}
-
{`Duration: ${msToString(resource.time)}`}
-
+ const timeData = React.useMemo(() => + Object.entries({ + 'Start': msToString(startTimeOffset), + 'Duration': msToString(resource.time), + }).map(([name, value]) => ({ name, value })), + [startTimeOffset, resource]); + return
+ + {resource.request.queryString.length > 0 && } + + {requestBody && } @@ -165,9 +170,7 @@ const ResponseTab: React.FunctionComponent<{ resource: ResourceSnapshot; }> = ({ resource }) => { return
- -
{resource.response.headers.map(pair => `${pair.name}: ${pair.value}`).join('\n')}
-
+
; }; 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 c0fb4669c6f81..0e7014b5e76a6 100644 --- a/tests/playwright-test/ui-mode-test-network-tab.spec.ts +++ b/tests/playwright-test/ui-mode-test-network-tab.spec.ts @@ -197,9 +197,14 @@ test('should display list of query parameters (only if present)', async ({ runUI await page.getByText('call-with-query-params').click(); const region = page.getByRole('region', { name: 'Query String Parameters' }); - await expect(region.getByText('param1: value1')).toBeVisible(); - await expect(region.getByText('param1: value2')).toBeVisible(); - await expect(region.getByText('param2: value2')).toBeVisible(); + await expect(region).toMatchAriaSnapshot( + `- table: + - rowgroup: + - 'row "param1 value1"' + - 'row "param1 value2"' + - 'row "param2 value2"' + ` + ); await page.getByText('endpoint').click(); @@ -260,7 +265,7 @@ test('should toggle sections inside network details', async ({ runUITest, server await requestPanel.getByRole('button', { name: 'Request Headers' }).click(); await expect(requestPanel.getByRole('region', { name: 'Request Headers' })).toBeHidden(); - await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start: .+Duration: \d+ms/); + await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start.+Duration\d+ms/); await requestPanel.getByRole('button', { name: 'Time' }).click(); await expect(requestPanel.getByRole('region', { name: 'Request Headers' })).toBeHidden(); @@ -268,11 +273,11 @@ test('should toggle sections inside network details', async ({ runUITest, server await requestPanel.getByRole('button', { name: 'Time' }).click(); await expect(requestPanel.getByRole('region', { name: 'Request Headers' })).toBeHidden(); - await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start: .+Duration: \d+ms/); + await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start.+Duration\d+ms/); // Re-opening should preserve open state await page.getByRole('tabpanel', { name: 'Network' }).getByRole('button', { name: 'Close' }).click(); await page.getByRole('listitem').filter({ hasText: 'post-data-1' }).click(); await expect(requestPanel.getByRole('region', { name: 'Request Headers' })).toBeHidden(); - await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start: .+Duration: \d+ms/); + await expect(requestPanel.getByRole('region', { name: 'Time' })).toHaveText(/Start.+Duration\d+ms/); });