Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 40 additions & 20 deletions packages/playwright-core/src/server/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { mkdirIfNeeded } from './utils/fileUtils';
import { rewriteErrorMessage } from '../utils/isomorphic/stackTrace';
import { HarRecorder } from './har/harRecorder';
import { helper } from './helper';
import { SdkObject } from './instrumentation';
import { EventMap, SdkObject } from './instrumentation';
import * as network from './network';
import { InitScript } from './page';
import { Page, PageBinding } from './page';
Expand All @@ -39,6 +39,7 @@ import * as rawStorageSource from '../generated/storageScriptSource';

import type { Artifact } from './artifact';
import type { Browser, BrowserOptions } from './browser';
import type { ConsoleMessage } from './console';
import type { Download } from './download';
import type * as frames from './frames';
import type { Progress } from './progress';
Expand All @@ -47,25 +48,44 @@ import type { SerializedStorage } from '@injected/storageScript';
import type * as types from './types';
import type * as channels from '@protocol/channels';

export abstract class BrowserContext extends SdkObject {
static Events = {
Console: 'console',
Close: 'close',
Page: 'page',
// Can't use just 'error' due to node.js special treatment of error events.
// @see https://nodejs.org/api/events.html#events_error_events
PageError: 'pageerror',
Request: 'request',
Response: 'response',
RequestFailed: 'requestfailed',
RequestFinished: 'requestfinished',
RequestAborted: 'requestaborted',
RequestFulfilled: 'requestfulfilled',
RequestContinued: 'requestcontinued',
BeforeClose: 'beforeclose',
VideoStarted: 'videostarted',
RecorderEvent: 'recorderevent',
};
const BrowserContextEvent = {
Console: 'console',
Close: 'close',
Page: 'page',
// Can't use just 'error' due to node.js special treatment of error events.
// @see https://nodejs.org/api/events.html#events_error_events
PageError: 'pageerror',
Request: 'request',
Response: 'response',
RequestFailed: 'requestfailed',
RequestFinished: 'requestfinished',
RequestAborted: 'requestaborted',
RequestFulfilled: 'requestfulfilled',
RequestContinued: 'requestcontinued',
BeforeClose: 'beforeclose',
VideoStarted: 'videostarted',
RecorderEvent: 'recorderevent',
} as const;

export type BrowserContextEventMap = {
[BrowserContextEvent.Console]: [message: ConsoleMessage];
[BrowserContextEvent.Close]: [];
[BrowserContextEvent.Page]: [page: Page];
[BrowserContextEvent.PageError]: [error: Error, page: Page];
[BrowserContextEvent.Request]: [request: network.Request];
[BrowserContextEvent.Response]: [response: network.Response];
[BrowserContextEvent.RequestFailed]: [request: network.Request];
[BrowserContextEvent.RequestFinished]: [requestAndResponse: { request: network.Request, response: network.Response | null }];
[BrowserContextEvent.RequestAborted]: [request: network.Request];
[BrowserContextEvent.RequestFulfilled]: [request: network.Request];
[BrowserContextEvent.RequestContinued]: [request: network.Request];
[BrowserContextEvent.BeforeClose]: [];
[BrowserContextEvent.VideoStarted]: [artifact: Artifact];
[BrowserContextEvent.RecorderEvent]: [event: { event: 'actionAdded' | 'actionUpdated' | 'signalAdded', data: any, page: Page, code: string }];
};

export abstract class BrowserContext<EM extends EventMap = EventMap> extends SdkObject<BrowserContextEventMap | EM> {
static Events = BrowserContextEvent;

readonly _pageBindings = new Map<string, PageBinding>();
readonly _options: types.BrowserContextOptions;
Expand Down
14 changes: 10 additions & 4 deletions packages/playwright-core/src/server/chromium/crBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,16 @@ export class CRBrowser extends Browser {
}
}

export class CRBrowserContext extends BrowserContext {
static CREvents = {
ServiceWorker: 'serviceworker',
};
const CREvents = {
ServiceWorker: 'serviceworker',
} as const;

export type CREventsMap = {
[CREvents.ServiceWorker]: [serviceWorker: CRServiceWorker];
};

export class CRBrowserContext extends BrowserContext<CREventsMap> {
static CREvents = CREvents;

declare readonly _browser: CRBrowser;

Expand Down
19 changes: 6 additions & 13 deletions packages/playwright-core/src/server/chromium/crConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export const ConnectionEvents = {
Disconnected: Symbol('ConnectionEvents.Disconnected')
};

export type ConnectionEventMap = {
[ConnectionEvents.Disconnected]: [];
};

// CRPlaywright uses this special id to issue Browser.close command which we
// should ignore.
export const kBrowserCloseMessageId = -9999;
Expand Down Expand Up @@ -100,19 +104,14 @@ export class CRConnection extends SdkObject {

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

export class CRSession extends SdkObject {
export class CRSession extends SdkObject<Protocol.EventMap & ConnectionEventMap> {
private readonly _connection: CRConnection;
private _eventListener?: SessionEventListener;
private readonly _callbacks = new Map<number, { resolve: (o: any) => void, reject: (e: ProtocolError) => void, error: ProtocolError }>();
private readonly _sessionId: string;
private readonly _parentSession: CRSession | null;
private _crashed: boolean = false;
private _closed = false;
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;
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;
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;
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;
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;

constructor(connection: CRConnection, parentSession: CRSession | null, sessionId: string, eventListener?: SessionEventListener) {
super(connection, 'cr-session');
Expand All @@ -121,12 +120,6 @@ export class CRSession extends SdkObject {
this._parentSession = parentSession;
this._sessionId = sessionId;
this._eventListener = eventListener;

this.on = super.on;
this.addListener = super.addListener;
this.off = super.removeListener;
this.removeListener = super.removeListener;
this.once = super.once;
}

_markAsCrashed() {
Expand Down Expand Up @@ -172,7 +165,7 @@ export class CRSession extends SdkObject {
Promise.resolve().then(() => {
if (this._eventListener)
this._eventListener(object.method!, object.params);
this.emit(object.method!, object.params);
(this.emit as any)(object.method as any, object.params);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/chromium/crPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ class FrameSession {
const buffer = Buffer.from(payload.data, 'base64');
this._page.emit(Page.Events.ScreencastFrame, {
buffer,
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1000 : undefined,
frameSwapWallTime: payload.metadata.timestamp ? payload.metadata.timestamp * 1000 : Date.now(),
width: payload.metadata.deviceWidth,
height: payload.metadata.deviceHeight,
});
Expand Down
Loading
Loading