Skip to content

Commit 65002a0

Browse files
authored
feat(rpc): support firefox user prefs (#3093)
Also ignore firefoxUserPrefs in launchPersistentContext according to our api.
1 parent 80c0711 commit 65002a0

File tree

7 files changed

+32
-15
lines changed

7 files changed

+32
-15
lines changed

src/rpc/channels.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ export type BrowserTypeLaunchParams = {
170170
password?: string,
171171
},
172172
downloadsPath?: string,
173+
firefoxUserPrefs?: SerializedValue,
173174
slowMo?: number,
174175
};
175176
export type BrowserTypeLaunchResult = {
@@ -197,6 +198,7 @@ export type BrowserTypeLaunchServerParams = {
197198
password?: string,
198199
},
199200
downloadsPath?: string,
201+
firefoxUserPrefs?: SerializedValue,
200202
port?: number,
201203
};
202204
export type BrowserTypeLaunchServerResult = {

src/rpc/client/browserType.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { ChannelOwner } from './channelOwner';
2222
import { BrowserServer } from './browserServer';
2323
import { LoggerSink } from '../../loggerSink';
2424
import { headersObjectToArray, envObjectToArray } from '../serializers';
25+
import { serializeArgument } from './jsHandle';
26+
27+
type FirefoxPrefsOptions = { firefoxUserPrefs?: { [key: string]: string | number | boolean } };
2528

2629
export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeInitializer> {
2730

@@ -41,7 +44,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
4144
return this._initializer.name;
4245
}
4346

44-
async launch(options: types.LaunchOptions & { logger?: LoggerSink } = {}): Promise<Browser> {
47+
async launch(options: types.LaunchOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise<Browser> {
4548
const logger = options.logger;
4649
options = { ...options, logger: undefined };
4750
return this._wrapApiCall('browserType.launch', async () => {
@@ -50,14 +53,15 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
5053
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
5154
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
5255
env: options.env ? envObjectToArray(options.env) : undefined,
56+
firefoxUserPrefs: options.firefoxUserPrefs ? serializeArgument(options.firefoxUserPrefs).value : undefined,
5357
};
5458
const browser = Browser.from((await this._channel.launch(launchOptions)).browser);
5559
browser._logger = logger;
5660
return browser;
5761
}, logger);
5862
}
5963

60-
async launchServer(options: types.LaunchServerOptions & { logger?: LoggerSink } = {}): Promise<BrowserServer> {
64+
async launchServer(options: types.LaunchServerOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise<BrowserServer> {
6165
const logger = options.logger;
6266
options = { ...options, logger: undefined };
6367
return this._wrapApiCall('browserType.launchServer', async () => {
@@ -66,6 +70,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
6670
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
6771
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
6872
env: options.env ? envObjectToArray(options.env) : undefined,
73+
firefoxUserPrefs: options.firefoxUserPrefs ? serializeArgument(options.firefoxUserPrefs).value : undefined,
6974
};
7075
return BrowserServer.from((await this._channel.launchServer(launchServerOptions)).server);
7176
}, logger);

src/rpc/protocol.pdl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ interface BrowserType
151151
username?: string
152152
password?: string
153153
downloadsPath?: string
154+
firefoxUserPrefs?: SerializedValue
154155
slowMo?: number
155156
returns
156157
browser: Browser
@@ -176,6 +177,7 @@ interface BrowserType
176177
username?: string
177178
password?: string
178179
downloadsPath?: string
180+
firefoxUserPrefs?: SerializedValue
179181
port?: number
180182
returns
181183
server: BrowserServer

src/rpc/server/browserTypeDispatcher.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { BrowserContextBase } from '../../browserContext';
2424
import { BrowserContextDispatcher } from './browserContextDispatcher';
2525
import { BrowserServerDispatcher } from './browserServerDispatcher';
2626
import { headersArrayToObject, envArrayToObject } from '../serializers';
27+
import { parseValue } from './jsHandleDispatcher';
2728

2829
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeInitializer> implements BrowserTypeChannel {
2930
constructor(scope: DispatcherScope, browserType: BrowserTypeBase) {
@@ -38,6 +39,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
3839
...params,
3940
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
4041
env: params.env ? envArrayToObject(params.env) : undefined,
42+
firefoxUserPrefs: params.firefoxUserPrefs ? parseValue(params.firefoxUserPrefs) : undefined,
4143
};
4244
const browser = await this._object.launch(options);
4345
return { browser: new BrowserDispatcher(this._scope, browser as BrowserBase) };
@@ -59,6 +61,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
5961
const options = {
6062
...params,
6163
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
64+
firefoxUserPrefs: params.firefoxUserPrefs ? parseValue(params.firefoxUserPrefs) : undefined,
6265
env: params.env ? envArrayToObject(params.env) : undefined,
6366
};
6467
return { server: new BrowserServerDispatcher(this._scope, await this._object.launchServer(options)) };

src/rpc/server/cdpSessionDispatcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import { CRSession, CRSessionEvents } from '../../chromium/crConnection';
1818
import { CDPSessionChannel, CDPSessionInitializer, SerializedValue } from '../channels';
1919
import { Dispatcher, DispatcherScope } from './dispatcher';
20-
import { serializeResult, parseArgument } from './jsHandleDispatcher';
20+
import { serializeResult, parseValue } from './jsHandleDispatcher';
2121

2222
export class CDPSessionDispatcher extends Dispatcher<CRSession, CDPSessionInitializer> implements CDPSessionChannel {
2323
constructor(scope: DispatcherScope, crSession: CRSession) {
@@ -33,7 +33,7 @@ export class CDPSessionDispatcher extends Dispatcher<CRSession, CDPSessionInitia
3333
}
3434

3535
async send(params: { method: string, params?: SerializedValue }): Promise<{ result: SerializedValue }> {
36-
const cdpParams = params.params ? parseArgument({ value: params.params, handles: [] }) : undefined;
36+
const cdpParams = params.params ? parseValue(params.params) : undefined;
3737
return { result: serializeResult(await this._object.send(params.method as any, cdpParams)) };
3838
}
3939

src/rpc/server/jsHandleDispatcher.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, JSHandleInitiali
6565
export function parseArgument(arg: SerializedArgument): any {
6666
return parseSerializedValue(arg.value, arg.handles.map(a => (a as JSHandleDispatcher)._object));
6767
}
68+
export function parseValue(v: SerializedValue): any {
69+
return parseSerializedValue(v, []);
70+
}
6871

6972
export function serializeResult(arg: any): SerializedValue {
7073
return serializeValue(arg, value => ({ fallThrough: value }), new Set());

src/server/firefox.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,28 @@ export class Firefox extends BrowserTypeBase {
7373
throw new Error('Pass userDataDir parameter instead of specifying -profile argument');
7474
if (args.find(arg => arg.startsWith('-juggler')))
7575
throw new Error('Use the port parameter instead of -juggler argument');
76+
let firefoxUserPrefs = isPersistent ? undefined : options.firefoxUserPrefs;
7677
if (proxy) {
77-
options.firefoxUserPrefs = options.firefoxUserPrefs || {};
78-
options.firefoxUserPrefs['network.proxy.type'] = 1;
78+
// TODO: we should support proxy in persistent context without overriding user prefs.
79+
firefoxUserPrefs = firefoxUserPrefs || {};
80+
firefoxUserPrefs['network.proxy.type'] = 1;
7981
const proxyServer = new URL(proxy.server);
8082
const isSocks = proxyServer.protocol === 'socks5:';
8183
if (isSocks) {
82-
options.firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname;
83-
options.firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10);
84+
firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname;
85+
firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10);
8486
} else {
85-
options.firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname;
86-
options.firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10);
87-
options.firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname;
88-
options.firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10);
87+
firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname;
88+
firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10);
89+
firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname;
90+
firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10);
8991
}
9092
if (proxy.bypass)
91-
options.firefoxUserPrefs['network.proxy.no_proxies_on'] = proxy.bypass;
93+
firefoxUserPrefs['network.proxy.no_proxies_on'] = proxy.bypass;
9294
}
93-
if (options.firefoxUserPrefs) {
95+
if (firefoxUserPrefs) {
9496
const lines: string[] = [];
95-
for (const [name, value] of Object.entries(options.firefoxUserPrefs))
97+
for (const [name, value] of Object.entries(firefoxUserPrefs))
9698
lines.push(`user_pref(${JSON.stringify(name)}, ${JSON.stringify(value)});`);
9799
fs.writeFileSync(path.join(userDataDir, 'user.js'), lines.join('\n'));
98100
}

0 commit comments

Comments
 (0)