mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
120 lines
4.5 KiB
TypeScript
120 lines
4.5 KiB
TypeScript
/**
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { EventEmitter } from 'events';
|
|
import { createGuid } from '../utils';
|
|
import type { APIRequestContext } from './fetch';
|
|
import type { Browser } from './browser';
|
|
import type { BrowserContext } from './browserContext';
|
|
import type { BrowserType } from './browserType';
|
|
import type { ElementHandle } from './dom';
|
|
import type { Frame } from './frames';
|
|
import type { Page } from './page';
|
|
import type { Playwright } from './playwright';
|
|
|
|
export type Attribution = {
|
|
playwright: Playwright;
|
|
browserType?: BrowserType;
|
|
browser?: Browser;
|
|
context?: BrowserContext | APIRequestContext;
|
|
page?: Page;
|
|
frame?: Frame;
|
|
};
|
|
|
|
import type { CallMetadata } from '@protocol/callMetadata';
|
|
export type { CallMetadata } from '@protocol/callMetadata';
|
|
import type * as trace from '@trace/trace';
|
|
|
|
export const kTestSdkObjects = new WeakSet<SdkObject>();
|
|
|
|
export class SdkObject extends EventEmitter {
|
|
guid: string;
|
|
attribution: Attribution;
|
|
instrumentation: Instrumentation;
|
|
|
|
constructor(parent: SdkObject, guidPrefix?: string, guid?: string) {
|
|
super();
|
|
this.guid = guid || `${guidPrefix || ''}@${createGuid()}`;
|
|
this.setMaxListeners(0);
|
|
this.attribution = { ...parent.attribution };
|
|
this.instrumentation = parent.instrumentation;
|
|
if (process.env._PW_INTERNAL_COUNT_SDK_OBJECTS)
|
|
kTestSdkObjects.add(this);
|
|
}
|
|
}
|
|
|
|
export interface Instrumentation {
|
|
addListener(listener: InstrumentationListener, context: BrowserContext | APIRequestContext | null): void;
|
|
removeListener(listener: InstrumentationListener): void;
|
|
onBeforeCall(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
|
onBeforeInputAction(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle): Promise<void>;
|
|
onCallLog(sdkObject: SdkObject, metadata: CallMetadata, logName: string, message: string): void;
|
|
onAfterCall(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
|
onEvent(sdkObject: SdkObject, event: trace.EventTraceEvent): void;
|
|
onPageOpen(page: Page): void;
|
|
onPageClose(page: Page): void;
|
|
onBrowserOpen(browser: Browser): void;
|
|
onBrowserClose(browser: Browser): void;
|
|
}
|
|
|
|
export interface InstrumentationListener {
|
|
onBeforeCall?(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
|
onBeforeInputAction?(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle): Promise<void>;
|
|
onCallLog?(sdkObject: SdkObject, metadata: CallMetadata, logName: string, message: string): void;
|
|
onAfterCall?(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
|
onEvent?(sdkObject: SdkObject, event: trace.EventTraceEvent): void;
|
|
onPageOpen?(page: Page): void;
|
|
onPageClose?(page: Page): void;
|
|
onBrowserOpen?(browser: Browser): void;
|
|
onBrowserClose?(browser: Browser): void;
|
|
}
|
|
|
|
export function createInstrumentation(): Instrumentation {
|
|
const listeners = new Map<InstrumentationListener, BrowserContext | APIRequestContext | null>();
|
|
return new Proxy({}, {
|
|
get: (obj: any, prop: string | symbol) => {
|
|
if (typeof prop !== 'string')
|
|
return obj[prop];
|
|
if (prop === 'addListener')
|
|
return (listener: InstrumentationListener, context: BrowserContext | APIRequestContext | null) => listeners.set(listener, context);
|
|
if (prop === 'removeListener')
|
|
return (listener: InstrumentationListener) => listeners.delete(listener);
|
|
if (!prop.startsWith('on'))
|
|
return obj[prop];
|
|
return async (sdkObject: SdkObject, ...params: any[]) => {
|
|
for (const [listener, context] of listeners) {
|
|
if (!context || sdkObject.attribution.context === context)
|
|
await (listener as any)[prop]?.(sdkObject, ...params);
|
|
}
|
|
};
|
|
},
|
|
});
|
|
}
|
|
|
|
export function serverSideCallMetadata(): CallMetadata {
|
|
return {
|
|
id: '',
|
|
startTime: 0,
|
|
endTime: 0,
|
|
wallTime: Date.now(),
|
|
type: 'Internal',
|
|
method: '',
|
|
params: {},
|
|
log: [],
|
|
isServerSide: true,
|
|
};
|
|
}
|