From 65002a0ac28cc84496e679e56ce8a4ab6c751a26 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Wed, 22 Jul 2020 17:20:00 -0700 Subject: [PATCH] feat(rpc): support firefox user prefs (#3093) Also ignore firefoxUserPrefs in launchPersistentContext according to our api. --- src/rpc/channels.ts | 2 ++ src/rpc/client/browserType.ts | 9 +++++++-- src/rpc/protocol.pdl | 2 ++ src/rpc/server/browserTypeDispatcher.ts | 3 +++ src/rpc/server/cdpSessionDispatcher.ts | 4 ++-- src/rpc/server/jsHandleDispatcher.ts | 3 +++ src/server/firefox.ts | 24 +++++++++++++----------- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/rpc/channels.ts b/src/rpc/channels.ts index f71a9423f0..8f913c2bcf 100644 --- a/src/rpc/channels.ts +++ b/src/rpc/channels.ts @@ -170,6 +170,7 @@ export type BrowserTypeLaunchParams = { password?: string, }, downloadsPath?: string, + firefoxUserPrefs?: SerializedValue, slowMo?: number, }; export type BrowserTypeLaunchResult = { @@ -197,6 +198,7 @@ export type BrowserTypeLaunchServerParams = { password?: string, }, downloadsPath?: string, + firefoxUserPrefs?: SerializedValue, port?: number, }; export type BrowserTypeLaunchServerResult = { diff --git a/src/rpc/client/browserType.ts b/src/rpc/client/browserType.ts index b0d026be52..b75b08f034 100644 --- a/src/rpc/client/browserType.ts +++ b/src/rpc/client/browserType.ts @@ -22,6 +22,9 @@ import { ChannelOwner } from './channelOwner'; import { BrowserServer } from './browserServer'; import { LoggerSink } from '../../loggerSink'; import { headersObjectToArray, envObjectToArray } from '../serializers'; +import { serializeArgument } from './jsHandle'; + +type FirefoxPrefsOptions = { firefoxUserPrefs?: { [key: string]: string | number | boolean } }; export class BrowserType extends ChannelOwner { @@ -41,7 +44,7 @@ export class BrowserType extends ChannelOwner { + async launch(options: types.LaunchOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise { const logger = options.logger; options = { ...options, logger: undefined }; return this._wrapApiCall('browserType.launch', async () => { @@ -50,6 +53,7 @@ export class BrowserType extends ChannelOwner { + async launchServer(options: types.LaunchServerOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise { const logger = options.logger; options = { ...options, logger: undefined }; return this._wrapApiCall('browserType.launchServer', async () => { @@ -66,6 +70,7 @@ export class BrowserType extends ChannelOwner implements BrowserTypeChannel { constructor(scope: DispatcherScope, browserType: BrowserTypeBase) { @@ -38,6 +39,7 @@ export class BrowserTypeDispatcher extends Dispatcher implements CDPSessionChannel { constructor(scope: DispatcherScope, crSession: CRSession) { @@ -33,7 +33,7 @@ export class CDPSessionDispatcher extends Dispatcher { - const cdpParams = params.params ? parseArgument({ value: params.params, handles: [] }) : undefined; + const cdpParams = params.params ? parseValue(params.params) : undefined; return { result: serializeResult(await this._object.send(params.method as any, cdpParams)) }; } diff --git a/src/rpc/server/jsHandleDispatcher.ts b/src/rpc/server/jsHandleDispatcher.ts index 7cc67a529e..0b9c72cd47 100644 --- a/src/rpc/server/jsHandleDispatcher.ts +++ b/src/rpc/server/jsHandleDispatcher.ts @@ -65,6 +65,9 @@ export class JSHandleDispatcher extends Dispatcher (a as JSHandleDispatcher)._object)); } +export function parseValue(v: SerializedValue): any { + return parseSerializedValue(v, []); +} export function serializeResult(arg: any): SerializedValue { return serializeValue(arg, value => ({ fallThrough: value }), new Set()); diff --git a/src/server/firefox.ts b/src/server/firefox.ts index 89e1cf9eb4..8faf95bc1f 100644 --- a/src/server/firefox.ts +++ b/src/server/firefox.ts @@ -73,26 +73,28 @@ export class Firefox extends BrowserTypeBase { throw new Error('Pass userDataDir parameter instead of specifying -profile argument'); if (args.find(arg => arg.startsWith('-juggler'))) throw new Error('Use the port parameter instead of -juggler argument'); + let firefoxUserPrefs = isPersistent ? undefined : options.firefoxUserPrefs; if (proxy) { - options.firefoxUserPrefs = options.firefoxUserPrefs || {}; - options.firefoxUserPrefs['network.proxy.type'] = 1; + // TODO: we should support proxy in persistent context without overriding user prefs. + firefoxUserPrefs = firefoxUserPrefs || {}; + firefoxUserPrefs['network.proxy.type'] = 1; const proxyServer = new URL(proxy.server); const isSocks = proxyServer.protocol === 'socks5:'; if (isSocks) { - options.firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname; - options.firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10); + firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname; + firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10); } else { - options.firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname; - options.firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10); - options.firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname; - options.firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10); + firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname; + firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10); + firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname; + firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10); } if (proxy.bypass) - options.firefoxUserPrefs['network.proxy.no_proxies_on'] = proxy.bypass; + firefoxUserPrefs['network.proxy.no_proxies_on'] = proxy.bypass; } - if (options.firefoxUserPrefs) { + if (firefoxUserPrefs) { const lines: string[] = []; - for (const [name, value] of Object.entries(options.firefoxUserPrefs)) + for (const [name, value] of Object.entries(firefoxUserPrefs)) lines.push(`user_pref(${JSON.stringify(name)}, ${JSON.stringify(value)});`); fs.writeFileSync(path.join(userDataDir, 'user.js'), lines.join('\n')); }