mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: dispatcher is a scope (#16843)
This commit is contained in:
parent
aac9df0542
commit
6319b14069
@ -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<Android, channels.AndroidChannel, RootDispatcher, AndroidDispatcher> implements channels.AndroidChannel {
|
||||
export class AndroidDispatcher extends Dispatcher<Android, channels.AndroidChannel, RootDispatcher> 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<channels.AndroidDevicesResult> {
|
||||
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<Android, channels.AndroidChann
|
||||
}
|
||||
}
|
||||
|
||||
export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.AndroidDeviceChannel, AndroidDispatcher, AndroidDeviceDispatcher> implements channels.AndroidDeviceChannel {
|
||||
export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.AndroidDeviceChannel, AndroidDispatcher> implements channels.AndroidDeviceChannel {
|
||||
_type_EventTarget = true;
|
||||
_type_AndroidDevice = true;
|
||||
|
||||
@ -53,7 +53,7 @@ export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.
|
||||
super(scope, device, 'AndroidDevice', {
|
||||
model: device.model,
|
||||
serial: device.serial,
|
||||
}, true);
|
||||
});
|
||||
for (const webView of device.webViews())
|
||||
this._dispatchEvent('webViewAdded', { webView });
|
||||
this.addObjectListener(AndroidDevice.Events.WebViewAdded, webView => this._dispatchEvent('webViewAdded', { webView }));
|
||||
@ -145,7 +145,7 @@ export class AndroidDeviceDispatcher extends Dispatcher<AndroidDevice, channels.
|
||||
|
||||
async open(params: channels.AndroidDeviceOpenParams, metadata: CallMetadata): Promise<channels.AndroidDeviceOpenResult> {
|
||||
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<AndroidDevice, channels.
|
||||
|
||||
async launchBrowser(params: channels.AndroidDeviceLaunchBrowserParams): Promise<channels.AndroidDeviceLaunchBrowserResult> {
|
||||
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<AndroidDevice, channels.
|
||||
}
|
||||
|
||||
async connectToWebView(params: channels.AndroidDeviceConnectToWebViewParams): Promise<channels.AndroidDeviceConnectToWebViewResult> {
|
||||
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<SocketBackend, channels.AndroidSocketChannel, AndroidDeviceDispatcher, AndroidSocketDispatcher> implements channels.AndroidSocketChannel {
|
||||
export class AndroidSocketDispatcher extends Dispatcher<SocketBackend, channels.AndroidSocketChannel, AndroidDeviceDispatcher> 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');
|
||||
|
||||
@ -62,7 +62,7 @@ export class ArtifactDispatcher extends Dispatcher<Artifact, channels.ArtifactCh
|
||||
}
|
||||
try {
|
||||
const readable = fs.createReadStream(localPath);
|
||||
const stream = new StreamDispatcher(this._scope, readable);
|
||||
const stream = new StreamDispatcher(this, readable);
|
||||
// Resolve with a stream, so that client starts saving the data.
|
||||
resolve({ stream });
|
||||
// Block the Artifact until the stream is consumed.
|
||||
@ -83,7 +83,7 @@ export class ArtifactDispatcher extends Dispatcher<Artifact, channels.ArtifactCh
|
||||
if (!fileName)
|
||||
return {};
|
||||
const readable = fs.createReadStream(fileName);
|
||||
return { stream: new StreamDispatcher(this._scope, readable) };
|
||||
return { stream: new StreamDispatcher(this, readable) };
|
||||
}
|
||||
|
||||
async failure(): Promise<channels.ArtifactFailureResult> {
|
||||
|
||||
@ -34,7 +34,7 @@ import * as path from 'path';
|
||||
import { createGuid } from '../../utils';
|
||||
import { WritableStreamDispatcher } from './writableStreamDispatcher';
|
||||
|
||||
export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channels.BrowserContextChannel, DispatcherScope, BrowserContextDispatcher> implements channels.BrowserContextChannel {
|
||||
export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channels.BrowserContextChannel, DispatcherScope> implements channels.BrowserContextChannel {
|
||||
_type_EventTarget = true;
|
||||
_type_BrowserContext = true;
|
||||
private _context: BrowserContext;
|
||||
@ -48,7 +48,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
isChromium: context._browser.options.isChromium,
|
||||
requestContext,
|
||||
tracing,
|
||||
}, true);
|
||||
});
|
||||
|
||||
this.adopt(requestContext);
|
||||
this.adopt(tracing);
|
||||
@ -70,9 +70,9 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
}
|
||||
|
||||
for (const page of context.pages())
|
||||
this._dispatchEvent('page', { page: PageDispatcher.from(this._scope, page) });
|
||||
this._dispatchEvent('page', { page: PageDispatcher.from(this, page) });
|
||||
this.addObjectListener(BrowserContext.Events.Page, page => {
|
||||
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<BrowserContext, channel
|
||||
|
||||
if (context._browser.options.name === 'chromium') {
|
||||
for (const page of (context as CRBrowserContext).backgroundPages())
|
||||
this._dispatchEvent('backgroundPage', { page: PageDispatcher.from(this._scope, page) });
|
||||
this.addObjectListener(CRBrowserContext.CREvents.BackgroundPage, page => 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<BrowserContext, channel
|
||||
await fs.promises.mkdir(tmpDir);
|
||||
this._context._tempDirs.push(tmpDir);
|
||||
const file = fs.createWriteStream(path.join(tmpDir, params.name));
|
||||
return { writableStream: new WritableStreamDispatcher(this._scope, file) };
|
||||
return { writableStream: new WritableStreamDispatcher(this, file) };
|
||||
}
|
||||
|
||||
async setDefaultNavigationTimeoutNoReply(params: channels.BrowserContextSetDefaultNavigationTimeoutNoReplyParams) {
|
||||
@ -130,7 +130,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
|
||||
async exposeBinding(params: channels.BrowserContextExposeBindingParams): Promise<void> {
|
||||
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<BrowserContext, channel
|
||||
return;
|
||||
}
|
||||
await this._context.setRequestInterceptor((route, request) => {
|
||||
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<BrowserContext, channel
|
||||
if (!params.page && !params.frame || params.page && params.frame)
|
||||
throw new Error(`CDP session must be initiated with either Page or Frame, not none or both`);
|
||||
const crBrowserContext = this._object as CRBrowserContext;
|
||||
return { session: new CDPSessionDispatcher(this._scope, await crBrowserContext.newCDPSession((params.page ? params.page as PageDispatcher : params.frame as FrameDispatcher)._object)) };
|
||||
return { session: new CDPSessionDispatcher(this, await crBrowserContext.newCDPSession((params.page ? params.page as PageDispatcher : params.frame as FrameDispatcher)._object)) };
|
||||
}
|
||||
|
||||
async harStart(params: channels.BrowserContextHarStartParams): Promise<channels.BrowserContextHarStartResult> {
|
||||
@ -225,7 +225,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
||||
const artifact = await this._context._harExport(params.harId);
|
||||
if (!artifact)
|
||||
throw new Error('No HAR artifact. Ensure record.harPath is set.');
|
||||
return { artifact: new ArtifactDispatcher(this._scope, artifact) };
|
||||
return { artifact: new ArtifactDispatcher(this, artifact) };
|
||||
}
|
||||
|
||||
override _dispose() {
|
||||
|
||||
@ -29,11 +29,11 @@ import { BrowserContext } from '../browserContext';
|
||||
import { Selectors } from '../selectors';
|
||||
import type { BrowserTypeDispatcher } from './browserTypeDispatcher';
|
||||
|
||||
export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChannel, BrowserTypeDispatcher, BrowserDispatcher> implements channels.BrowserChannel {
|
||||
export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChannel, BrowserTypeDispatcher> 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<Browser, channels.BrowserChann
|
||||
|
||||
async newContext(params: channels.BrowserNewContextParams, metadata: CallMetadata): Promise<channels.BrowserNewContextResult> {
|
||||
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<channels.BrowserNewContextForReuseResult> {
|
||||
return newContextForReuse(this._object, this._scope, params, null, metadata);
|
||||
return newContextForReuse(this._object, this, params, null, metadata);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
@ -63,7 +63,7 @@ export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChann
|
||||
if (!this._object.options.isChromium)
|
||||
throw new Error(`CDP session is only available in Chromium`);
|
||||
const crBrowser = this._object as CRBrowser;
|
||||
return { session: new CDPSessionDispatcher(this._scope, await crBrowser.newBrowserCDPSession()) };
|
||||
return { session: new CDPSessionDispatcher(this, await crBrowser.newBrowserCDPSession()) };
|
||||
}
|
||||
|
||||
async startTracing(params: channels.BrowserStartTracingParams): Promise<void> {
|
||||
@ -82,13 +82,13 @@ export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserChann
|
||||
}
|
||||
|
||||
// This class implements multiplexing browser dispatchers over a single Browser instance.
|
||||
export class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.BrowserChannel, RootDispatcher, BrowserDispatcher> implements channels.BrowserChannel {
|
||||
export class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.BrowserChannel, RootDispatcher> implements channels.BrowserChannel {
|
||||
_type_Browser = true;
|
||||
private _contexts = new Set<BrowserContext>();
|
||||
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<Browser, channels.Bro
|
||||
this._contexts.add(context);
|
||||
context.setSelectors(this.selectors);
|
||||
context.on(BrowserContext.Events.Close, () => 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<channels.BrowserNewContextForReuseResult> {
|
||||
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<void> {
|
||||
@ -120,7 +120,7 @@ export class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.Bro
|
||||
if (!this._object.options.isChromium)
|
||||
throw new Error(`CDP session is only available in Chromium`);
|
||||
const crBrowser = this._object as CRBrowser;
|
||||
return { session: new CDPSessionDispatcher(this._scope, await crBrowser.newBrowserCDPSession()) };
|
||||
return { session: new CDPSessionDispatcher(this as any as BrowserDispatcher, await crBrowser.newBrowserCDPSession()) };
|
||||
}
|
||||
|
||||
async startTracing(params: channels.BrowserStartTracingParams): Promise<void> {
|
||||
|
||||
@ -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<BrowserType, channels.BrowserTypeChannel, RootDispatcher, BrowserTypeDispatcher> implements channels.BrowserTypeChannel {
|
||||
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.BrowserTypeChannel, RootDispatcher> 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<channels.BrowserTypeLaunchResult> {
|
||||
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<channels.BrowserTypeLaunchPersistentContextResult> {
|
||||
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<channels.BrowserTypeConnectOverCDPResult> {
|
||||
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<BrowserType, channels.Brow
|
||||
const paramsHeaders = Object.assign({ 'User-Agent': getUserAgent() }, params.headers || {});
|
||||
const transport = await WebSocketTransport.connect(progress, params.wsEndpoint, paramsHeaders, true);
|
||||
let socksInterceptor: SocksInterceptor | undefined;
|
||||
const pipe = new JsonPipeDispatcher(this._scope);
|
||||
const pipe = new JsonPipeDispatcher(this);
|
||||
transport.onmessage = json => {
|
||||
if (json.method === '__create__' && json.params.type === 'SocksSupport')
|
||||
socksInterceptor = new SocksInterceptor(transport, params.socksProxyRedirectPortForTest, json.params.guid);
|
||||
|
||||
@ -21,11 +21,11 @@ import { Dispatcher } from './dispatcher';
|
||||
import type { BrowserDispatcher } from './browserDispatcher';
|
||||
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
|
||||
export class CDPSessionDispatcher extends Dispatcher<CRSession, channels.CDPSessionChannel, BrowserDispatcher | BrowserContextDispatcher, CDPSessionDispatcher> implements channels.CDPSessionChannel {
|
||||
export class CDPSessionDispatcher extends Dispatcher<CRSession, channels.CDPSessionChannel, BrowserDispatcher | BrowserContextDispatcher> 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 });
|
||||
};
|
||||
|
||||
@ -44,9 +44,8 @@ export function lookupNullableDispatcher<DispatcherType>(object: any | null): Di
|
||||
return object ? lookupDispatcher(object) : undefined;
|
||||
}
|
||||
|
||||
export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeType extends DispatcherScope, ScopeType extends DispatcherScope = ParentScopeType> extends EventEmitter implements channels.Channel {
|
||||
export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeType extends DispatcherScope> 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<Type extends { guid: string }, ChannelType, ParentScopeT
|
||||
|
||||
readonly _guid: string;
|
||||
readonly _type: string;
|
||||
readonly _scope: ScopeType;
|
||||
_object: Type;
|
||||
|
||||
constructor(parent: ParentScopeType | DispatcherConnection, object: Type, type: string, initializer: channels.InitializerTraits<Type>, isScope?: boolean) {
|
||||
constructor(parent: ParentScopeType | DispatcherConnection, object: Type, type: string, initializer: channels.InitializerTraits<Type>) {
|
||||
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<Type extends { guid: string }, ChannelType, ParentScopeT
|
||||
this._connection.sendCreate(this._parent, type, guid, initializer, this._parent._object);
|
||||
}
|
||||
|
||||
parentScope(): ParentScopeType | undefined {
|
||||
return this._parent;
|
||||
parentScope(): ParentScopeType {
|
||||
return this._parent!;
|
||||
}
|
||||
|
||||
addObjectListener(eventName: (string | symbol), handler: (...args: any[]) => void) {
|
||||
@ -93,7 +89,6 @@ export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeT
|
||||
}
|
||||
|
||||
adopt(child: DispatcherScope) {
|
||||
assert(this._isScope);
|
||||
const oldParent = child._parent!;
|
||||
oldParent._dispatchers.delete(child._guid);
|
||||
this._dispatchers.set(child._guid, child);
|
||||
@ -113,6 +108,11 @@ export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeT
|
||||
}
|
||||
|
||||
_dispose() {
|
||||
this._disposeRecursively();
|
||||
this._connection.sendDispose(this);
|
||||
}
|
||||
|
||||
private _disposeRecursively() {
|
||||
assert(!this._disposed, `${this._guid} is disposed more than once`);
|
||||
this._disposed = true;
|
||||
eventsHelper.removeEventListeners(this._eventListeners);
|
||||
@ -124,11 +124,8 @@ export class Dispatcher<Type extends { guid: string }, ChannelType, ParentScopeT
|
||||
|
||||
// Dispose all children.
|
||||
for (const dispatcher of [...this._dispatchers.values()])
|
||||
dispatcher._dispose();
|
||||
dispatcher._disposeRecursively();
|
||||
this._dispatchers.clear();
|
||||
|
||||
if (this._isScope)
|
||||
this._connection.sendDispose(this);
|
||||
delete (this._object as any)[dispatcherSymbol];
|
||||
}
|
||||
|
||||
@ -150,7 +147,7 @@ export class RootDispatcher extends Dispatcher<{ guid: '' }, any, any> {
|
||||
private _initialized = false;
|
||||
|
||||
constructor(connection: DispatcherConnection, private readonly createPlaywright?: (scope: RootDispatcher, options: channels.RootInitializeParams) => Promise<PlaywrightDispatcher>) {
|
||||
super(connection, { guid: '' }, 'Root', {}, true);
|
||||
super(connection, { guid: '' }, 'Root', {});
|
||||
}
|
||||
|
||||
async initialize(params: channels.RootInitializeParams): Promise<channels.RootInitializeResult> {
|
||||
|
||||
@ -24,27 +24,27 @@ import type { PageDispatcher } from './pageDispatcher';
|
||||
import { parseArgument, serializeResult } from './jsHandleDispatcher';
|
||||
import { ElementHandleDispatcher } from './elementHandlerDispatcher';
|
||||
|
||||
export class ElectronDispatcher extends Dispatcher<Electron, channels.ElectronChannel, RootDispatcher, ElectronDispatcher> implements channels.ElectronChannel {
|
||||
export class ElectronDispatcher extends Dispatcher<Electron, channels.ElectronChannel, RootDispatcher> 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<channels.ElectronLaunchResult> {
|
||||
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<ElectronApplication, channels.ElectronApplicationChannel, ElectronDispatcher, ElectronApplicationDispatcher> implements channels.ElectronApplicationChannel {
|
||||
export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplication, channels.ElectronApplicationChannel, ElectronDispatcher> 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<ElectronApplicatio
|
||||
|
||||
async browserWindow(params: channels.ElectronApplicationBrowserWindowParams): Promise<channels.ElectronApplicationBrowserWindowResult> {
|
||||
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<channels.ElectronApplicationEvaluateExpressionResult> {
|
||||
@ -64,7 +64,7 @@ export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplicatio
|
||||
async evaluateExpressionHandle(params: channels.ElectronApplicationEvaluateExpressionHandleParams): Promise<channels.ElectronApplicationEvaluateExpressionHandleResult> {
|
||||
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<void> {
|
||||
|
||||
@ -197,12 +197,12 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann
|
||||
|
||||
async querySelector(params: channels.ElementHandleQuerySelectorParams, metadata: CallMetadata): Promise<channels.ElementHandleQuerySelectorResult> {
|
||||
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<channels.ElementHandleQuerySelectorAllResult> {
|
||||
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<channels.ElementHandleEvalOnSelectorResult> {
|
||||
@ -218,6 +218,6 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann
|
||||
}
|
||||
|
||||
async waitForSelector(params: channels.ElementHandleWaitForSelectorParams, metadata: CallMetadata): Promise<channels.ElementHandleWaitForSelectorResult> {
|
||||
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)) };
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
name: frame.name(),
|
||||
parentFrame: FrameDispatcher.fromNullable(scope, frame.parentFrame()),
|
||||
loadStates: Array.from(frame._subtreeLifecycleEvents),
|
||||
}, true);
|
||||
});
|
||||
this._frame = frame;
|
||||
this.addObjectListener(Frame.Events.AddLifecycle, lifecycleEvent => {
|
||||
this._dispatchEvent('loadstate', { add: lifecycleEvent });
|
||||
@ -62,7 +62,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
return;
|
||||
const params = { url: event.url, name: event.name, error: event.error ? event.error.message : undefined };
|
||||
if (event.newDocument)
|
||||
(params as any).newDocument = { request: RequestDispatcher.fromNullable(scope.parentScope()!, event.newDocument.request || null) };
|
||||
(params as any).newDocument = { request: RequestDispatcher.fromNullable(scope.parentScope(), event.newDocument.request || null) };
|
||||
this._dispatchEvent('navigated', params);
|
||||
});
|
||||
}
|
||||
@ -72,7 +72,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
}
|
||||
|
||||
async frameElement(): Promise<channels.FrameFrameElementResult> {
|
||||
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<channels.FrameEvaluateExpressionResult> {
|
||||
@ -80,11 +80,11 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
}
|
||||
|
||||
async evaluateExpressionHandle(params: channels.FrameEvaluateExpressionHandleParams, metadata: CallMetadata): Promise<channels.FrameEvaluateExpressionHandleResult> {
|
||||
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<channels.FrameWaitForSelectorResult> {
|
||||
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<void> {
|
||||
@ -100,12 +100,12 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
}
|
||||
|
||||
async querySelector(params: channels.FrameQuerySelectorParams, metadata: CallMetadata): Promise<channels.FrameQuerySelectorResult> {
|
||||
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<channels.FrameQuerySelectorAllResult> {
|
||||
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<channels.FrameQueryCountResult> {
|
||||
@ -121,11 +121,11 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
}
|
||||
|
||||
async addScriptTag(params: channels.FrameAddScriptTagParams, metadata: CallMetadata): Promise<channels.FrameAddScriptTagResult> {
|
||||
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<channels.FrameAddStyleTagResult> {
|
||||
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<void> {
|
||||
@ -245,7 +245,7 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel, Pa
|
||||
}
|
||||
|
||||
async waitForFunction(params: channels.FrameWaitForFunctionParams, metadata: CallMetadata): Promise<channels.FrameWaitForFunctionResult> {
|
||||
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<channels.FrameTitleResult> {
|
||||
|
||||
@ -41,19 +41,19 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, channels.JSHandl
|
||||
|
||||
async evaluateExpressionHandle(params: channels.JSHandleEvaluateExpressionHandleParams): Promise<channels.JSHandleEvaluateExpressionHandleResult> {
|
||||
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<channels.JSHandleGetPropertyResult> {
|
||||
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<channels.JSHandleGetPropertyListResult> {
|
||||
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 };
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +164,7 @@ export class WebSocketDispatcher extends Dispatcher<WebSocket, channels.WebSocke
|
||||
}
|
||||
}
|
||||
|
||||
export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, channels.APIRequestContextChannel, RootDispatcher | BrowserContextDispatcher, APIRequestContextDispatcher> implements channels.APIRequestContextChannel {
|
||||
export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, channels.APIRequestContextChannel, RootDispatcher | BrowserContextDispatcher> implements channels.APIRequestContextChannel {
|
||||
_type_APIRequestContext = true;
|
||||
|
||||
static from(scope: RootDispatcher | BrowserContextDispatcher, request: APIRequestContext): APIRequestContextDispatcher {
|
||||
@ -182,7 +182,7 @@ export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, c
|
||||
|
||||
super(parentScope, request, 'APIRequestContext', {
|
||||
tracing,
|
||||
}, true);
|
||||
});
|
||||
|
||||
this.adopt(tracing);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ import type { Download } from '../download';
|
||||
import { createGuid } from '../../utils';
|
||||
import type { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
|
||||
export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, BrowserContextDispatcher, PageDispatcher> implements channels.PageChannel {
|
||||
export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, BrowserContextDispatcher> implements channels.PageChannel {
|
||||
_type_EventTarget = true;
|
||||
_type_Page = true;
|
||||
private _page: Page;
|
||||
@ -66,7 +66,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
viewportSize: page.viewportSize() || undefined,
|
||||
isClosed: page.isClosed(),
|
||||
opener: PageDispatcher.fromNullable(parentScope, page.opener())
|
||||
}, true);
|
||||
});
|
||||
|
||||
this.adopt(mainFrame);
|
||||
|
||||
@ -75,22 +75,22 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
this._dispatchEvent('close');
|
||||
this._dispose();
|
||||
});
|
||||
this.addObjectListener(Page.Events.Console, message => 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<ArtifactDispatcher>(artifact) }));
|
||||
if (page._video)
|
||||
this._dispatchEvent('video', { artifact: existingDispatcher<ArtifactDispatcher>(page._video) });
|
||||
@ -114,7 +114,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
|
||||
async exposeBinding(params: channels.PageExposeBindingParams, metadata: CallMetadata): Promise<void> {
|
||||
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<Page, channels.PageChannel, Brows
|
||||
return;
|
||||
}
|
||||
await this._page.setClientRequestInterceptor((route, request) => {
|
||||
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<Page, channels.PageChannel, Brows
|
||||
}
|
||||
|
||||
_onFrameAttached(frame: Frame) {
|
||||
this._dispatchEvent('frameAttached', { frame: FrameDispatcher.from(this._scope, frame) });
|
||||
this._dispatchEvent('frameAttached', { frame: FrameDispatcher.from(this, frame) });
|
||||
}
|
||||
|
||||
_onFrameDetached(frame: Frame) {
|
||||
@ -296,7 +296,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||
}
|
||||
|
||||
|
||||
export class WorkerDispatcher extends Dispatcher<Worker, channels.WorkerChannel, PageDispatcher | BrowserContextDispatcher, WorkerDispatcher> implements channels.WorkerChannel {
|
||||
export class WorkerDispatcher extends Dispatcher<Worker, channels.WorkerChannel, PageDispatcher | BrowserContextDispatcher> 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<Worker, channels.WorkerChannel,
|
||||
constructor(scope: PageDispatcher | BrowserContextDispatcher, worker: Worker) {
|
||||
super(scope, worker, 'Worker', {
|
||||
url: worker.url()
|
||||
}, true);
|
||||
});
|
||||
this.addObjectListener(Worker.Events.Close, () => this._dispatchEvent('close'));
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ export class WorkerDispatcher extends Dispatcher<Worker, channels.WorkerChannel,
|
||||
}
|
||||
|
||||
async evaluateExpressionHandle(params: channels.WorkerEvaluateExpressionHandleParams, metadata: CallMetadata): Promise<channels.WorkerEvaluateExpressionHandleResult> {
|
||||
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))) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -52,14 +52,14 @@ export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.Playwr
|
||||
selectors: new SelectorsDispatcher(scope, browserDispatcher?.selectors || playwright.selectors),
|
||||
preLaunchedBrowser: browserDispatcher,
|
||||
socksSupport: socksProxy ? new SocksSupportDispatcher(scope, socksProxy) : undefined,
|
||||
}, false);
|
||||
});
|
||||
this._type_Playwright = true;
|
||||
this._browserDispatcher = browserDispatcher;
|
||||
}
|
||||
|
||||
async newRequest(params: channels.PlaywrightNewRequestParams, metadata?: channels.Metadata): Promise<channels.PlaywrightNewRequestResult> {
|
||||
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<channels.PlaywrightHideHighlightResult> {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -30,7 +30,7 @@ export class TracingDispatcher extends Dispatcher<Tracing, channels.TracingChann
|
||||
}
|
||||
|
||||
constructor(scope: BrowserContextDispatcher | APIRequestContextDispatcher, tracing: Tracing) {
|
||||
super(scope, tracing, 'Tracing', {}, true);
|
||||
super(scope, tracing, 'Tracing', {});
|
||||
}
|
||||
|
||||
async tracingStart(params: channels.TracingTracingStartParams): Promise<channels.TracingTracingStartResult> {
|
||||
@ -43,7 +43,7 @@ export class TracingDispatcher extends Dispatcher<Tracing, channels.TracingChann
|
||||
|
||||
async tracingStopChunk(params: channels.TracingTracingStopChunkParams): Promise<channels.TracingTracingStopChunkResult> {
|
||||
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<channels.TracingTracingStopResult> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user