chore: init eventEmitter w/ platform (#34809)

This commit is contained in:
Pavel Feldman 2025-02-14 17:06:11 -08:00 committed by GitHub
parent 145b6bf4fe
commit 024a52821a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 48 additions and 51 deletions

View File

@ -393,7 +393,7 @@ export class AndroidWebView extends EventEmitter implements api.AndroidWebView {
private _pagePromise: Promise<Page> | undefined; private _pagePromise: Promise<Page> | undefined;
constructor(device: AndroidDevice, data: channels.AndroidWebView) { constructor(device: AndroidDevice, data: channels.AndroidWebView) {
super(); super(device._platform);
this._device = device; this._device = device;
this._data = data; this._data = data;
} }

View File

@ -38,21 +38,20 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
readonly _channel: T; readonly _channel: T;
readonly _initializer: channels.InitializerTraits<T>; readonly _initializer: channels.InitializerTraits<T>;
_logger: Logger | undefined; _logger: Logger | undefined;
readonly _platform: Platform;
readonly _instrumentation: ClientInstrumentation; readonly _instrumentation: ClientInstrumentation;
private _eventToSubscriptionMapping: Map<string, string> = new Map(); private _eventToSubscriptionMapping: Map<string, string> = new Map();
private _isInternalType = false; private _isInternalType = false;
_wasCollected: boolean = false; _wasCollected: boolean = false;
constructor(parent: ChannelOwner | Connection, type: string, guid: string, initializer: channels.InitializerTraits<T>) { constructor(parent: ChannelOwner | Connection, type: string, guid: string, initializer: channels.InitializerTraits<T>) {
super(); const connection = parent instanceof ChannelOwner ? parent._connection : parent;
super(connection._platform);
this.setMaxListeners(0); this.setMaxListeners(0);
this._connection = parent instanceof ChannelOwner ? parent._connection : parent; this._connection = connection;
this._type = type; this._type = type;
this._guid = guid; this._guid = guid;
this._parent = parent instanceof ChannelOwner ? parent : undefined; this._parent = parent instanceof ChannelOwner ? parent : undefined;
this._instrumentation = this._connection._instrumentation; this._instrumentation = this._connection._instrumentation;
this._platform = this._connection.platform;
this._connection._objects.set(guid, this); this._connection._objects.set(guid, this);
if (this._parent) { if (this._parent) {
@ -60,7 +59,7 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
this._logger = this._parent._logger; this._logger = this._parent._logger;
} }
this._channel = this._createChannel(new EventEmitter()); this._channel = this._createChannel(new EventEmitter(connection._platform));
this._initializer = initializer; this._initializer = initializer;
} }

View File

@ -16,14 +16,12 @@
import { Connection } from './connection'; import { Connection } from './connection';
import { setPlatformForSelectors } from './selectors'; import { setPlatformForSelectors } from './selectors';
import { setPlatformForEventEmitter } from './eventEmitter';
import { setIsUnderTestForValidator } from '../protocol/validatorPrimitives'; import { setIsUnderTestForValidator } from '../protocol/validatorPrimitives';
import type { Platform } from './platform'; import type { Platform } from './platform';
export function createConnectionFactory(platform: Platform): () => Connection { export function createConnectionFactory(platform: Platform): () => Connection {
setPlatformForSelectors(platform); setPlatformForSelectors(platform);
setPlatformForEventEmitter(platform);
setIsUnderTestForValidator(() => platform.isUnderTest()); setIsUnderTestForValidator(() => platform.isUnderTest());
return () => new Connection(platform); return () => new Connection(platform);
} }

View File

@ -78,15 +78,13 @@ export class Connection extends EventEmitter {
toImpl: ((client: ChannelOwner) => any) | undefined; toImpl: ((client: ChannelOwner) => any) | undefined;
private _tracingCount = 0; private _tracingCount = 0;
readonly _instrumentation: ClientInstrumentation; readonly _instrumentation: ClientInstrumentation;
readonly platform: Platform;
// Used from @playwright/test fixtures -> TODO remove? // Used from @playwright/test fixtures -> TODO remove?
readonly headers: HeadersArray; readonly headers: HeadersArray;
constructor(platform: Platform, localUtils?: LocalUtils, instrumentation?: ClientInstrumentation, headers: HeadersArray = []) { constructor(platform: Platform, localUtils?: LocalUtils, instrumentation?: ClientInstrumentation, headers: HeadersArray = []) {
super(); super(platform);
this._instrumentation = instrumentation || createInstrumentation(); this._instrumentation = instrumentation || createInstrumentation();
this._localUtils = localUtils; this._localUtils = localUtils;
this.platform = platform;
this._rootObject = new Root(this); this._rootObject = new Root(this);
this.headers = headers; this.headers = headers;
} }
@ -136,9 +134,9 @@ export class Connection extends EventEmitter {
const type = object._type; const type = object._type;
const id = ++this._lastId; const id = ++this._lastId;
const message = { id, guid, method, params }; const message = { id, guid, method, params };
if (this.platform.isLogEnabled('channel')) { if (this._platform.isLogEnabled('channel')) {
// Do not include metadata in debug logs to avoid noise. // Do not include metadata in debug logs to avoid noise.
this.platform.log('channel', 'SEND> ' + JSON.stringify(message)); this._platform.log('channel', 'SEND> ' + JSON.stringify(message));
} }
const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined; const location = frames[0] ? { file: frames[0].file, line: frames[0].line, column: frames[0].column } : undefined;
const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId }; const metadata: channels.Metadata = { apiName, location, internal: !apiName, stepId };
@ -146,7 +144,7 @@ export class Connection extends EventEmitter {
this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {}); this._localUtils?.addStackToTracingNoReply({ callData: { stack: frames, id } }).catch(() => {});
// We need to exit zones before calling into the server, otherwise // We need to exit zones before calling into the server, otherwise
// when we receive events from the server, we would be in an API zone. // when we receive events from the server, we would be in an API zone.
this.platform.zones.empty.run(() => this.onmessage({ ...message, metadata })); this._platform.zones.empty.run(() => this.onmessage({ ...message, metadata }));
return await new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject, apiName, type, method })); return await new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject, apiName, type, method }));
} }
@ -156,15 +154,15 @@ export class Connection extends EventEmitter {
const { id, guid, method, params, result, error, log } = message as any; const { id, guid, method, params, result, error, log } = message as any;
if (id) { if (id) {
if (this.platform.isLogEnabled('channel')) if (this._platform.isLogEnabled('channel'))
this.platform.log('channel', '<RECV ' + JSON.stringify(message)); this._platform.log('channel', '<RECV ' + JSON.stringify(message));
const callback = this._callbacks.get(id); const callback = this._callbacks.get(id);
if (!callback) if (!callback)
throw new Error(`Cannot find command to respond: ${id}`); throw new Error(`Cannot find command to respond: ${id}`);
this._callbacks.delete(id); this._callbacks.delete(id);
if (error && !result) { if (error && !result) {
const parsedError = parseError(error); const parsedError = parseError(error);
rewriteErrorMessage(parsedError, parsedError.message + formatCallLog(this.platform, log)); rewriteErrorMessage(parsedError, parsedError.message + formatCallLog(this._platform, log));
callback.reject(parsedError); callback.reject(parsedError);
} else { } else {
const validator = findValidator(callback.type, callback.method, 'Result'); const validator = findValidator(callback.type, callback.method, 'Result');
@ -173,8 +171,8 @@ export class Connection extends EventEmitter {
return; return;
} }
if (this.platform.isLogEnabled('channel')) if (this._platform.isLogEnabled('channel'))
this.platform.log('channel', '<EVENT ' + JSON.stringify(message)); this._platform.log('channel', '<EVENT ' + JSON.stringify(message));
if (method === '__create__') { if (method === '__create__') {
this._createRemoteObject(guid, params.type, params.guid, params.initializer); this._createRemoteObject(guid, params.type, params.guid, params.initializer);
return; return;

View File

@ -22,8 +22,6 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. * USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { emptyPlatform } from './platform';
import type { EventEmitter as EventEmitterType } from 'events'; import type { EventEmitter as EventEmitterType } from 'events';
import type { Platform } from './platform'; import type { Platform } from './platform';
@ -31,12 +29,6 @@ type EventType = string | symbol;
type Listener = (...args: any[]) => any; type Listener = (...args: any[]) => any;
type EventMap = Record<EventType, Listener | Listener[]>; type EventMap = Record<EventType, Listener | Listener[]>;
let platform = emptyPlatform;
export function setPlatformForEventEmitter(p: Platform) {
platform = p;
}
export class EventEmitter implements EventEmitterType { export class EventEmitter implements EventEmitterType {
private _events: EventMap | undefined = undefined; private _events: EventMap | undefined = undefined;
@ -44,8 +36,10 @@ export class EventEmitter implements EventEmitterType {
private _maxListeners: number | undefined = undefined; private _maxListeners: number | undefined = undefined;
readonly _pendingHandlers = new Map<EventType, Set<Promise<void>>>(); readonly _pendingHandlers = new Map<EventType, Set<Promise<void>>>();
private _rejectionHandler: ((error: Error) => void) | undefined; private _rejectionHandler: ((error: Error) => void) | undefined;
readonly _platform: Platform;
constructor() { constructor(platform: Platform) {
this._platform = platform;
if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null); this._events = Object.create(null);
this._eventsCount = 0; this._eventsCount = 0;
@ -63,7 +57,7 @@ export class EventEmitter implements EventEmitterType {
} }
getMaxListeners(): number { getMaxListeners(): number {
return this._maxListeners === undefined ? platform.defaultMaxListeners() : this._maxListeners; return this._maxListeners === undefined ? this._platform.defaultMaxListeners() : this._maxListeners;
} }
emit(type: EventType, ...args: any[]): boolean { emit(type: EventType, ...args: any[]): boolean {
@ -161,7 +155,7 @@ export class EventEmitter implements EventEmitterType {
w.emitter = this; w.emitter = this;
w.type = type; w.type = type;
w.count = existing.length; w.count = existing.length;
if (!platform.isUnderTest()) { if (!this._platform.isUnderTest()) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn(w); console.warn(w);
} }

View File

@ -64,7 +64,7 @@ export class Frame extends ChannelOwner<channels.FrameChannel> implements api.Fr
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.FrameInitializer) { constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.FrameInitializer) {
super(parent, type, guid, initializer); super(parent, type, guid, initializer);
this._eventEmitter = new EventEmitter(); this._eventEmitter = new EventEmitter(parent._platform);
this._eventEmitter.setMaxListeners(0); this._eventEmitter.setMaxListeners(0);
this._parentFrame = Frame.fromNullable(initializer.parentFrame); this._parentFrame = Frame.fromNullable(initializer.parentFrame);
if (this._parentFrame) if (this._parentFrame)

View File

@ -24,7 +24,7 @@ export async function connectOverWebSocket(parentConnection: Connection, params:
const localUtils = parentConnection.localUtils(); const localUtils = parentConnection.localUtils();
const transport = localUtils ? new JsonPipeTransport(localUtils) : new WebSocketTransport(); const transport = localUtils ? new JsonPipeTransport(localUtils) : new WebSocketTransport();
const connectHeaders = await transport.connect(params); const connectHeaders = await transport.connect(params);
const connection = new Connection(parentConnection.platform, localUtils, parentConnection._instrumentation, connectHeaders); const connection = new Connection(parentConnection._platform, localUtils, parentConnection._instrumentation, connectHeaders);
connection.markAsRemote(); connection.markAsRemote();
connection.on('close', () => transport.close()); connection.on('close', () => transport.close());

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test.describe('EventEmitter tests', () => { test.describe('EventEmitter tests', () => {

View File

@ -21,7 +21,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import events from 'events'; import events from 'events';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { setUnderTest } from '../../../packages/playwright-core/lib/server/utils/debug'; import { setUnderTest } from '../../../packages/playwright-core/lib/server/utils/debug';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import * as common from './utils'; import * as common from './utils';

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test.describe('EventEmitter', () => { test.describe('EventEmitter', () => {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('Listener count test', () => { test('Listener count test', () => {

View File

@ -21,7 +21,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
test('listeners empty check', () => { test('listeners empty check', () => {
const e = new EventEmitter(); const e = new EventEmitter();

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
const listener = () => {}; const listener = () => {};

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH the SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH the SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('emit maxListeners on e', () => { test('emit maxListeners on e', () => {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('EventEmitter prototype test', () => { test('EventEmitter prototype test', () => {

View File

@ -21,7 +21,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
let callbacks_called = []; let callbacks_called = [];
const e = new EventEmitter(); const e = new EventEmitter();

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('should work', () => { test('should work', () => {

View File

@ -21,7 +21,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import * as common from './utils'; import * as common from './utils';
test('should work', () => { test('should work', () => {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('EventEmitter functionality', () => { test('EventEmitter functionality', () => {

View File

@ -16,7 +16,7 @@
*/ */
import { ManualPromise } from '../../../packages/playwright-core/lib/utils/isomorphic/manualPromise'; import { ManualPromise } from '../../../packages/playwright-core/lib/utils/isomorphic/manualPromise';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('should not throw with ignoreErrors', async () => { test('should not throw with ignoreErrors', async () => {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import * as common from './utils'; import * as common from './utils';

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import * as common from './utils'; import * as common from './utils';

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('set max listeners test', () => { test('set max listeners test', () => {

View File

@ -21,7 +21,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
test('should support special event names', () => { test('should support special event names', () => {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
class MyEE extends EventEmitter { class MyEE extends EventEmitter {

View File

@ -20,7 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { EventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter'; import { EventEmitter } from './utils';
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('should support symbols', () => { test('should support symbols', () => {

View File

@ -20,6 +20,8 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { EventEmitter as OriginalEventEmitter } from '../../../packages/playwright-core/lib/client/eventEmitter';
import { nodePlatform } from '../../../packages/playwright-core/lib/server/utils/nodePlatform';
export const mustNotCall = (msg?: string) => { export const mustNotCall = (msg?: string) => {
return function mustNotCall() { return function mustNotCall() {
@ -44,3 +46,9 @@ export const mustCall = (fn?: Function, exact?: number) => {
--count; --count;
}; };
}; };
export class EventEmitter extends OriginalEventEmitter {
constructor() {
super(nodePlatform);
}
}