chore: split client-side instrumentation into sync and async (#31054)

This commit is contained in:
Pavel Feldman 2024-05-28 14:29:57 -07:00 committed by GitHub
parent 61203964a8
commit 6675652269
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 32 additions and 23 deletions

View File

@ -235,11 +235,11 @@ export class BrowserType extends ChannelOwner<channels.BrowserTypeChannel> imple
context.setDefaultTimeout(this._defaultContextTimeout);
if (this._defaultContextNavigationTimeout !== undefined)
context.setDefaultNavigationTimeout(this._defaultContextNavigationTimeout);
await this._instrumentation.onDidCreateBrowserContext(context);
await this._instrumentation.runAfterCreateBrowserContext(context);
}
async _willCloseContext(context: BrowserContext) {
this._contexts.delete(context);
await this._instrumentation.onWillCloseBrowserContext(context);
await this._instrumentation.runBeforeCloseBrowserContext(context);
}
}

View File

@ -24,21 +24,23 @@ export interface ClientInstrumentation {
removeAllListeners(): void;
onApiCallBegin(apiCall: string, params: Record<string, any>, frames: StackFrame[], userData: any, out: { stepId?: string }): void;
onApiCallEnd(userData: any, error?: Error): void;
onDidCreateBrowserContext(context: BrowserContext): Promise<void>;
onDidCreateRequestContext(context: APIRequestContext): Promise<void>;
onWillPause(): void;
onWillCloseBrowserContext(context: BrowserContext): Promise<void>;
onWillCloseRequestContext(context: APIRequestContext): Promise<void>;
runAfterCreateBrowserContext(context: BrowserContext): Promise<void>;
runAfterCreateRequestContext(context: APIRequestContext): Promise<void>;
runBeforeCloseBrowserContext(context: BrowserContext): Promise<void>;
runBeforeCloseRequestContext(context: APIRequestContext): Promise<void>;
}
export interface ClientInstrumentationListener {
onApiCallBegin?(apiName: string, params: Record<string, any>, frames: StackFrame[], userData: any, out: { stepId?: string }): void;
onApiCallEnd?(userData: any, error?: Error): void;
onDidCreateBrowserContext?(context: BrowserContext): Promise<void>;
onDidCreateRequestContext?(context: APIRequestContext): Promise<void>;
onWillPause?(): void;
onWillCloseBrowserContext?(context: BrowserContext): Promise<void>;
onWillCloseRequestContext?(context: APIRequestContext): Promise<void>;
runAfterCreateBrowserContext?(context: BrowserContext): Promise<void>;
runAfterCreateRequestContext?(context: APIRequestContext): Promise<void>;
runBeforeCloseBrowserContext?(context: BrowserContext): Promise<void>;
runBeforeCloseRequestContext?(context: APIRequestContext): Promise<void>;
}
export function createInstrumentation(): ClientInstrumentation {
@ -53,12 +55,19 @@ export function createInstrumentation(): ClientInstrumentation {
return (listener: ClientInstrumentationListener) => listeners.splice(listeners.indexOf(listener), 1);
if (prop === 'removeAllListeners')
return () => listeners.splice(0, listeners.length);
if (!prop.startsWith('on'))
return obj[prop];
return async (...params: any[]) => {
for (const listener of listeners)
await (listener as any)[prop]?.(...params);
};
if (prop.startsWith('run')) {
return async (...params: any[]) => {
for (const listener of listeners)
await (listener as any)[prop]?.(...params);
};
}
if (prop.startsWith('on')) {
return (...params: any[]) => {
for (const listener of listeners)
(listener as any)[prop]?.(...params);
};
}
return obj[prop];
},
});
}

View File

@ -77,7 +77,7 @@ export class APIRequest implements api.APIRequest {
this._contexts.add(context);
context._request = this;
context._tracing._tracesDir = tracesDir;
await context._instrumentation.onDidCreateRequestContext(context);
await context._instrumentation.runAfterCreateRequestContext(context);
return context;
}
}
@ -102,7 +102,7 @@ export class APIRequestContext extends ChannelOwner<channels.APIRequestContextCh
async dispose(options: { reason?: string } = {}): Promise<void> {
this._closeReason = options.reason;
await this._instrumentation.onWillCloseRequestContext(this);
await this._instrumentation.runBeforeCloseRequestContext(this);
try {
await this._channel.dispose(options);
} catch (e) {

View File

@ -268,19 +268,19 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
onWillPause: () => {
currentTestInfo()?.setTimeout(0);
},
onDidCreateBrowserContext: async (context: BrowserContext) => {
runAfterCreateBrowserContext: async (context: BrowserContext) => {
await artifactsRecorder?.didCreateBrowserContext(context);
const testInfo = currentTestInfo();
if (testInfo)
attachConnectedHeaderIfNeeded(testInfo, context.browser());
},
onDidCreateRequestContext: async (context: APIRequestContext) => {
runAfterCreateRequestContext: async (context: APIRequestContext) => {
await artifactsRecorder?.didCreateRequestContext(context);
},
onWillCloseBrowserContext: async (context: BrowserContext) => {
runBeforeCloseBrowserContext: async (context: BrowserContext) => {
await artifactsRecorder?.willCloseBrowserContext(context);
},
onWillCloseRequestContext: async (context: APIRequestContext) => {
runBeforeCloseRequestContext: async (context: APIRequestContext) => {
await artifactsRecorder?.willCloseRequestContext(context);
},
};

View File

@ -68,7 +68,7 @@ test.beforeAll(async function recordTrace({ browser, browserName, browserType, s
// Go through instrumentation to exercise reentrant stack traces.
const csi = {
onWillCloseBrowserContext: async () => {
runBeforeCloseBrowserContext: async () => {
await page.hover('body');
await page.close();
traceFile = path.join(workerInfo.project.outputDir, String(workerInfo.workerIndex), browserName, 'trace.zip');