diff --git a/packages/playwright-core/src/server/dispatchers/androidDispatcher.ts b/packages/playwright-core/src/server/dispatchers/androidDispatcher.ts index 597db65c23..5adb4bbf8e 100644 --- a/packages/playwright-core/src/server/dispatchers/androidDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/androidDispatcher.ts @@ -22,16 +22,16 @@ import type * as channels from '../../protocol/channels'; import { BrowserContextDispatcher } from './browserContextDispatcher'; import type { CallMetadata } from '../instrumentation'; -export class AndroidDispatcher extends Dispatcher implements channels.AndroidChannel { +export class AndroidDispatcher extends Dispatcher implements channels.AndroidChannel { _type_Android = true; constructor(scope: RootDispatcher, android: Android) { - super(scope, android, 'Android', {}, true); + super(scope, android, 'Android', {}); } async devices(params: channels.AndroidDevicesParams): Promise { const devices = await this._object.devices(params); return { - devices: devices.map(d => AndroidDeviceDispatcher.from(this._scope, d)) + devices: devices.map(d => AndroidDeviceDispatcher.from(this, d)) }; } @@ -40,7 +40,7 @@ export class AndroidDispatcher extends Dispatcher implements channels.AndroidDeviceChannel { +export class AndroidDeviceDispatcher extends Dispatcher implements channels.AndroidDeviceChannel { _type_EventTarget = true; _type_AndroidDevice = true; @@ -53,7 +53,7 @@ export class AndroidDeviceDispatcher extends Dispatcher this._dispatchEvent('webViewAdded', { webView })); @@ -145,7 +145,7 @@ export class AndroidDeviceDispatcher extends Dispatcher { const socket = await this._object.open(params.command); - return { socket: new AndroidSocketDispatcher(this._scope, socket) }; + return { socket: new AndroidSocketDispatcher(this, socket) }; } async installApk(params: channels.AndroidDeviceInstallApkParams) { @@ -158,7 +158,7 @@ export class AndroidDeviceDispatcher extends Dispatcher { const context = await this._object.launchBrowser(params.pkg, params); - return { context: new BrowserContextDispatcher(this._scope, context) }; + return { context: new BrowserContextDispatcher(this, context) }; } async close(params: channels.AndroidDeviceCloseParams) { @@ -170,15 +170,15 @@ export class AndroidDeviceDispatcher extends Dispatcher { - return { context: new BrowserContextDispatcher(this._scope, await this._object.connectToWebView(params.socketName)) }; + return { context: new BrowserContextDispatcher(this, await this._object.connectToWebView(params.socketName)) }; } } -export class AndroidSocketDispatcher extends Dispatcher implements channels.AndroidSocketChannel { +export class AndroidSocketDispatcher extends Dispatcher implements channels.AndroidSocketChannel { _type_AndroidSocket = true; constructor(scope: AndroidDeviceDispatcher, socket: SocketBackend) { - super(scope, socket, 'AndroidSocket', {}, true); + super(scope, socket, 'AndroidSocket', {}); this.addObjectListener('data', (data: Buffer) => this._dispatchEvent('data', { data })); this.addObjectListener('close', () => { this._dispatchEvent('close'); diff --git a/packages/playwright-core/src/server/dispatchers/artifactDispatcher.ts b/packages/playwright-core/src/server/dispatchers/artifactDispatcher.ts index 96a2a11e21..a4bcff1164 100644 --- a/packages/playwright-core/src/server/dispatchers/artifactDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/artifactDispatcher.ts @@ -62,7 +62,7 @@ export class ArtifactDispatcher extends Dispatcher { diff --git a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts index af6765842b..b8d6d26925 100644 --- a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts @@ -34,7 +34,7 @@ import * as path from 'path'; import { createGuid } from '../../utils'; import { WritableStreamDispatcher } from './writableStreamDispatcher'; -export class BrowserContextDispatcher extends Dispatcher implements channels.BrowserContextChannel { +export class BrowserContextDispatcher extends Dispatcher implements channels.BrowserContextChannel { _type_EventTarget = true; _type_BrowserContext = true; private _context: BrowserContext; @@ -48,7 +48,7 @@ export class BrowserContextDispatcher extends Dispatcher { - this._dispatchEvent('page', { page: PageDispatcher.from(this._scope, page) }); + this._dispatchEvent('page', { page: PageDispatcher.from(this, page) }); }); this.addObjectListener(BrowserContext.Events.Close, () => { this._dispatchEvent('close'); @@ -81,33 +81,33 @@ export class BrowserContextDispatcher extends Dispatcher this._dispatchEvent('backgroundPage', { page: PageDispatcher.from(this._scope, page) })); + this._dispatchEvent('backgroundPage', { page: PageDispatcher.from(this, page) }); + this.addObjectListener(CRBrowserContext.CREvents.BackgroundPage, page => this._dispatchEvent('backgroundPage', { page: PageDispatcher.from(this, page) })); for (const serviceWorker of (context as CRBrowserContext).serviceWorkers()) - this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this._scope, serviceWorker) }); - this.addObjectListener(CRBrowserContext.CREvents.ServiceWorker, serviceWorker => this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this._scope, serviceWorker) })); + this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this, serviceWorker) }); + this.addObjectListener(CRBrowserContext.CREvents.ServiceWorker, serviceWorker => this._dispatchEvent('serviceWorker', { worker: new WorkerDispatcher(this, serviceWorker) })); } this.addObjectListener(BrowserContext.Events.Request, (request: Request) => { return this._dispatchEvent('request', { - request: RequestDispatcher.from(this._scope, request), - page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined()) + request: RequestDispatcher.from(this, request), + page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined()) }); }); this.addObjectListener(BrowserContext.Events.Response, (response: Response) => this._dispatchEvent('response', { - response: ResponseDispatcher.from(this._scope, response), - page: PageDispatcher.fromNullable(this._scope, response.frame()?._page.initializedOrUndefined()) + response: ResponseDispatcher.from(this, response), + page: PageDispatcher.fromNullable(this, response.frame()?._page.initializedOrUndefined()) })); this.addObjectListener(BrowserContext.Events.RequestFailed, (request: Request) => this._dispatchEvent('requestFailed', { - request: RequestDispatcher.from(this._scope, request), + request: RequestDispatcher.from(this, request), failureText: request._failureText || undefined, responseEndTiming: request._responseEndTiming, - page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined()) + page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined()) })); this.addObjectListener(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => this._dispatchEvent('requestFinished', { - request: RequestDispatcher.from(this._scope, request), - response: ResponseDispatcher.fromNullable(this._scope, response), + request: RequestDispatcher.from(this, request), + response: ResponseDispatcher.fromNullable(this, response), responseEndTiming: request._responseEndTiming, - page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined()), + page: PageDispatcher.fromNullable(this, request.frame()?._page.initializedOrUndefined()), })); } @@ -117,7 +117,7 @@ export class BrowserContextDispatcher extends Dispatcher { await this._context.exposeBinding(params.name, !!params.needsHandle, (source, ...args) => { - const pageDispatcher = PageDispatcher.from(this._scope, source.page); + const pageDispatcher = PageDispatcher.from(this, source.page); const binding = new BindingCallDispatcher(pageDispatcher, params.name, !!params.needsHandle, source, args); this._dispatchEvent('bindingCall', { binding }); return binding.promise(); @@ -187,7 +187,7 @@ export class BrowserContextDispatcher extends Dispatcher { - this._dispatchEvent('route', { route: RouteDispatcher.from(RequestDispatcher.from(this._scope, request), route) }); + this._dispatchEvent('route', { route: RouteDispatcher.from(RequestDispatcher.from(this, request), route) }); }); } @@ -213,7 +213,7 @@ export class BrowserContextDispatcher extends Dispatcher { @@ -225,7 +225,7 @@ export class BrowserContextDispatcher extends Dispatcher implements channels.BrowserChannel { +export class BrowserDispatcher extends Dispatcher implements channels.BrowserChannel { _type_Browser = true; constructor(scope: BrowserTypeDispatcher, browser: Browser) { - super(scope, browser, 'Browser', { version: browser.version(), name: browser.options.name }, true); + super(scope, browser, 'Browser', { version: browser.version(), name: browser.options.name }); this.addObjectListener(Browser.Events.Disconnected, () => this._didClose()); } @@ -44,11 +44,11 @@ export class BrowserDispatcher extends Dispatcher { const context = await this._object.newContext(metadata, params); - return { context: new BrowserContextDispatcher(this._scope, context) }; + return { context: new BrowserContextDispatcher(this, context) }; } async newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise { - return newContextForReuse(this._object, this._scope, params, null, metadata); + return newContextForReuse(this._object, this, params, null, metadata); } async close(): Promise { @@ -63,7 +63,7 @@ export class BrowserDispatcher extends Dispatcher { @@ -82,13 +82,13 @@ export class BrowserDispatcher extends Dispatcher implements channels.BrowserChannel { +export class ConnectedBrowserDispatcher extends Dispatcher implements channels.BrowserChannel { _type_Browser = true; private _contexts = new Set(); readonly selectors: Selectors; constructor(scope: RootDispatcher, browser: Browser) { - super(scope, browser, 'Browser', { version: browser.version(), name: browser.options.name }, true); + super(scope, browser, 'Browser', { version: browser.version(), name: browser.options.name }); // When we have a remotely-connected browser, each client gets a fresh Selector instance, // so that two clients do not interfere between each other. this.selectors = new Selectors(); @@ -101,11 +101,11 @@ export class ConnectedBrowserDispatcher extends Dispatcher this._contexts.delete(context)); - return { context: new BrowserContextDispatcher(this._scope, context) }; + return { context: new BrowserContextDispatcher(this, context) }; } async newContextForReuse(params: channels.BrowserNewContextForReuseParams, metadata: CallMetadata): Promise { - return newContextForReuse(this._object, this._scope, params, this.selectors, metadata); + return newContextForReuse(this._object, this as any as BrowserDispatcher, params, this.selectors, metadata); } async close(): Promise { @@ -120,7 +120,7 @@ export class ConnectedBrowserDispatcher extends Dispatcher { diff --git a/packages/playwright-core/src/server/dispatchers/browserTypeDispatcher.ts b/packages/playwright-core/src/server/dispatchers/browserTypeDispatcher.ts index 07d5090f79..f2cf3e51b9 100644 --- a/packages/playwright-core/src/server/dispatchers/browserTypeDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/browserTypeDispatcher.ts @@ -29,28 +29,28 @@ import { ProgressController } from '../progress'; import { WebSocketTransport } from '../transport'; import { findValidator, ValidationError, type ValidatorContext } from '../../protocol/validator'; -export class BrowserTypeDispatcher extends Dispatcher implements channels.BrowserTypeChannel { +export class BrowserTypeDispatcher extends Dispatcher implements channels.BrowserTypeChannel { _type_BrowserType = true; constructor(scope: RootDispatcher, browserType: BrowserType) { super(scope, browserType, 'BrowserType', { executablePath: browserType.executablePath(), name: browserType.name() - }, true); + }); } async launch(params: channels.BrowserTypeLaunchParams, metadata: CallMetadata): Promise { const browser = await this._object.launch(metadata, params); - return { browser: new BrowserDispatcher(this._scope, browser) }; + return { browser: new BrowserDispatcher(this, browser) }; } async launchPersistentContext(params: channels.BrowserTypeLaunchPersistentContextParams, metadata: CallMetadata): Promise { const browserContext = await this._object.launchPersistentContext(metadata, params.userDataDir, params); - return { context: new BrowserContextDispatcher(this._scope, browserContext) }; + return { context: new BrowserContextDispatcher(this, browserContext) }; } async connectOverCDP(params: channels.BrowserTypeConnectOverCDPParams, metadata: CallMetadata): Promise { const browser = await this._object.connectOverCDP(metadata, params.endpointURL, params, params.timeout); - const browserDispatcher = new BrowserDispatcher(this._scope, browser); + const browserDispatcher = new BrowserDispatcher(this, browser); return { browser: browserDispatcher, defaultContext: browser._defaultContext ? new BrowserContextDispatcher(browserDispatcher, browser._defaultContext) : undefined, @@ -64,7 +64,7 @@ export class BrowserTypeDispatcher extends Dispatcher { if (json.method === '__create__' && json.params.type === 'SocksSupport') socksInterceptor = new SocksInterceptor(transport, params.socksProxyRedirectPortForTest, json.params.guid); diff --git a/packages/playwright-core/src/server/dispatchers/cdpSessionDispatcher.ts b/packages/playwright-core/src/server/dispatchers/cdpSessionDispatcher.ts index 9a1ff337c2..4dd724f992 100644 --- a/packages/playwright-core/src/server/dispatchers/cdpSessionDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/cdpSessionDispatcher.ts @@ -21,11 +21,11 @@ import { Dispatcher } from './dispatcher'; import type { BrowserDispatcher } from './browserDispatcher'; import type { BrowserContextDispatcher } from './browserContextDispatcher'; -export class CDPSessionDispatcher extends Dispatcher implements channels.CDPSessionChannel { +export class CDPSessionDispatcher extends Dispatcher implements channels.CDPSessionChannel { _type_CDPSession = true; constructor(scope: BrowserDispatcher | BrowserContextDispatcher, crSession: CRSession) { - super(scope, crSession, 'CDPSession', {}, true); + super(scope, crSession, 'CDPSession', {}); crSession._eventListener = (method, params) => { this._dispatchEvent('event', { method, params }); }; diff --git a/packages/playwright-core/src/server/dispatchers/dispatcher.ts b/packages/playwright-core/src/server/dispatchers/dispatcher.ts index 5abc2003ce..dda9007423 100644 --- a/packages/playwright-core/src/server/dispatchers/dispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/dispatcher.ts @@ -44,9 +44,8 @@ export function lookupNullableDispatcher(object: any | null): Di return object ? lookupDispatcher(object) : undefined; } -export class Dispatcher extends EventEmitter implements channels.Channel { +export class Dispatcher extends EventEmitter implements channels.Channel { private _connection: DispatcherConnection; - private _isScope: boolean; // Parent is always "isScope". private _parent: ParentScopeType | undefined; // Only "isScope" channel owners have registered dispatchers inside. @@ -56,16 +55,13 @@ export class Dispatcher, isScope?: boolean) { + constructor(parent: ParentScopeType | DispatcherConnection, object: Type, type: string, initializer: channels.InitializerTraits) { super(); this._connection = parent instanceof DispatcherConnection ? parent : parent._connection; - this._isScope = !!isScope; this._parent = parent instanceof DispatcherConnection ? undefined : parent; - this._scope = (isScope ? this : this._parent!) as any as ScopeType; const guid = object.guid; assert(!this._connection._dispatchers.has(guid)); @@ -84,8 +80,8 @@ export class Dispatcher void) { @@ -93,7 +89,6 @@ export class Dispatcher { private _initialized = false; constructor(connection: DispatcherConnection, private readonly createPlaywright?: (scope: RootDispatcher, options: channels.RootInitializeParams) => Promise) { - super(connection, { guid: '' }, 'Root', {}, true); + super(connection, { guid: '' }, 'Root', {}); } async initialize(params: channels.RootInitializeParams): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/electronDispatcher.ts b/packages/playwright-core/src/server/dispatchers/electronDispatcher.ts index 514a47c3ed..0462bad356 100644 --- a/packages/playwright-core/src/server/dispatchers/electronDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/electronDispatcher.ts @@ -24,27 +24,27 @@ import type { PageDispatcher } from './pageDispatcher'; import { parseArgument, serializeResult } from './jsHandleDispatcher'; import { ElementHandleDispatcher } from './elementHandlerDispatcher'; -export class ElectronDispatcher extends Dispatcher implements channels.ElectronChannel { +export class ElectronDispatcher extends Dispatcher implements channels.ElectronChannel { _type_Electron = true; constructor(scope: RootDispatcher, electron: Electron) { - super(scope, electron, 'Electron', {}, true); + super(scope, electron, 'Electron', {}); } async launch(params: channels.ElectronLaunchParams): Promise { const electronApplication = await this._object.launch(params); - return { electronApplication: new ElectronApplicationDispatcher(this._scope, electronApplication) }; + return { electronApplication: new ElectronApplicationDispatcher(this, electronApplication) }; } } -export class ElectronApplicationDispatcher extends Dispatcher implements channels.ElectronApplicationChannel { +export class ElectronApplicationDispatcher extends Dispatcher implements channels.ElectronApplicationChannel { _type_EventTarget = true; _type_ElectronApplication = true; constructor(scope: ElectronDispatcher, electronApplication: ElectronApplication) { super(scope, electronApplication, 'ElectronApplication', { context: new BrowserContextDispatcher(scope, electronApplication.context()) - }, true); + }); this.addObjectListener(ElectronApplication.Events.Close, () => { this._dispatchEvent('close'); this._dispose(); @@ -53,7 +53,7 @@ export class ElectronApplicationDispatcher extends Dispatcher { const handle = await this._object.browserWindow((params.page as PageDispatcher).page()); - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, handle) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this, handle) }; } async evaluateExpression(params: channels.ElectronApplicationEvaluateExpressionParams): Promise { @@ -64,7 +64,7 @@ export class ElectronApplicationDispatcher extends Dispatcher { const handle = await this._object._nodeElectronHandlePromise; const result = await handle.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg)); - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, result) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this, result) }; } async close(): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts index b0288ddebe..786c03c97c 100644 --- a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts @@ -197,12 +197,12 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann async querySelector(params: channels.ElementHandleQuerySelectorParams, metadata: CallMetadata): Promise { const handle = await this._elementHandle.querySelector(params.selector, params); - return { element: ElementHandleDispatcher.fromNullable(this._scope, handle) }; + return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), handle) }; } async querySelectorAll(params: channels.ElementHandleQuerySelectorAllParams, metadata: CallMetadata): Promise { const elements = await this._elementHandle.querySelectorAll(params.selector); - return { elements: elements.map(e => ElementHandleDispatcher.from(this._scope, e)) }; + return { elements: elements.map(e => ElementHandleDispatcher.from(this.parentScope(), e)) }; } async evalOnSelector(params: channels.ElementHandleEvalOnSelectorParams, metadata: CallMetadata): Promise { @@ -218,6 +218,6 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann } async waitForSelector(params: channels.ElementHandleWaitForSelectorParams, metadata: CallMetadata): Promise { - return { element: ElementHandleDispatcher.fromNullable(this._scope, await this._elementHandle.waitForSelector(metadata, params.selector, params)) }; + return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._elementHandle.waitForSelector(metadata, params.selector, params)) }; } } diff --git a/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts b/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts index da3551adee..4f69b42d38 100644 --- a/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts @@ -49,7 +49,7 @@ export class FrameDispatcher extends Dispatcher { this._dispatchEvent('loadstate', { add: lifecycleEvent }); @@ -62,7 +62,7 @@ export class FrameDispatcher extends Dispatcher { - return { element: ElementHandleDispatcher.from(this._scope, await this._frame.frameElement()) }; + return { element: ElementHandleDispatcher.from(this.parentScope(), await this._frame.frameElement()) }; } async evaluateExpression(params: channels.FrameEvaluateExpressionParams, metadata: CallMetadata): Promise { @@ -80,11 +80,11 @@ export class FrameDispatcher extends Dispatcher { - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, await this._frame.evaluateExpressionHandleAndWaitForSignals(params.expression, params.isFunction, parseArgument(params.arg), 'main')) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this.parentScope(), await this._frame.evaluateExpressionHandleAndWaitForSignals(params.expression, params.isFunction, parseArgument(params.arg), 'main')) }; } async waitForSelector(params: channels.FrameWaitForSelectorParams, metadata: CallMetadata): Promise { - return { element: ElementHandleDispatcher.fromNullable(this._scope, await this._frame.waitForSelector(metadata, params.selector, params)) }; + return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._frame.waitForSelector(metadata, params.selector, params)) }; } async dispatchEvent(params: channels.FrameDispatchEventParams, metadata: CallMetadata): Promise { @@ -100,12 +100,12 @@ export class FrameDispatcher extends Dispatcher { - return { element: ElementHandleDispatcher.fromNullable(this._scope, await this._frame.querySelector(params.selector, params)) }; + return { element: ElementHandleDispatcher.fromNullable(this.parentScope(), await this._frame.querySelector(params.selector, params)) }; } async querySelectorAll(params: channels.FrameQuerySelectorAllParams, metadata: CallMetadata): Promise { const elements = await this._frame.querySelectorAll(params.selector); - return { elements: elements.map(e => ElementHandleDispatcher.from(this._scope, e)) }; + return { elements: elements.map(e => ElementHandleDispatcher.from(this.parentScope(), e)) }; } async queryCount(params: channels.FrameQueryCountParams): Promise { @@ -121,11 +121,11 @@ export class FrameDispatcher extends Dispatcher { - return { element: ElementHandleDispatcher.from(this._scope, await this._frame.addScriptTag(params)) }; + return { element: ElementHandleDispatcher.from(this.parentScope(), await this._frame.addScriptTag(params)) }; } async addStyleTag(params: channels.FrameAddStyleTagParams, metadata: CallMetadata): Promise { - return { element: ElementHandleDispatcher.from(this._scope, await this._frame.addStyleTag(params)) }; + return { element: ElementHandleDispatcher.from(this.parentScope(), await this._frame.addStyleTag(params)) }; } async click(params: channels.FrameClickParams, metadata: CallMetadata): Promise { @@ -245,7 +245,7 @@ export class FrameDispatcher extends Dispatcher { - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, await this._frame._waitForFunctionExpression(metadata, params.expression, params.isFunction, parseArgument(params.arg), params)) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this.parentScope(), await this._frame._waitForFunctionExpression(metadata, params.expression, params.isFunction, parseArgument(params.arg), params)) }; } async title(params: channels.FrameTitleParams, metadata: CallMetadata): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts b/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts index 9d55a8e4d2..78dbc40489 100644 --- a/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts @@ -41,19 +41,19 @@ export class JSHandleDispatcher extends Dispatcher { const jsHandle = await this._object.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg)); - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, jsHandle) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this.parentScope(), jsHandle) }; } async getProperty(params: channels.JSHandleGetPropertyParams): Promise { const jsHandle = await this._object.getProperty(params.name); - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, jsHandle) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this.parentScope(), jsHandle) }; } async getPropertyList(): Promise { const map = await this._object.getProperties(); const properties = []; for (const [name, value] of map) - properties.push({ name, value: ElementHandleDispatcher.fromJSHandle(this._scope, value) }); + properties.push({ name, value: ElementHandleDispatcher.fromJSHandle(this.parentScope(), value) }); return { properties }; } diff --git a/packages/playwright-core/src/server/dispatchers/networkDispatchers.ts b/packages/playwright-core/src/server/dispatchers/networkDispatchers.ts index 74d93f696c..b5e33ab4e9 100644 --- a/packages/playwright-core/src/server/dispatchers/networkDispatchers.ts +++ b/packages/playwright-core/src/server/dispatchers/networkDispatchers.ts @@ -164,7 +164,7 @@ export class WebSocketDispatcher extends Dispatcher implements channels.APIRequestContextChannel { +export class APIRequestContextDispatcher extends Dispatcher implements channels.APIRequestContextChannel { _type_APIRequestContext = true; static from(scope: RootDispatcher | BrowserContextDispatcher, request: APIRequestContext): APIRequestContextDispatcher { @@ -182,7 +182,7 @@ export class APIRequestContextDispatcher extends Dispatcher implements channels.PageChannel { +export class PageDispatcher extends Dispatcher implements channels.PageChannel { _type_EventTarget = true; _type_Page = true; private _page: Page; @@ -66,7 +66,7 @@ export class PageDispatcher extends Dispatcher this._dispatchEvent('console', { message: new ConsoleMessageDispatcher(this._scope, message) })); + this.addObjectListener(Page.Events.Console, message => this._dispatchEvent('console', { message: new ConsoleMessageDispatcher(this, message) })); this.addObjectListener(Page.Events.Crash, () => this._dispatchEvent('crash')); - this.addObjectListener(Page.Events.Dialog, dialog => this._dispatchEvent('dialog', { dialog: new DialogDispatcher(this._scope, dialog) })); + this.addObjectListener(Page.Events.Dialog, dialog => this._dispatchEvent('dialog', { dialog: new DialogDispatcher(this, dialog) })); this.addObjectListener(Page.Events.Download, (download: Download) => { // Artifact can outlive the page, so bind to the context scope. this._dispatchEvent('download', { url: download.url, suggestedFilename: download.suggestedFilename(), artifact: new ArtifactDispatcher(parentScope, download.artifact) }); }); this.addObjectListener(Page.Events.FileChooser, (fileChooser: FileChooser) => this._dispatchEvent('fileChooser', { - element: ElementHandleDispatcher.from(this._scope, fileChooser.element()), + element: ElementHandleDispatcher.from(this, fileChooser.element()), isMultiple: fileChooser.isMultiple() })); this.addObjectListener(Page.Events.FrameAttached, frame => this._onFrameAttached(frame)); this.addObjectListener(Page.Events.FrameDetached, frame => this._onFrameDetached(frame)); this.addObjectListener(Page.Events.PageError, error => this._dispatchEvent('pageError', { error: serializeError(error) })); - this.addObjectListener(Page.Events.WebSocket, webSocket => this._dispatchEvent('webSocket', { webSocket: new WebSocketDispatcher(this._scope, webSocket) })); - this.addObjectListener(Page.Events.Worker, worker => this._dispatchEvent('worker', { worker: new WorkerDispatcher(this._scope, worker) })); + this.addObjectListener(Page.Events.WebSocket, webSocket => this._dispatchEvent('webSocket', { webSocket: new WebSocketDispatcher(this, webSocket) })); + this.addObjectListener(Page.Events.Worker, worker => this._dispatchEvent('worker', { worker: new WorkerDispatcher(this, worker) })); this.addObjectListener(Page.Events.Video, (artifact: Artifact) => this._dispatchEvent('video', { artifact: existingDispatcher(artifact) })); if (page._video) this._dispatchEvent('video', { artifact: existingDispatcher(page._video) }); @@ -114,7 +114,7 @@ export class PageDispatcher extends Dispatcher { await this._page.exposeBinding(params.name, !!params.needsHandle, (source, ...args) => { - const binding = new BindingCallDispatcher(this._scope, params.name, !!params.needsHandle, source, args); + const binding = new BindingCallDispatcher(this, params.name, !!params.needsHandle, source, args); this._dispatchEvent('bindingCall', { binding }); return binding.promise(); }); @@ -159,7 +159,7 @@ export class PageDispatcher extends Dispatcher { - this._dispatchEvent('route', { route: RouteDispatcher.from(RequestDispatcher.from(this.parentScope()!, request), route) }); + this._dispatchEvent('route', { route: RouteDispatcher.from(RequestDispatcher.from(this.parentScope(), request), route) }); }); } @@ -282,7 +282,7 @@ export class PageDispatcher extends Dispatcher implements channels.WorkerChannel { +export class WorkerDispatcher extends Dispatcher implements channels.WorkerChannel { _type_Worker = true; static fromNullable(scope: PageDispatcher | BrowserContextDispatcher, worker: Worker | null): WorkerDispatcher | undefined { @@ -309,7 +309,7 @@ export class WorkerDispatcher extends Dispatcher this._dispatchEvent('close')); } @@ -318,7 +318,7 @@ export class WorkerDispatcher extends Dispatcher { - return { handle: ElementHandleDispatcher.fromJSHandle(this._scope, await this._object.evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg))) }; + return { handle: ElementHandleDispatcher.fromJSHandle(this, await this._object.evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg))) }; } } diff --git a/packages/playwright-core/src/server/dispatchers/playwrightDispatcher.ts b/packages/playwright-core/src/server/dispatchers/playwrightDispatcher.ts index 9bdb4f1d87..2e925589b6 100644 --- a/packages/playwright-core/src/server/dispatchers/playwrightDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/playwrightDispatcher.ts @@ -52,14 +52,14 @@ export class PlaywrightDispatcher extends Dispatcher { const request = new GlobalAPIRequestContext(this._object, params); - return { request: APIRequestContextDispatcher.from(this._scope, request) }; + return { request: APIRequestContextDispatcher.from(this.parentScope(), request) }; } async hideHighlight(params: channels.PlaywrightHideHighlightParams, metadata?: channels.Metadata): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/streamDispatcher.ts b/packages/playwright-core/src/server/dispatchers/streamDispatcher.ts index 0e1fb617ee..9e2740540a 100644 --- a/packages/playwright-core/src/server/dispatchers/streamDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/streamDispatcher.ts @@ -15,16 +15,16 @@ */ import type * as channels from '../../protocol/channels'; -import type { DispatcherScope } from './dispatcher'; import { Dispatcher } from './dispatcher'; import type * as stream from 'stream'; import { createGuid } from '../../utils'; +import type { ArtifactDispatcher } from './artifactDispatcher'; -export class StreamDispatcher extends Dispatcher<{ guid: string, stream: stream.Readable }, channels.StreamChannel, DispatcherScope> implements channels.StreamChannel { +export class StreamDispatcher extends Dispatcher<{ guid: string, stream: stream.Readable }, channels.StreamChannel, ArtifactDispatcher> implements channels.StreamChannel { _type_Stream = true; private _ended: boolean = false; - constructor(scope: DispatcherScope, stream: stream.Readable) { + constructor(scope: ArtifactDispatcher, stream: stream.Readable) { super(scope, { guid: 'stream@' + createGuid(), stream }, 'Stream', {}); // In Node v12.9.0+ we can use readableEnded. stream.once('end', () => this._ended = true); diff --git a/packages/playwright-core/src/server/dispatchers/tracingDispatcher.ts b/packages/playwright-core/src/server/dispatchers/tracingDispatcher.ts index 07a849b73e..84ab9786e2 100644 --- a/packages/playwright-core/src/server/dispatchers/tracingDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/tracingDispatcher.ts @@ -30,7 +30,7 @@ export class TracingDispatcher extends Dispatcher { @@ -43,7 +43,7 @@ export class TracingDispatcher extends Dispatcher { const { artifact, sourceEntries } = await this._object.stopChunk(params); - return { artifact: artifact ? new ArtifactDispatcher(this._scope, artifact) : undefined, sourceEntries }; + return { artifact: artifact ? new ArtifactDispatcher(this, artifact) : undefined, sourceEntries }; } async tracingStop(params: channels.TracingTracingStopParams): Promise {