mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 13:45:36 +03:00
chore: flush har when recording tracing (#26746)
This commit is contained in:
parent
4bbd16d316
commit
99b8ca2be2
@ -20,6 +20,7 @@ import { Artifact } from '../artifact';
|
||||
import type { BrowserContext } from '../browserContext';
|
||||
import type * as har from '@trace/har';
|
||||
import { HarTracer } from './harTracer';
|
||||
import type { HarTracerDelegate } from './harTracer';
|
||||
import type * as channels from '@protocol/channels';
|
||||
import { yazl } from '../../zipBundle';
|
||||
import type { ZipFile } from '../../zipBundle';
|
||||
@ -28,7 +29,7 @@ import type EventEmitter from 'events';
|
||||
import { createGuid } from '../../utils';
|
||||
import type { Page } from '../page';
|
||||
|
||||
export class HarRecorder {
|
||||
export class HarRecorder implements HarTracerDelegate {
|
||||
private _artifact: Artifact;
|
||||
private _isFlushed: boolean = false;
|
||||
private _tracer: HarTracer;
|
||||
|
@ -182,13 +182,7 @@ export class HarTracer {
|
||||
return null;
|
||||
if (!this._options.waitForContentOnStop)
|
||||
return;
|
||||
const race = Promise.race([
|
||||
new Promise<void>(f => target.on('close', () => {
|
||||
this._barrierPromises.delete(race);
|
||||
f();
|
||||
})),
|
||||
promise
|
||||
]) as Promise<void>;
|
||||
const race = target.openScope.safeRace(promise);
|
||||
this._barrierPromises.add(race);
|
||||
race.then(() => this._barrierPromises.delete(race));
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ export class Page extends SdkObject {
|
||||
private _eventsToEmitAfterInitialized: { event: string | symbol, args: any[] }[] = [];
|
||||
readonly _disconnectedScope = new LongStandingScope();
|
||||
readonly _crashedScope = new LongStandingScope();
|
||||
readonly openScope = new LongStandingScope();
|
||||
readonly _browserContext: BrowserContext;
|
||||
readonly keyboard: input.Keyboard;
|
||||
readonly mouse: input.Mouse;
|
||||
@ -276,6 +277,7 @@ export class Page extends SdkObject {
|
||||
this.emit(Page.Events.Close);
|
||||
this._closedPromise.resolve();
|
||||
this.instrumentation.onPageClose(this);
|
||||
this.openScope.close('Page closed');
|
||||
}
|
||||
|
||||
_didCrash() {
|
||||
@ -284,6 +286,7 @@ export class Page extends SdkObject {
|
||||
this.emit(Page.Events.Crash);
|
||||
this._crashedScope.close('Page crashed');
|
||||
this.instrumentation.onPageClose(this);
|
||||
this.openScope.close('Page closed');
|
||||
}
|
||||
|
||||
_didDisconnect() {
|
||||
@ -292,6 +295,7 @@ export class Page extends SdkObject {
|
||||
assert(!this._disconnected, 'Page disconnected twice');
|
||||
this._disconnected = true;
|
||||
this._disconnectedScope.close('Page closed');
|
||||
this.openScope.close('Page closed');
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(handle: dom.ElementHandle) {
|
||||
@ -711,6 +715,7 @@ export class Worker extends SdkObject {
|
||||
private _executionContextPromise: Promise<js.ExecutionContext>;
|
||||
private _executionContextCallback: (value: js.ExecutionContext) => void;
|
||||
_existingExecutionContext: js.ExecutionContext | null = null;
|
||||
readonly openScope = new LongStandingScope();
|
||||
|
||||
constructor(parent: SdkObject, url: string) {
|
||||
super(parent, 'worker');
|
||||
@ -732,6 +737,7 @@ export class Worker extends SdkObject {
|
||||
if (this._existingExecutionContext)
|
||||
this._existingExecutionContext.contextDestroyed('Worker was closed');
|
||||
this.emit(Worker.Events.Close, this);
|
||||
this.openScope.close('Worker closed');
|
||||
}
|
||||
|
||||
async evaluateExpression(expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
|
||||
|
@ -82,6 +82,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
private _tracesTmpDir: string | undefined;
|
||||
private _allResources = new Set<string>();
|
||||
private _contextCreatedEvent: trace.ContextCreatedTraceEvent;
|
||||
private _pendingHarEntries = new Set<har.Entry>();
|
||||
|
||||
constructor(context: BrowserContext | APIRequestContext, tracesDir: string | undefined) {
|
||||
super(context, 'tracing');
|
||||
@ -230,6 +231,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
if (this._state.recording)
|
||||
throw new Error(`Must stop trace file before stopping tracing`);
|
||||
this._harTracer.stop();
|
||||
this.flushHarEntries();
|
||||
await this._fs.syncAndGetError();
|
||||
this._state = undefined;
|
||||
}
|
||||
@ -272,6 +274,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
if (this._state.options.snapshots)
|
||||
await this._snapshotter?.stop();
|
||||
|
||||
this.flushHarEntries();
|
||||
|
||||
// Network file survives across chunks, make a snapshot before returning the resulting entries.
|
||||
// We should pick a name starting with "traceName" and ending with .network.
|
||||
// Something like <traceName>someSuffixHere.network.
|
||||
@ -387,14 +391,28 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||
}
|
||||
|
||||
onEntryStarted(entry: har.Entry) {
|
||||
this._pendingHarEntries.add(entry);
|
||||
}
|
||||
|
||||
onEntryFinished(entry: har.Entry) {
|
||||
this._pendingHarEntries.delete(entry);
|
||||
const event: trace.ResourceSnapshotTraceEvent = { type: 'resource-snapshot', snapshot: entry };
|
||||
const visited = visitTraceEvent(event, this._state!.networkSha1s);
|
||||
this._fs.appendFile(this._state!.networkFile, JSON.stringify(visited) + '\n', true /* flush */);
|
||||
}
|
||||
|
||||
flushHarEntries() {
|
||||
const harLines: string[] = [];
|
||||
for (const entry of this._pendingHarEntries) {
|
||||
const event: trace.ResourceSnapshotTraceEvent = { type: 'resource-snapshot', snapshot: entry };
|
||||
const visited = visitTraceEvent(event, this._state!.networkSha1s);
|
||||
harLines.push(JSON.stringify(visited));
|
||||
}
|
||||
this._pendingHarEntries.clear();
|
||||
if (harLines.length)
|
||||
this._fs.appendFile(this._state!.networkFile, harLines.join('\n') + '\n', true /* flush */);
|
||||
}
|
||||
|
||||
onContentBlob(sha1: string, buffer: Buffer) {
|
||||
this._appendResource(sha1, buffer);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user