diff --git a/packages/trace-viewer/src/ui/workbench.tsx b/packages/trace-viewer/src/ui/workbench.tsx index 58ee991e8de45..1859852bb6b93 100644 --- a/packages/trace-viewer/src/ui/workbench.tsx +++ b/packages/trace-viewer/src/ui/workbench.tsx @@ -78,6 +78,7 @@ const PartitionedWorkbench: React.FunctionComponent('navigatorTab', 'actions'); const [selectedPropertiesTab, setSelectedPropertiesTab] = useSetting('propertiesTab', showSourcesFirst ? 'source' : 'call'); const [sidebarLocation, setSidebarLocation] = useSetting<'bottom' | 'right'>('propertiesSidebarLocation', 'bottom'); + const [browserPanelHidden, setBrowserPanelHidden] = useSetting('browserPanelHidden', false); const [actionsFilter] = useSetting('actionsFilter', []); // Per-model settings, should be primitive non-retaining types. @@ -360,6 +361,44 @@ const PartitionedWorkbench: React.FunctionComponent; + const propertiesPaneToolbar = [ + browserPanelHidden ? + setBrowserPanelHidden(false)} /> : + setBrowserPanelHidden(true)} />, + ]; + if (!browserPanelHidden) { + propertiesPaneToolbar.push(sidebarLocation === 'bottom' ? + { + setSidebarLocation('right'); + }} /> : + { + setSidebarLocation('bottom'); + }} /> + ); + } + const navigatorPane = ; + const propertiesPane = ; + const browserPane = ; return
{!hideTimeline && } - sidebar={ - - } - />} - sidebar={ { - setSidebarLocation('right'); - }} /> : - { - setSidebarLocation('bottom'); - }} /> - ]} - mode={sidebarLocation === 'bottom' ? 'default' : 'select'} + main={browserPanelHidden ? propertiesPane : browserPane} + sidebar={navigatorPane} />} + sidebarHidden={browserPanelHidden} + sidebar={propertiesPane} />
; }; diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts index e8bc8e1d359c3..d40cbbace372f 100644 --- a/tests/library/trace-viewer.spec.ts +++ b/tests/library/trace-viewer.spec.ts @@ -481,6 +481,36 @@ test('should have network requests', async ({ showTraceViewer }) => { await expect(traceViewer.networkRequests.filter({ hasText: '404GET404text' })).toHaveCSS('background-color', 'rgb(242, 222, 222)'); }); +test('should expand network details when browser panel is hidden', async ({ showTraceViewer }) => { + test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/41062' }); + const traceViewer = await showTraceViewer(traceFile); + await traceViewer.selectAction('Navigate'); + await traceViewer.showNetworkTab(); + const networkTab = traceViewer.networkTab; + const initialBox = await networkTab.boundingBox(); + + await expect(traceViewer.snapshotContainer).toBeVisible(); + await expect(traceViewer.page.getByRole('button', { name: 'Dock to right' })).toBeVisible(); + await traceViewer.page.getByRole('button', { name: 'Hide browser panel' }).click(); + await expect(traceViewer.snapshotContainer).toBeHidden(); + await expect(traceViewer.page.getByRole('button', { name: 'Show browser panel' })).toBeVisible(); + await expect(traceViewer.page.getByRole('button', { name: 'Dock to right' })).toBeHidden(); + await expect(traceViewer.actionsTree).toBeVisible(); + await traceViewer.selectAction('Click'); + await expect(traceViewer.actionsTree.getByRole('treeitem', { selected: true })).toHaveText(/Click/); + await traceViewer.selectAction('Navigate'); + const expandedBox = await networkTab.boundingBox(); + + expect(initialBox).toBeTruthy(); + expect(expandedBox).toBeTruthy(); + expect(expandedBox!.height).toBeGreaterThan(initialBox!.height); + await expect(traceViewer.networkRequests).toContainText([/frame.htmlGET200text\/html/]); + + await traceViewer.page.getByRole('button', { name: 'Show browser panel' }).click(); + await expect(traceViewer.snapshotContainer).toBeVisible(); + await expect(traceViewer.page.getByRole('button', { name: 'Dock to right' })).toBeVisible(); +}); + test('should highlight network request on timeline on hover', async ({ showTraceViewer }) => { const traceViewer = await showTraceViewer(traceFile); await traceViewer.selectAction('Navigate');