mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-04 16:44:11 +03:00
chore(rpc): move classes around, fix tests, respect dispatcher scopes (#2784)
This commit is contained in:
parent
87516cb3a3
commit
95538e73e7
@ -55,7 +55,6 @@ export interface BrowserChannel extends Channel {
|
||||
|
||||
close(): Promise<void>;
|
||||
newContext(params: { options?: types.BrowserContextOptions }): Promise<BrowserContextChannel>;
|
||||
newPage(params: { options?: types.BrowserContextOptions }): Promise<PageChannel>;
|
||||
}
|
||||
export type BrowserInitializer = {};
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import * as childProcess from 'child_process';
|
||||
import * as path from 'path';
|
||||
import { Connection } from './connection';
|
||||
import { Connection } from './client/connection';
|
||||
import { Transport } from './transport';
|
||||
|
||||
(async () => {
|
||||
@ -24,7 +24,7 @@ import { Transport } from './transport';
|
||||
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
||||
const connection = new Connection();
|
||||
connection.onmessage = message => transport.send(message);
|
||||
transport.onmessage = message => connection.send(message);
|
||||
transport.onmessage = message => connection.dispatch(message);
|
||||
|
||||
const chromium = await connection.waitForObjectWithKnownName('chromium');
|
||||
const browser = await chromium.launch({ headless: false });
|
||||
|
@ -19,12 +19,13 @@ import { BrowserChannel, BrowserInitializer } from '../channels';
|
||||
import { BrowserContext } from './browserContext';
|
||||
import { Page } from './page';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { Events } from '../../events';
|
||||
|
||||
export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||
readonly _contexts = new Set<BrowserContext>();
|
||||
private _isConnected = true;
|
||||
private _isClosedOrClosing = false;
|
||||
|
||||
|
||||
static from(browser: BrowserChannel): Browser {
|
||||
@ -40,6 +41,7 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||
channel.on('close', () => {
|
||||
this._isConnected = false;
|
||||
this.emit(Events.Browser.Disconnected);
|
||||
this._isClosedOrClosing = true;
|
||||
});
|
||||
}
|
||||
|
||||
@ -69,6 +71,9 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
if (this._isClosedOrClosing)
|
||||
return;
|
||||
this._isClosedOrClosing = true;
|
||||
await this._channel.close();
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import { BrowserContextChannel, BrowserContextInitializer } from '../channels';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { helper } from '../../helper';
|
||||
import { Browser } from './browser';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { Events } from '../../events';
|
||||
import { TimeoutSettings } from '../../timeoutSettings';
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { ChildProcess } from 'child_process';
|
||||
import { BrowserServerChannel, BrowserServerInitializer } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Events } from '../../events';
|
||||
|
||||
|
@ -19,7 +19,7 @@ import { BrowserTypeChannel, BrowserTypeInitializer } from '../channels';
|
||||
import { Browser } from './browser';
|
||||
import { BrowserContext } from './browserContext';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { BrowserServer } from './browserServer';
|
||||
|
||||
export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeInitializer> {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { Channel } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
|
||||
export abstract class ChannelOwner<T extends Channel, Initializer> extends EventEmitter {
|
||||
readonly _channel: T;
|
||||
|
@ -15,23 +15,23 @@
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'ws';
|
||||
import { Browser } from './client/browser';
|
||||
import { BrowserContext } from './client/browserContext';
|
||||
import { BrowserType } from './client/browserType';
|
||||
import { ChannelOwner } from './client/channelOwner';
|
||||
import { ElementHandle } from './client/elementHandle';
|
||||
import { Frame } from './client/frame';
|
||||
import { JSHandle } from './client/jsHandle';
|
||||
import { Request, Response, Route } from './client/network';
|
||||
import { Page, BindingCall } from './client/page';
|
||||
import { Worker } from './client/worker';
|
||||
import { Browser } from './browser';
|
||||
import { BrowserContext } from './browserContext';
|
||||
import { BrowserType } from './browserType';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { ElementHandle } from './elementHandle';
|
||||
import { Frame } from './frame';
|
||||
import { JSHandle } from './jsHandle';
|
||||
import { Request, Response, Route } from './network';
|
||||
import { Page, BindingCall } from './page';
|
||||
import { Worker } from './worker';
|
||||
import debug = require('debug');
|
||||
import { Channel } from './channels';
|
||||
import { ConsoleMessage } from './client/consoleMessage';
|
||||
import { Dialog } from './client/dialog';
|
||||
import { Download } from './client/download';
|
||||
import { parseError } from './serializers';
|
||||
import { BrowserServer } from './client/browserServer';
|
||||
import { Channel } from '../channels';
|
||||
import { ConsoleMessage } from './consoleMessage';
|
||||
import { Dialog } from './dialog';
|
||||
import { Download } from './download';
|
||||
import { parseError } from '../serializers';
|
||||
import { BrowserServer } from './browserServer';
|
||||
|
||||
export class Connection {
|
||||
private _channels = new Map<string, Channel>();
|
||||
@ -122,7 +122,7 @@ export class Connection {
|
||||
return new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject }));
|
||||
}
|
||||
|
||||
send(message: string) {
|
||||
dispatch(message: string) {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
const { id, guid, method, params, result, error } = parsedMessage;
|
||||
if (id) {
|
@ -19,7 +19,7 @@ import { ConsoleMessageLocation } from '../../types';
|
||||
import { JSHandle } from './jsHandle';
|
||||
import { ConsoleMessageChannel, ConsoleMessageInitializer } from '../channels';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
|
||||
export class ConsoleMessage extends ChannelOwner<ConsoleMessageChannel, ConsoleMessageInitializer> {
|
||||
static from(request: ConsoleMessageChannel): ConsoleMessage {
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { DialogChannel, DialogInitializer } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
|
||||
export class Dialog extends ChannelOwner<DialogChannel, DialogInitializer> {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { DownloadChannel, DownloadInitializer } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
|
@ -18,7 +18,7 @@ import * as types from '../../types';
|
||||
import { ElementHandleChannel, JSHandleInitializer } from '../channels';
|
||||
import { Frame } from './frame';
|
||||
import { FuncOn, JSHandle, serializeArgument, parseResult } from './jsHandle';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
|
||||
export class ElementHandle<T extends Node = Node> extends JSHandle<T> {
|
||||
readonly _elementChannel: ElementHandleChannel;
|
||||
|
@ -25,7 +25,7 @@ import { JSHandle, Func1, FuncOn, SmartHandle, serializeArgument, parseResult }
|
||||
import * as network from './network';
|
||||
import { Response } from './network';
|
||||
import { Page } from './page';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { normalizeFilePayloads } from '../serializers';
|
||||
|
||||
export type GotoOptions = types.NavigateOptions & {
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { JSHandleChannel, JSHandleInitializer } from '../channels';
|
||||
import { ElementHandle } from './elementHandle';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { serializeAsCallArgument, parseEvaluationResultValue } from '../../common/utilityScriptSerializers';
|
||||
|
||||
type NoHandles<Arg> = Arg extends JSHandle ? never : (Arg extends object ? { [Key in keyof Arg]: NoHandles<Arg[Key]> } : Arg);
|
||||
|
@ -19,7 +19,7 @@ import * as types from '../../types';
|
||||
import { RequestChannel, ResponseChannel, RouteChannel, RequestInitializer, ResponseInitializer, RouteInitializer } from '../channels';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Frame } from './frame';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { normalizeFulfillParameters } from '../serializers';
|
||||
|
||||
export type NetworkCookie = {
|
||||
|
@ -22,7 +22,7 @@ import { assert, assertMaxArguments, helper, Listener } from '../../helper';
|
||||
import { TimeoutSettings } from '../../timeoutSettings';
|
||||
import * as types from '../../types';
|
||||
import { BindingCallChannel, BindingCallInitializer, Channel, PageChannel, PageInitializer } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { parseError, serializeError } from '../serializers';
|
||||
import { Accessibility } from './accessibility';
|
||||
import { BrowserContext } from './browserContext';
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Events } from '../../events';
|
||||
import { assertMaxArguments } from '../../helper';
|
||||
import { WorkerChannel, WorkerInitializer } from '../channels';
|
||||
import { Connection } from '../connection';
|
||||
import { Connection } from './connection';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { Func1, JSHandle, parseResult, serializeArgument, SmartHandle } from './jsHandle';
|
||||
import { Page } from './page';
|
||||
|
@ -15,15 +15,16 @@
|
||||
*/
|
||||
|
||||
import { Transport } from './transport';
|
||||
import { DispatcherScope } from './dispatcher';
|
||||
import { DispatcherConnection } from './server/dispatcher';
|
||||
import { Playwright } from '../server/playwright';
|
||||
import { BrowserTypeDispatcher } from './server/browserTypeDispatcher';
|
||||
|
||||
const dispatcherScope = new DispatcherScope();
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
const transport = new Transport(process.stdout, process.stdin);
|
||||
transport.onmessage = message => dispatcherScope.send(message);
|
||||
dispatcherScope.onmessage = message => transport.send(message);
|
||||
transport.onmessage = message => dispatcherConnection.dispatch(message);
|
||||
dispatcherConnection.onmessage = message => transport.send(message);
|
||||
|
||||
const dispatcherScope = dispatcherConnection.createScope();
|
||||
const playwright = new Playwright(__dirname, require('../../browsers.json')['browsers']);
|
||||
new BrowserTypeDispatcher(dispatcherScope, playwright.chromium!);
|
||||
new BrowserTypeDispatcher(dispatcherScope, playwright.firefox!);
|
||||
|
@ -17,7 +17,7 @@
|
||||
import * as types from '../../types';
|
||||
import { BrowserContextBase, BrowserContext } from '../../browserContext';
|
||||
import { Events } from '../../events';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, lookupDispatcher } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, lookupDispatcher } from './dispatcher';
|
||||
import { PageDispatcher, BindingCallDispatcher } from './pageDispatcher';
|
||||
import { PageChannel, BrowserContextChannel, BrowserContextInitializer } from '../channels';
|
||||
import { RouteDispatcher, RequestDispatcher } from './networkDispatchers';
|
||||
@ -34,6 +34,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, Browser
|
||||
context.on(Events.BrowserContext.Page, page => this._dispatchEvent('page', PageDispatcher.from(this._scope, page)));
|
||||
context.on(Events.BrowserContext.Close, () => {
|
||||
this._dispatchEvent('close');
|
||||
scope.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -14,27 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BrowserBase, Browser } from '../../browser';
|
||||
import { Browser, BrowserBase } from '../../browser';
|
||||
import { BrowserContextBase } from '../../browserContext';
|
||||
import * as types from '../../types';
|
||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
import { BrowserChannel, BrowserContextChannel, PageChannel, BrowserInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope, lookupDispatcher } from '../dispatcher';
|
||||
import { PageDispatcher } from './pageDispatcher';
|
||||
import { Events } from '../../events';
|
||||
import * as types from '../../types';
|
||||
import { BrowserChannel, BrowserContextChannel, BrowserInitializer } from '../channels';
|
||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
|
||||
export class BrowserDispatcher extends Dispatcher<Browser, BrowserInitializer> implements BrowserChannel {
|
||||
constructor(scope: DispatcherScope, browser: BrowserBase) {
|
||||
super(scope, browser, 'browser', {});
|
||||
browser.on(Events.Browser.Disconnected, () => this._dispatchEvent('close'));
|
||||
browser.on(Events.Browser.Disconnected, () => {
|
||||
this._dispatchEvent('close');
|
||||
scope.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
async newContext(params: { options?: types.BrowserContextOptions }): Promise<BrowserContextChannel> {
|
||||
return new BrowserContextDispatcher(this._scope, await this._object.newContext(params.options) as BrowserContextBase);
|
||||
}
|
||||
|
||||
async newPage(params: { options?: types.BrowserContextOptions }): Promise<PageChannel> {
|
||||
return lookupDispatcher<PageDispatcher>(await this._object.newPage(params.options))!;
|
||||
return new BrowserContextDispatcher(this._scope.createChild(), await this._object.newContext(params.options) as BrowserContextBase);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { BrowserServer } from '../../server/browserServer';
|
||||
import { BrowserServerChannel, BrowserServerInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
import { Events } from '../../events';
|
||||
|
||||
export class BrowserServerDispatcher extends Dispatcher<BrowserServer, BrowserServerInitializer> implements BrowserServerChannel {
|
||||
|
@ -19,7 +19,7 @@ import { BrowserTypeBase, BrowserType } from '../../server/browserType';
|
||||
import * as types from '../../types';
|
||||
import { BrowserDispatcher } from './browserDispatcher';
|
||||
import { BrowserChannel, BrowserTypeChannel, BrowserContextChannel, BrowserTypeInitializer, BrowserServerChannel } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
import { BrowserContextBase } from '../../browserContext';
|
||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||
import { BrowserServerDispatcher } from './browserServerDispatcher';
|
||||
@ -34,12 +34,12 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||
|
||||
async launch(params: { options?: types.LaunchOptions }): Promise<BrowserChannel> {
|
||||
const browser = await this._object.launch(params.options || undefined);
|
||||
return new BrowserDispatcher(this._scope, browser as BrowserBase);
|
||||
return new BrowserDispatcher(this._scope.createChild(), browser as BrowserBase);
|
||||
}
|
||||
|
||||
async launchPersistentContext(params: { userDataDir: string, options?: types.LaunchOptions & types.BrowserContextOptions }): Promise<BrowserContextChannel> {
|
||||
const browserContext = await this._object.launchPersistentContext(params.userDataDir, params.options);
|
||||
return new BrowserContextDispatcher(this._scope, browserContext as BrowserContextBase);
|
||||
return new BrowserContextDispatcher(this._scope.createChild(), browserContext as BrowserContextBase);
|
||||
}
|
||||
|
||||
async launchServer(params: { options?: types.LaunchServerOptions }): Promise<BrowserServerChannel> {
|
||||
@ -48,6 +48,6 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||
|
||||
async connect(params: { options: types.ConnectOptions }): Promise<BrowserChannel> {
|
||||
const browser = await this._object.connect(params.options);
|
||||
return new BrowserDispatcher(this._scope, browser as BrowserBase);
|
||||
return new BrowserDispatcher(this._scope.createChild(), browser as BrowserBase);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { ConsoleMessage } from '../../console';
|
||||
import { ConsoleMessageChannel, ConsoleMessageInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
import { createHandle } from './elementHandlerDispatcher';
|
||||
|
||||
export class ConsoleMessageDispatcher extends Dispatcher<ConsoleMessage, ConsoleMessageInitializer> implements ConsoleMessageChannel {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { Dialog } from '../../dialog';
|
||||
import { DialogChannel, DialogInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
|
||||
export class DialogDispatcher extends Dispatcher<Dialog, DialogInitializer> implements DialogChannel {
|
||||
constructor(scope: DispatcherScope, dialog: Dialog) {
|
||||
|
@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { helper, debugAssert } from '../helper';
|
||||
import { Channel } from './channels';
|
||||
import { serializeError } from './serializers';
|
||||
import { helper, debugAssert } from '../../helper';
|
||||
import { Channel } from '../channels';
|
||||
import { serializeError } from '../serializers';
|
||||
|
||||
export const dispatcherSymbol = Symbol('dispatcher');
|
||||
|
||||
@ -47,7 +47,7 @@ export class Dispatcher<Type, Initializer> extends EventEmitter implements Chann
|
||||
this._guid = guid;
|
||||
this._object = object;
|
||||
this._scope = scope;
|
||||
scope.dispatchers.set(this._guid, this);
|
||||
scope.bind(this._guid, this);
|
||||
(object as any)[dispatcherSymbol] = this;
|
||||
this._scope.sendMessageToClient(this._guid, '__create__', { type, initializer });
|
||||
}
|
||||
@ -58,17 +58,62 @@ export class Dispatcher<Type, Initializer> extends EventEmitter implements Chann
|
||||
}
|
||||
|
||||
export class DispatcherScope {
|
||||
readonly dispatchers = new Map<string, Dispatcher<any, any>>();
|
||||
onmessage = (message: string) => {};
|
||||
private _connection: DispatcherConnection;
|
||||
private _dispatchers = new Map<string, Dispatcher<any, any>>();
|
||||
private _parent: DispatcherScope | undefined;
|
||||
private _childScopes = new Set<DispatcherScope>();
|
||||
|
||||
constructor(connection: DispatcherConnection, parent?: DispatcherScope) {
|
||||
this._connection = connection;
|
||||
this._parent = parent;
|
||||
if (parent)
|
||||
parent._childScopes.add(this);
|
||||
}
|
||||
|
||||
createChild(): DispatcherScope {
|
||||
return new DispatcherScope(this._connection, this);
|
||||
}
|
||||
|
||||
bind(guid: string, arg: Dispatcher<any, any>) {
|
||||
this._dispatchers.set(guid, arg);
|
||||
this._connection._dispatchers.set(guid, arg);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
for (const child of [...this._childScopes])
|
||||
child.dispose();
|
||||
this._childScopes.clear();
|
||||
for (const guid of this._dispatchers.keys())
|
||||
this._connection._dispatchers.delete(guid);
|
||||
if (this._parent)
|
||||
this._parent._childScopes.delete(this);
|
||||
}
|
||||
|
||||
async sendMessageToClient(guid: string, method: string, params: any): Promise<any> {
|
||||
this._connection._sendMessageToClient(guid, method, params);
|
||||
}
|
||||
}
|
||||
|
||||
export class DispatcherConnection {
|
||||
readonly _dispatchers = new Map<string, Dispatcher<any, any>>();
|
||||
onmessage = (message: string) => {};
|
||||
|
||||
async _sendMessageToClient(guid: string, method: string, params: any): Promise<any> {
|
||||
this.onmessage(JSON.stringify({ guid, method, params: this._replaceDispatchersWithGuids(params) }));
|
||||
}
|
||||
|
||||
async send(message: string) {
|
||||
createScope(): DispatcherScope {
|
||||
return new DispatcherScope(this);
|
||||
}
|
||||
|
||||
async dispatch(message: string) {
|
||||
const parsedMessage = JSON.parse(message);
|
||||
const { id, guid, method, params } = parsedMessage;
|
||||
const dispatcher = this.dispatchers.get(guid)!;
|
||||
const dispatcher = this._dispatchers.get(guid);
|
||||
if (!dispatcher) {
|
||||
this.onmessage(JSON.stringify({ id, error: serializeError(new Error('Target browser or context has been closed')) }));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = await (dispatcher as any)[method](this._replaceGuidsWithDispatchers(params));
|
||||
this.onmessage(JSON.stringify({ id, result: this._replaceDispatchersWithGuids(result) }));
|
||||
@ -101,8 +146,8 @@ export class DispatcherScope {
|
||||
return payload;
|
||||
if (Array.isArray(payload))
|
||||
return payload.map(p => this._replaceGuidsWithDispatchers(p));
|
||||
if (payload.guid && this.dispatchers.has(payload.guid))
|
||||
return this.dispatchers.get(payload.guid);
|
||||
if (payload.guid && this._dispatchers.has(payload.guid))
|
||||
return this._dispatchers.get(payload.guid);
|
||||
// TODO: send base64
|
||||
if (payload instanceof Buffer)
|
||||
return payload;
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { Download } from '../../download';
|
||||
import { DownloadChannel, DownloadInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
|
||||
export class DownloadDispatcher extends Dispatcher<Download, DownloadInitializer> implements DownloadChannel {
|
||||
constructor(scope: DispatcherScope, download: Download) {
|
||||
|
@ -18,7 +18,7 @@ import { ElementHandle } from '../../dom';
|
||||
import * as js from '../../javascript';
|
||||
import * as types from '../../types';
|
||||
import { ElementHandleChannel, FrameChannel } from '../channels';
|
||||
import { DispatcherScope, lookupNullableDispatcher } from '../dispatcher';
|
||||
import { DispatcherScope, lookupNullableDispatcher } from './dispatcher';
|
||||
import { JSHandleDispatcher, serializeResult, parseArgument } from './jsHandleDispatcher';
|
||||
import { FrameDispatcher } from './frameDispatcher';
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Frame } from '../../frames';
|
||||
import * as types from '../../types';
|
||||
import { ElementHandleChannel, FrameChannel, FrameInitializer, JSHandleChannel, ResponseChannel } from '../channels';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, existingDispatcher } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, existingDispatcher } from './dispatcher';
|
||||
import { convertSelectOptionValues, ElementHandleDispatcher, createHandle } from './elementHandlerDispatcher';
|
||||
import { parseArgument, serializeResult } from './jsHandleDispatcher';
|
||||
import { ResponseDispatcher } from './networkDispatchers';
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import * as js from '../../javascript';
|
||||
import { JSHandleChannel, JSHandleInitializer } from '../channels';
|
||||
import { Dispatcher, DispatcherScope } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||
import { parseEvaluationResultValue, serializeAsCallArgument } from '../../common/utilityScriptSerializers';
|
||||
import { createHandle } from './elementHandlerDispatcher';
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Request, Response, Route } from '../../network';
|
||||
import * as types from '../../types';
|
||||
import { RequestChannel, ResponseChannel, RouteChannel, ResponseInitializer, RequestInitializer, RouteInitializer, Binary } from '../channels';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, existingDispatcher } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope, lookupNullableDispatcher, existingDispatcher } from './dispatcher';
|
||||
import { FrameDispatcher } from './frameDispatcher';
|
||||
|
||||
export class RequestDispatcher extends Dispatcher<Request, RequestInitializer> implements RequestChannel {
|
||||
|
@ -21,7 +21,7 @@ import { Request } from '../../network';
|
||||
import { Page, Worker } from '../../page';
|
||||
import * as types from '../../types';
|
||||
import { BindingCallChannel, BindingCallInitializer, ElementHandleChannel, PageChannel, PageInitializer, ResponseChannel, WorkerInitializer, WorkerChannel, JSHandleChannel, Binary } from '../channels';
|
||||
import { Dispatcher, DispatcherScope, lookupDispatcher, lookupNullableDispatcher, existingDispatcher } from '../dispatcher';
|
||||
import { Dispatcher, DispatcherScope, lookupDispatcher, lookupNullableDispatcher, existingDispatcher } from './dispatcher';
|
||||
import { parseError, serializeError } from '../serializers';
|
||||
import { ConsoleMessageDispatcher } from './consoleMessageDispatcher';
|
||||
import { DialogDispatcher } from './dialogDispatcher';
|
||||
|
@ -20,8 +20,8 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const rm = require('rimraf').sync;
|
||||
const {TestServer} = require('../utils/testserver/');
|
||||
const { DispatcherScope } = require('../lib/rpc/dispatcher');
|
||||
const { Connection } = require('../lib/rpc/connection');
|
||||
const { DispatcherConnection } = require('../lib/rpc/server/dispatcher');
|
||||
const { Connection } = require('../lib/rpc/client/connection');
|
||||
const { BrowserTypeDispatcher } = require('../lib/rpc/server/browserTypeDispatcher');
|
||||
|
||||
class ServerEnvironment {
|
||||
@ -172,17 +172,17 @@ class BrowserTypeEnvironment {
|
||||
// Channel substitute
|
||||
let overridenBrowserType = this._browserType;
|
||||
if (process.env.PWCHANNEL) {
|
||||
const dispatcherScope = new DispatcherScope();
|
||||
const dispatcherConnection = new DispatcherConnection();
|
||||
const connection = new Connection();
|
||||
dispatcherScope.onmessage = async message => {
|
||||
setImmediate(() => connection.send(message));
|
||||
dispatcherConnection.onmessage = async message => {
|
||||
setImmediate(() => connection.dispatch(message));
|
||||
};
|
||||
connection.onmessage = async message => {
|
||||
const result = await dispatcherScope.send(message);
|
||||
const result = await dispatcherConnection.dispatch(message);
|
||||
await new Promise(f => setImmediate(f));
|
||||
return result;
|
||||
};
|
||||
new BrowserTypeDispatcher(dispatcherScope, this._browserType);
|
||||
new BrowserTypeDispatcher(dispatcherConnection.createScope(), this._browserType);
|
||||
overridenBrowserType = await connection.waitForObjectWithKnownName(this._browserType.name());
|
||||
}
|
||||
state.browserType = overridenBrowserType;
|
||||
|
Loading…
Reference in New Issue
Block a user