chore(trace): improve loading progress bar (#22201)
Fixes: https://github.com/microsoft/playwright/issues/22118
This commit is contained in:
parent
bc1de5f28d
commit
0d31d69d65
|
|
@ -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<string, PageEntry>();
|
||||
|
|
@ -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<string, trace.ActionTraceEvent>();
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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: '<files>', type: 'string', name };
|
||||
if (name === 'eventInit' || name === 'expectedValue' || (name === 'arg' && isEval))
|
||||
value = parseSerializedValue(value.value, new Array(10).fill({ handle: '<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: '<handle>', 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 {
|
||||
|
|
|
|||
|
|
@ -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%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,10 +125,10 @@ export const WorkbenchLoader: React.FunctionComponent<{
|
|||
<div className='spacer'></div>
|
||||
<ToolbarButton icon='color-mode' title='Toggle color mode' toggled={false} onClick={() => toggleTheme()}></ToolbarButton>
|
||||
</div>
|
||||
<Workbench model={model} />
|
||||
{!!progress.total && <div className='progress'>
|
||||
<div className='inner-progress' style={{ width: (100 * progress.done / progress.total) + '%' }}></div>
|
||||
</div>}
|
||||
<Workbench model={model} />
|
||||
{fileForLocalModeError && <div className='drop-target'>
|
||||
<div>Trace Viewer uses Service Workers to show traces. To view trace:</div>
|
||||
<div style={{ paddingTop: 20 }}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue