From 0d31d69d651813850b08ea7153084efe093bb8e4 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 5 Apr 2023 13:03:25 -0700 Subject: [PATCH] chore(trace): improve loading progress bar (#22201) Fixes: https://github.com/microsoft/playwright/issues/22118 --- packages/trace-viewer/src/traceModel.ts | 22 ++++++++++++++++++- packages/trace-viewer/src/ui/callTab.tsx | 4 +++- packages/trace-viewer/src/ui/workbench.css | 11 +++++----- .../trace-viewer/src/ui/workbenchLoader.tsx | 2 +- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/trace-viewer/src/traceModel.ts b/packages/trace-viewer/src/traceModel.ts index ada2e0a5a9..6c6eafcbe9 100644 --- a/packages/trace-viewer/src/traceModel.ts +++ b/packages/trace-viewer/src/traceModel.ts @@ -26,6 +26,18 @@ import { SnapshotStorage } from './snapshotStorage'; const zipjs = zipImport as typeof zip; +type Progress = (done: number, total: number) => void; + +const splitProgress = (progress: Progress, weights: number[]): Progress[] => { + const doneList = new Array(weights.length).fill(0); + return new Array(weights.length).fill(0).map((_, i) => { + return (done: number, total: number) => { + doneList[i] = done / total * weights[i] * 1000; + progress(doneList.reduce((a, b) => a + b, 0), 1000); + }; + }); +}; + export class TraceModel { contextEntries: ContextEntry[] = []; pageEntries = new Map(); @@ -38,7 +50,9 @@ export class TraceModel { async load(traceURL: string, progress: (done: number, total: number) => void) { const isLive = traceURL.endsWith('json'); - this._backend = isLive ? new FetchTraceModelBackend(traceURL) : new ZipTraceModelBackend(traceURL, progress); + // Allow 10% to hop from sw to page. + const [fetchProgress, unzipProgress] = splitProgress(progress, [0.5, 0.4, 0.1]); + this._backend = isLive ? new FetchTraceModelBackend(traceURL) : new ZipTraceModelBackend(traceURL, fetchProgress); const ordinals: string[] = []; let hasSource = false; @@ -54,6 +68,9 @@ export class TraceModel { this._snapshotStorage = new SnapshotStorage(); + // 3 * ordinals progress increments below. + const total = ordinals.length * 3; + let done = 0; for (const ordinal of ordinals) { const contextEntry = createEmptyContext(); const actionMap = new Map(); @@ -63,10 +80,12 @@ export class TraceModel { const trace = await this._backend.readText(ordinal + 'trace.trace') || ''; for (const line of trace.split('\n')) this.appendEvent(contextEntry, actionMap, line); + unzipProgress(++done, total); const network = await this._backend.readText(ordinal + 'trace.network') || ''; for (const line of network.split('\n')) this.appendEvent(contextEntry, actionMap, line); + unzipProgress(++done, total); contextEntry.actions = [...actionMap.values()].sort((a1, a2) => a1.startTime - a2.startTime); if (!isLive) { @@ -82,6 +101,7 @@ export class TraceModel { for (const action of contextEntry.actions) action.stack = action.stack || callMetadata.get(action.callId); } + unzipProgress(++done, total); this.contextEntries.push(contextEntry); } diff --git a/packages/trace-viewer/src/ui/callTab.tsx b/packages/trace-viewer/src/ui/callTab.tsx index 84c2f2960e..506a6e0960 100644 --- a/packages/trace-viewer/src/ui/callTab.tsx +++ b/packages/trace-viewer/src/ui/callTab.tsx @@ -90,6 +90,8 @@ function renderProperty(property: Property, key: string) { function propertyToString(event: ActionTraceEvent, name: string, value: any, sdkLanguage: Language | undefined): Property { const isEval = event.method.includes('eval') || event.method === 'waitForFunction'; + if (name === 'files') + return { text: '', type: 'string', name }; if (name === 'eventInit' || name === 'expectedValue' || (name === 'arg' && isEval)) value = parseSerializedValue(value.value, new Array(10).fill({ handle: '' })); if ((name === 'value' && isEval) || (name === 'received' && event.method === 'expect')) @@ -101,7 +103,7 @@ function propertyToString(event: ActionTraceEvent, name: string, value: any, sdk return { text: String(value), type, name }; if (value.guid) return { text: '', type: 'handle', name }; - return { text: JSON.stringify(value), type: 'object', name }; + return { text: JSON.stringify(value).slice(0, 1000), type: 'object', name }; } function parseSerializedValue(value: SerializedValue, handles: any[] | undefined): any { diff --git a/packages/trace-viewer/src/ui/workbench.css b/packages/trace-viewer/src/ui/workbench.css index 38d2289e52..e4ba7cdf77 100644 --- a/packages/trace-viewer/src/ui/workbench.css +++ b/packages/trace-viewer/src/ui/workbench.css @@ -59,15 +59,14 @@ } .progress { - position: relative; - margin: auto; - width: 400px; - height: 10px; - border: 1px solid #aaa; + width: 100%; + height: 3px; + margin-top: -3px; + z-index: 10; } .inner-progress { - background-color: #aaa; + background-color: var(--vscode-progressBar-background); height: 100%; } diff --git a/packages/trace-viewer/src/ui/workbenchLoader.tsx b/packages/trace-viewer/src/ui/workbenchLoader.tsx index 83266cbfe1..36d6fb1a87 100644 --- a/packages/trace-viewer/src/ui/workbenchLoader.tsx +++ b/packages/trace-viewer/src/ui/workbenchLoader.tsx @@ -125,10 +125,10 @@ export const WorkbenchLoader: React.FunctionComponent<{
toggleTheme()}> - {!!progress.total &&
} + {fileForLocalModeError &&
Trace Viewer uses Service Workers to show traces. To view trace: