From 684159728f787e507b1c9f63ccd140385da02044 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Wed, 29 May 2024 19:02:38 -0700 Subject: [PATCH] chore(trace-viewer): preserve column widths after showing resource details --- packages/trace-viewer/src/ui/networkTab.tsx | 20 ++++++++---- packages/web/src/components/gridView.tsx | 34 +++++++++++++++------ tests/library/browsercontext-basic.spec.ts | 17 +++++++++++ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/packages/trace-viewer/src/ui/networkTab.tsx b/packages/trace-viewer/src/ui/networkTab.tsx index d007d58198..ecab8cacf0 100644 --- a/packages/trace-viewer/src/ui/networkTab.tsx +++ b/packages/trace-viewer/src/ui/networkTab.tsx @@ -76,6 +76,10 @@ export const NetworkTab: React.FunctionComponent<{ return { renderedEntries }; }, [networkModel.resources, networkModel.contextIdMap, sorting, boundaries]); + const [widths, setWidths] = React.useState>(() => { + return new Map(allColumns().map(column => [column, columnWidth(column)])); + }); + if (!networkModel.resources.length) return ; @@ -87,7 +91,8 @@ export const NetworkTab: React.FunctionComponent<{ onHighlighted={item => onEntryHovered(item?.resource)} columns={visibleColumns(!!selectedEntry, renderedEntries)} columnTitle={columnTitle} - columnWidth={columnWidth} + columnWidths={widths} + setColumnWidths={setWidths} isError={item => item.status.code >= 400} isInfo={item => !!item.route} render={(item, column) => renderCell(item, column)} @@ -96,7 +101,7 @@ export const NetworkTab: React.FunctionComponent<{ />; return <> {!selectedEntry && grid} - {selectedEntry && + {selectedEntry && setSelectedEntry(undefined)} /> {grid} } @@ -142,13 +147,16 @@ const columnWidth = (column: ColumnName) => { function visibleColumns(entrySelected: boolean, renderedEntries: RenderedEntry[]): (keyof RenderedEntry)[] { if (entrySelected) return ['name']; - const columns: (keyof RenderedEntry)[] = []; - if (hasMultipleContexts(renderedEntries)) - columns.push('contextId'); - columns.push('name', 'method', 'status', 'contentType', 'duration', 'size', 'start', 'route'); + let columns: (keyof RenderedEntry)[] = allColumns(); + if (!hasMultipleContexts(renderedEntries)) + columns = columns.filter(name => name !== 'contextId'); return columns; } +function allColumns(): (keyof RenderedEntry)[] { + return ['contextId', 'name', 'method', 'status', 'contentType', 'duration', 'size', 'start', 'route']; +} + const renderCell = (entry: RenderedEntry, column: ColumnName): RenderedGridCell => { if (column === 'contextId') { return { diff --git a/packages/web/src/components/gridView.tsx b/packages/web/src/components/gridView.tsx index 2a5257da2b..5e97d8dba8 100644 --- a/packages/web/src/components/gridView.tsx +++ b/packages/web/src/components/gridView.tsx @@ -30,19 +30,33 @@ export type RenderedGridCell = { export type GridViewProps = Omit, 'render'> & { columns: (keyof T)[], columnTitle: (column: keyof T) => string, - columnWidth: (column: keyof T) => number, + columnWidths: Map, + setColumnWidths: (widths: Map) => void, render: (item: T, column: keyof T, index: number) => RenderedGridCell, sorting?: Sorting, setSorting?: (sorting: Sorting | undefined) => void, }; export function GridView(model: GridViewProps) { - const initialOffsets: number[] = []; - for (let i = 0; i < model.columns.length - 1; ++i) { - const column = model.columns[i]; - initialOffsets[i] = (initialOffsets[i - 1] || 0) + model.columnWidth(column); + function offsets() { + const offsets: number[] = []; + for (let i = 0; i < model.columns.length - 1; ++i) { + const column = model.columns[i]; + offsets[i] = (offsets[i - 1] || 0) + model.columnWidths.get(column)!; + } + console.log('offsets', offsets, model.columns); + return offsets; + } + function setOffsets(offsets: number[]) { + const widths = new Map(model.columnWidths.entries()); + for (let i = 0; i < offsets.length; ++i) { + const width = offsets[i] - (offsets[i - 1] || 0); + const column = model.columns[i]; + widths.set(column, width); + } + console.log('setOffsets', offsets); + model.setColumnWidths(widths); } - const [offsets, setOffsets] = React.useState(initialOffsets); const toggleSorting = React.useCallback((f: keyof T) => { model.setSorting?.({ by: f, negate: model.sorting?.by === f ? !model.sorting.negate : false }); @@ -51,7 +65,7 @@ export function GridView(model: GridViewProps) { return
(model: GridViewProps) { return
model.setSorting && toggleSorting(column)} > @@ -84,7 +98,9 @@ export function GridView(model: GridViewProps) { return
+ style={{ + width: i < model.columns.length - 1 ? model.columnWidths.get(column) : undefined, + }}> {body}
; })} diff --git a/tests/library/browsercontext-basic.spec.ts b/tests/library/browsercontext-basic.spec.ts index f075184cf9..9c6bcad78b 100644 --- a/tests/library/browsercontext-basic.spec.ts +++ b/tests/library/browsercontext-basic.spec.ts @@ -19,6 +19,7 @@ import { kTargetClosedErrorMessage } from '../config/errors'; import { browserTest as it, expect } from '../config/browserTest'; import { attachFrame, verifyViewport } from '../config/utils'; import type { Page } from '@playwright/test'; +import { request } from '@playwright/test'; it('should create new context @smoke', async function({ browser }) { expect(browser.contexts().length).toBe(0); @@ -31,6 +32,22 @@ it('should create new context @smoke', async function({ browser }) { expect(browser).toBe(context.browser()); }); +it('log two contexts', async function({ browser }) { + const context1 = await browser.newContext(); + const context2 = await browser.newContext(); + const api1 = await request.newContext(); + const api2 = await request.newContext(); + const page1 = await context1.newPage(); + const page2 = await context2.newPage(); + await page1.evaluate(() => { window.open('about:blank'); }); + const promises = []; + promises.push(page1.goto('https://playwright.dev/')); + promises.push(page2.goto('https://theverge.com/')); + promises.push(api1.get('https://playwright.dev/')); + promises.push(api2.get('https://theverge.com/')); + await Promise.all(promises); +}); + it('should be able to click across browser contexts', async function({ browser }) { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29096' }); expect(browser.contexts().length).toBe(0);