feat(rpc): simplify browser name detection on the client side (#3670)

This commit is contained in:
Dmitry Gozman 2020-08-28 10:23:02 -07:00 committed by GitHub
parent eec92630df
commit 744af78dc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 25 deletions

View file

@ -22,7 +22,6 @@ import { Browser } from './server/browser';
import { ChildProcess } from 'child_process';
import { EventEmitter } from 'ws';
import { DispatcherScope, DispatcherConnection } from './dispatchers/dispatcher';
import { BrowserTypeDispatcher } from './dispatchers/browserTypeDispatcher';
import { BrowserDispatcher } from './dispatchers/browserDispatcher';
import { BrowserContextDispatcher } from './dispatchers/browserContextDispatcher';
import { BrowserNewContextParams, BrowserContextChannel } from './protocol/channels';
@ -106,8 +105,7 @@ export class BrowserServerImpl extends EventEmitter implements BrowserServer {
connection.dispatch(JSON.parse(Buffer.from(message).toString()));
});
socket.on('error', () => {});
const browserType = new BrowserTypeDispatcher(connection.rootDispatcher(), this._browserType);
const browser = new ConnectedBrowser(browserType._scope, this._browser);
const browser = new ConnectedBrowser(connection.rootDispatcher(), this._browser);
socket.on('close', () => {
// Avoid sending any more messages over closed socket.
connection.onmessage = () => {};

View file

@ -19,7 +19,6 @@ import { BrowserContext } from './browserContext';
import { Page } from './page';
import { ChannelOwner } from './channelOwner';
import { Events } from './events';
import { BrowserType } from './browserType';
import { BrowserContextOptions } from './types';
import { validateHeaders } from './network';
import { headersObjectToArray } from '../utils/utils';
@ -29,7 +28,6 @@ export class Browser extends ChannelOwner<channels.BrowserChannel, channels.Brow
private _isConnected = true;
private _isClosedOrClosing = false;
private _closedPromise: Promise<void>;
readonly _browserType: BrowserType;
_isRemote = false;
static from(browser: channels.BrowserChannel): Browser {
@ -42,7 +40,6 @@ export class Browser extends ChannelOwner<channels.BrowserChannel, channels.Brow
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.BrowserInitializer) {
super(parent, type, guid, initializer);
this._browserType = parent as BrowserType;
this._channel.on('close', () => this._didClose());
this._closedPromise = new Promise(f => this.once(Events.Browser.Disconnected, f));
}

View file

@ -132,33 +132,26 @@ export class Connection {
case 'BindingCall':
result = new BindingCall(parent, type, guid, initializer);
break;
case 'Browser':
if ((parent as BrowserType).name() === 'chromium')
case 'Browser': {
const browserName = (initializer as channels.BrowserInitializer).name;
if (browserName === 'chromium')
result = new ChromiumBrowser(parent, type, guid, initializer);
else if ((parent as BrowserType).name() === 'webkit')
else if (browserName === 'webkit')
result = new WebKitBrowser(parent, type, guid, initializer);
else if ((parent as BrowserType).name() === 'firefox')
else if (browserName === 'firefox')
result = new FirefoxBrowser(parent, type, guid, initializer);
else
result = new Browser(parent, type, guid, initializer);
break;
case 'BrowserContext':
let browserName = '';
if (parent instanceof ElectronApplication) {
// Launching electron produces ElectronApplication parent for BrowserContext.
browserName = 'electron';
} else if (parent instanceof Browser) {
// Launching a browser produces Browser parent for BrowserContext.
browserName = parent._browserType.name();
} else {
// Launching persistent context produces BrowserType parent for BrowserContext.
browserName = (parent as BrowserType).name();
}
}
case 'BrowserContext': {
const browserName = (initializer as channels.BrowserContextInitializer).browserName;
if (browserName === 'chromium')
result = new ChromiumBrowserContext(parent, type, guid, initializer);
else
result = new BrowserContext(parent, type, guid, initializer, browserName);
break;
}
case 'BrowserType':
result = new BrowserType(parent, type, guid, initializer);
break;

View file

@ -26,7 +26,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
private _context: BrowserContext;
constructor(scope: DispatcherScope, context: BrowserContext) {
super(scope, context, 'BrowserContext', {}, true);
super(scope, context, 'BrowserContext', { browserName: context._browser._options.name }, true);
this._context = context;
for (const page of context.pages())
@ -122,6 +122,8 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
}
async crNewCDPSession(params: channels.BrowserContextCrNewCDPSessionParams): Promise<channels.BrowserContextCrNewCDPSessionResult> {
if (this._object._browser._options.name !== 'chromium')
throw new Error(`CDP session is only available in Chromium`);
const crBrowserContext = this._object as CRBrowserContext;
return { session: new CDPSessionDispatcher(this._scope, await crBrowserContext.newCDPSession((params.page as PageDispatcher)._object)) };
}

View file

@ -24,7 +24,7 @@ import { PageDispatcher } from './pageDispatcher';
export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserInitializer> implements channels.BrowserChannel {
constructor(scope: DispatcherScope, browser: Browser, guid?: string) {
super(scope, browser, 'Browser', { version: browser.version() }, true, guid);
super(scope, browser, 'Browser', { version: browser.version(), name: browser._options.name }, true, guid);
browser.on(Browser.Events.Disconnected, () => this._didClose());
}
@ -42,16 +42,22 @@ export class BrowserDispatcher extends Dispatcher<Browser, channels.BrowserIniti
}
async crNewBrowserCDPSession(): Promise<channels.BrowserCrNewBrowserCDPSessionResult> {
if (this._object._options.name !== 'chromium')
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()) };
}
async crStartTracing(params: channels.BrowserCrStartTracingParams): Promise<void> {
if (this._object._options.name !== 'chromium')
throw new Error(`Tracing is only available in Chromium`);
const crBrowser = this._object as CRBrowser;
await crBrowser.startTracing(params.page ? (params.page as PageDispatcher)._object : undefined, params);
}
async crStopTracing(): Promise<channels.BrowserCrStopTracingResult> {
if (this._object._options.name !== 'chromium')
throw new Error(`Tracing is only available in Chromium`);
const crBrowser = this._object as CRBrowser;
const buffer = await crBrowser.stopTracing();
return { binary: buffer.toString('base64') };

View file

@ -319,6 +319,7 @@ export type BrowserTypeLaunchPersistentContextResult = {
// ----------- Browser -----------
export type BrowserInitializer = {
version: string,
name: string,
};
export interface BrowserChannel extends Channel {
on(event: 'close', callback: (params: BrowserCloseEvent) => void): this;
@ -426,7 +427,9 @@ export type BrowserCrStopTracingResult = {
};
// ----------- BrowserContext -----------
export type BrowserContextInitializer = {};
export type BrowserContextInitializer = {
browserName: string,
};
export interface BrowserContextChannel extends Channel {
on(event: 'bindingCall', callback: (params: BrowserContextBindingCallEvent) => void): this;
on(event: 'close', callback: (params: BrowserContextCloseEvent) => void): this;

View file

@ -300,6 +300,7 @@ Browser:
initializer:
version: string
name: string
commands:
@ -380,6 +381,9 @@ Browser:
BrowserContext:
type: interface
initializer:
browserName: string
commands:
addCookies: