2021-02-09 14:44:48 -08:00
|
|
|
/**
|
|
|
|
* 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';
|
2021-02-12 10:11:30 -08:00
|
|
|
import { Point, StackFrame } from '../common/types';
|
2021-07-02 14:33:38 -07:00
|
|
|
import { SerializedError } from '../protocol/channels';
|
2021-04-20 23:03:56 -07:00
|
|
|
import { createGuid } from '../utils/utils';
|
2021-02-09 14:44:48 -08:00
|
|
|
import type { Browser } from './browser';
|
|
|
|
import type { BrowserContext } from './browserContext';
|
|
|
|
import type { BrowserType } from './browserType';
|
2021-03-10 11:43:26 -08:00
|
|
|
import { ElementHandle } from './dom';
|
2021-02-09 14:44:48 -08:00
|
|
|
import type { Frame } from './frames';
|
|
|
|
import type { Page } from './page';
|
|
|
|
|
|
|
|
export type Attribution = {
|
2021-04-23 18:34:52 -07:00
|
|
|
isInternal: boolean,
|
2021-02-09 14:44:48 -08:00
|
|
|
browserType?: BrowserType;
|
|
|
|
browser?: Browser;
|
|
|
|
context?: BrowserContext;
|
|
|
|
page?: Page;
|
|
|
|
frame?: Frame;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type CallMetadata = {
|
2021-04-23 09:28:18 -07:00
|
|
|
id: string;
|
2021-02-10 21:50:29 -08:00
|
|
|
startTime: number;
|
|
|
|
endTime: number;
|
2021-02-17 22:10:13 -08:00
|
|
|
pauseStartTime?: number;
|
|
|
|
pauseEndTime?: number;
|
2021-02-09 14:44:48 -08:00
|
|
|
type: string;
|
|
|
|
method: string;
|
|
|
|
params: any;
|
2021-02-19 18:12:33 -08:00
|
|
|
apiName?: string;
|
2021-02-10 18:52:28 -08:00
|
|
|
stack?: StackFrame[];
|
2021-02-10 21:50:29 -08:00
|
|
|
log: string[];
|
2021-04-23 09:28:18 -07:00
|
|
|
snapshots: { title: string, snapshotName: string }[];
|
2021-07-02 14:33:38 -07:00
|
|
|
error?: SerializedError;
|
|
|
|
result?: any;
|
2021-02-12 10:11:30 -08:00
|
|
|
point?: Point;
|
2021-04-23 09:28:18 -07:00
|
|
|
objectId?: string;
|
2021-03-01 12:20:04 -08:00
|
|
|
pageId?: string;
|
|
|
|
frameId?: string;
|
2021-02-09 14:44:48 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
export class SdkObject extends EventEmitter {
|
2021-04-20 23:03:56 -07:00
|
|
|
guid: string;
|
2021-02-09 14:44:48 -08:00
|
|
|
attribution: Attribution;
|
|
|
|
instrumentation: Instrumentation;
|
|
|
|
|
2021-04-20 23:03:56 -07:00
|
|
|
protected constructor(parent: SdkObject, guidPrefix?: string, guid?: string) {
|
2021-02-09 14:44:48 -08:00
|
|
|
super();
|
2021-04-20 23:03:56 -07:00
|
|
|
this.guid = guid || `${guidPrefix || ''}@${createGuid()}`;
|
2021-02-09 14:44:48 -08:00
|
|
|
this.setMaxListeners(0);
|
|
|
|
this.attribution = { ...parent.attribution };
|
|
|
|
this.instrumentation = parent.instrumentation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface Instrumentation {
|
2021-04-23 18:34:52 -07:00
|
|
|
addListener(listener: InstrumentationListener): void;
|
2021-04-23 20:39:09 -07:00
|
|
|
removeListener(listener: InstrumentationListener): void;
|
2021-02-10 21:55:46 -08:00
|
|
|
onBeforeCall(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
2021-03-10 11:43:26 -08:00
|
|
|
onBeforeInputAction(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle): Promise<void>;
|
2021-02-10 21:55:46 -08:00
|
|
|
onCallLog(logName: string, message: string, sdkObject: SdkObject, metadata: CallMetadata): void;
|
|
|
|
onAfterCall(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
2021-04-23 09:28:18 -07:00
|
|
|
onEvent(sdkObject: SdkObject, metadata: CallMetadata): void;
|
2021-02-09 14:44:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface InstrumentationListener {
|
2021-02-10 21:55:46 -08:00
|
|
|
onBeforeCall?(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
2021-03-10 11:43:26 -08:00
|
|
|
onBeforeInputAction?(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle): Promise<void>;
|
2021-02-10 21:55:46 -08:00
|
|
|
onCallLog?(logName: string, message: string, sdkObject: SdkObject, metadata: CallMetadata): void;
|
|
|
|
onAfterCall?(sdkObject: SdkObject, metadata: CallMetadata): Promise<void>;
|
2021-04-23 09:28:18 -07:00
|
|
|
onEvent?(sdkObject: SdkObject, metadata: CallMetadata): void;
|
2021-02-09 14:44:48 -08:00
|
|
|
}
|
|
|
|
|
2021-04-23 18:34:52 -07:00
|
|
|
export function createInstrumentation(): Instrumentation {
|
|
|
|
const listeners: InstrumentationListener[] = [];
|
2021-02-10 21:44:22 -08:00
|
|
|
return new Proxy({}, {
|
|
|
|
get: (obj: any, prop: string) => {
|
2021-04-23 18:34:52 -07:00
|
|
|
if (prop === 'addListener')
|
|
|
|
return (listener: InstrumentationListener) => listeners.push(listener);
|
2021-04-23 20:39:09 -07:00
|
|
|
if (prop === 'removeListener')
|
|
|
|
return (listener: InstrumentationListener) => listeners.splice(listeners.indexOf(listener), 1);
|
2021-02-10 21:44:22 -08:00
|
|
|
if (!prop.startsWith('on'))
|
|
|
|
return obj[prop];
|
|
|
|
return async (...params: any[]) => {
|
|
|
|
for (const listener of listeners)
|
|
|
|
await (listener as any)[prop]?.(...params);
|
|
|
|
};
|
|
|
|
},
|
|
|
|
});
|
2021-02-09 14:44:48 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
export function internalCallMetadata(): CallMetadata {
|
|
|
|
return {
|
2021-04-23 09:28:18 -07:00
|
|
|
id: '',
|
2021-02-10 21:50:29 -08:00
|
|
|
startTime: 0,
|
|
|
|
endTime: 0,
|
2021-02-09 14:44:48 -08:00
|
|
|
type: 'Internal',
|
|
|
|
method: '',
|
|
|
|
params: {},
|
2021-02-10 21:50:29 -08:00
|
|
|
log: [],
|
2021-04-23 09:28:18 -07:00
|
|
|
snapshots: []
|
2021-02-09 14:44:48 -08:00
|
|
|
};
|
|
|
|
}
|