Skip to content

Commit cb6ab4f

Browse files
authored
chore: type server-side events (1) (microsoft#38549)
1 parent 84fa54f commit cb6ab4f

15 files changed

Lines changed: 743 additions & 139 deletions

File tree

packages/playwright-core/src/server/browserContext.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { mkdirIfNeeded } from './utils/fileUtils';
2828
import { rewriteErrorMessage } from '../utils/isomorphic/stackTrace';
2929
import { HarRecorder } from './har/harRecorder';
3030
import { helper } from './helper';
31-
import { SdkObject } from './instrumentation';
31+
import { EventMap, SdkObject } from './instrumentation';
3232
import * as network from './network';
3333
import { InitScript } from './page';
3434
import { Page, PageBinding } from './page';
@@ -39,6 +39,7 @@ import * as rawStorageSource from '../generated/storageScriptSource';
3939

4040
import type { Artifact } from './artifact';
4141
import type { Browser, BrowserOptions } from './browser';
42+
import type { ConsoleMessage } from './console';
4243
import type { Download } from './download';
4344
import type * as frames from './frames';
4445
import type { Progress } from './progress';
@@ -47,25 +48,44 @@ import type { SerializedStorage } from '@injected/storageScript';
4748
import type * as types from './types';
4849
import type * as channels from '@protocol/channels';
4950

50-
export abstract class BrowserContext extends SdkObject {
51-
static Events = {
52-
Console: 'console',
53-
Close: 'close',
54-
Page: 'page',
55-
// Can't use just 'error' due to node.js special treatment of error events.
56-
// @see https://nodejs.org/api/events.html#events_error_events
57-
PageError: 'pageerror',
58-
Request: 'request',
59-
Response: 'response',
60-
RequestFailed: 'requestfailed',
61-
RequestFinished: 'requestfinished',
62-
RequestAborted: 'requestaborted',
63-
RequestFulfilled: 'requestfulfilled',
64-
RequestContinued: 'requestcontinued',
65-
BeforeClose: 'beforeclose',
66-
VideoStarted: 'videostarted',
67-
RecorderEvent: 'recorderevent',
68-
};
51+
const BrowserContextEvent = {
52+
Console: 'console',
53+
Close: 'close',
54+
Page: 'page',
55+
// Can't use just 'error' due to node.js special treatment of error events.
56+
// @see https://nodejs.org/api/events.html#events_error_events
57+
PageError: 'pageerror',
58+
Request: 'request',
59+
Response: 'response',
60+
RequestFailed: 'requestfailed',
61+
RequestFinished: 'requestfinished',
62+
RequestAborted: 'requestaborted',
63+
RequestFulfilled: 'requestfulfilled',
64+
RequestContinued: 'requestcontinued',
65+
BeforeClose: 'beforeclose',
66+
VideoStarted: 'videostarted',
67+
RecorderEvent: 'recorderevent',
68+
} as const;
69+
70+
export type BrowserContextEventMap = {
71+
[BrowserContextEvent.Console]: [message: ConsoleMessage];
72+
[BrowserContextEvent.Close]: [];
73+
[BrowserContextEvent.Page]: [page: Page];
74+
[BrowserContextEvent.PageError]: [error: Error, page: Page];
75+
[BrowserContextEvent.Request]: [request: network.Request];
76+
[BrowserContextEvent.Response]: [response: network.Response];
77+
[BrowserContextEvent.RequestFailed]: [request: network.Request];
78+
[BrowserContextEvent.RequestFinished]: [requestAndResponse: { request: network.Request, response: network.Response | null }];
79+
[BrowserContextEvent.RequestAborted]: [request: network.Request];
80+
[BrowserContextEvent.RequestFulfilled]: [request: network.Request];
81+
[BrowserContextEvent.RequestContinued]: [request: network.Request];
82+
[BrowserContextEvent.BeforeClose]: [];
83+
[BrowserContextEvent.VideoStarted]: [artifact: Artifact];
84+
[BrowserContextEvent.RecorderEvent]: [event: { event: 'actionAdded' | 'actionUpdated' | 'signalAdded', data: any, page: Page, code: string }];
85+
};
86+
87+
export abstract class BrowserContext<EM extends EventMap = EventMap> extends SdkObject<BrowserContextEventMap | EM> {
88+
static Events = BrowserContextEvent;
6989

7090
readonly _pageBindings = new Map<string, PageBinding>();
7191
readonly _options: types.BrowserContextOptions;

packages/playwright-core/src/server/chromium/crBrowser.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,16 @@ export class CRBrowser extends Browser {
327327
}
328328
}
329329

330-
export class CRBrowserContext extends BrowserContext {
331-
static CREvents = {
332-
ServiceWorker: 'serviceworker',
333-
};
330+
const CREvents = {
331+
ServiceWorker: 'serviceworker',
332+
} as const;
333+
334+
export type CREventsMap = {
335+
[CREvents.ServiceWorker]: [serviceWorker: CRServiceWorker];
336+
};
337+
338+
export class CRBrowserContext extends BrowserContext<CREventsMap> {
339+
static CREvents = CREvents;
334340

335341
declare readonly _browser: CRBrowser;
336342

packages/playwright-core/src/server/chromium/crConnection.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ export const ConnectionEvents = {
3232
Disconnected: Symbol('ConnectionEvents.Disconnected')
3333
};
3434

35+
export type ConnectionEventMap = {
36+
[ConnectionEvents.Disconnected]: [];
37+
};
38+
3539
// CRPlaywright uses this special id to issue Browser.close command which we
3640
// should ignore.
3741
export const kBrowserCloseMessageId = -9999;
@@ -100,19 +104,14 @@ export class CRConnection extends SdkObject {
100104

101105
type SessionEventListener = (method: string, params?: Object) => void;
102106

103-
export class CRSession extends SdkObject {
107+
export class CRSession extends SdkObject<Protocol.EventMap & ConnectionEventMap> {
104108
private readonly _connection: CRConnection;
105109
private _eventListener?: SessionEventListener;
106110
private readonly _callbacks = new Map<number, { resolve: (o: any) => void, reject: (e: ProtocolError) => void, error: ProtocolError }>();
107111
private readonly _sessionId: string;
108112
private readonly _parentSession: CRSession | null;
109113
private _crashed: boolean = false;
110114
private _closed = false;
111-
override on: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
112-
override addListener: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
113-
override off: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
114-
override removeListener: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
115-
override once: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
116115

117116
constructor(connection: CRConnection, parentSession: CRSession | null, sessionId: string, eventListener?: SessionEventListener) {
118117
super(connection, 'cr-session');
@@ -121,12 +120,6 @@ export class CRSession extends SdkObject {
121120
this._parentSession = parentSession;
122121
this._sessionId = sessionId;
123122
this._eventListener = eventListener;
124-
125-
this.on = super.on;
126-
this.addListener = super.addListener;
127-
this.off = super.removeListener;
128-
this.removeListener = super.removeListener;
129-
this.once = super.once;
130123
}
131124

132125
_markAsCrashed() {
@@ -172,7 +165,7 @@ export class CRSession extends SdkObject {
172165
Promise.resolve().then(() => {
173166
if (this._eventListener)
174167
this._eventListener(object.method!, object.params);
175-
this.emit(object.method!, object.params);
168+
(this.emit as any)(object.method as any, object.params);
176169
});
177170
}
178171
}

packages/playwright-core/src/server/chromium/crPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ class FrameSession {
882882
const buffer = Buffer.from(payload.data, 'base64');
883883
this._page.emit(Page.Events.ScreencastFrame, {
884884
buffer,
885-
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1000 : undefined,
885+
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1000 : Date.now(),
886886
width: payload.metadata.deviceWidth,
887887
height: payload.metadata.deviceHeight,
888888
});

0 commit comments

Comments
 (0)