feat(rpc): support firefox user prefs (#3093)
Also ignore firefoxUserPrefs in launchPersistentContext according to our api.
This commit is contained in:
parent
80c0711d98
commit
65002a0ac2
|
|
@ -170,6 +170,7 @@ export type BrowserTypeLaunchParams = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
|
firefoxUserPrefs?: SerializedValue,
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
};
|
};
|
||||||
export type BrowserTypeLaunchResult = {
|
export type BrowserTypeLaunchResult = {
|
||||||
|
|
@ -197,6 +198,7 @@ export type BrowserTypeLaunchServerParams = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
|
firefoxUserPrefs?: SerializedValue,
|
||||||
port?: number,
|
port?: number,
|
||||||
};
|
};
|
||||||
export type BrowserTypeLaunchServerResult = {
|
export type BrowserTypeLaunchServerResult = {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@ import { ChannelOwner } from './channelOwner';
|
||||||
import { BrowserServer } from './browserServer';
|
import { BrowserServer } from './browserServer';
|
||||||
import { LoggerSink } from '../../loggerSink';
|
import { LoggerSink } from '../../loggerSink';
|
||||||
import { headersObjectToArray, envObjectToArray } from '../serializers';
|
import { headersObjectToArray, envObjectToArray } from '../serializers';
|
||||||
|
import { serializeArgument } from './jsHandle';
|
||||||
|
|
||||||
|
type FirefoxPrefsOptions = { firefoxUserPrefs?: { [key: string]: string | number | boolean } };
|
||||||
|
|
||||||
export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeInitializer> {
|
export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeInitializer> {
|
||||||
|
|
||||||
|
|
@ -41,7 +44,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
||||||
return this._initializer.name;
|
return this._initializer.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(options: types.LaunchOptions & { logger?: LoggerSink } = {}): Promise<Browser> {
|
async launch(options: types.LaunchOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise<Browser> {
|
||||||
const logger = options.logger;
|
const logger = options.logger;
|
||||||
options = { ...options, logger: undefined };
|
options = { ...options, logger: undefined };
|
||||||
return this._wrapApiCall('browserType.launch', async () => {
|
return this._wrapApiCall('browserType.launch', async () => {
|
||||||
|
|
@ -50,6 +53,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
||||||
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
env: options.env ? envObjectToArray(options.env) : undefined,
|
env: options.env ? envObjectToArray(options.env) : undefined,
|
||||||
|
firefoxUserPrefs: options.firefoxUserPrefs ? serializeArgument(options.firefoxUserPrefs).value : undefined,
|
||||||
};
|
};
|
||||||
const browser = Browser.from((await this._channel.launch(launchOptions)).browser);
|
const browser = Browser.from((await this._channel.launch(launchOptions)).browser);
|
||||||
browser._logger = logger;
|
browser._logger = logger;
|
||||||
|
|
@ -57,7 +61,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
||||||
}, logger);
|
}, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer(options: types.LaunchServerOptions & { logger?: LoggerSink } = {}): Promise<BrowserServer> {
|
async launchServer(options: types.LaunchServerOptions & FirefoxPrefsOptions & { logger?: LoggerSink } = {}): Promise<BrowserServer> {
|
||||||
const logger = options.logger;
|
const logger = options.logger;
|
||||||
options = { ...options, logger: undefined };
|
options = { ...options, logger: undefined };
|
||||||
return this._wrapApiCall('browserType.launchServer', async () => {
|
return this._wrapApiCall('browserType.launchServer', async () => {
|
||||||
|
|
@ -66,6 +70,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
||||||
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
env: options.env ? envObjectToArray(options.env) : undefined,
|
env: options.env ? envObjectToArray(options.env) : undefined,
|
||||||
|
firefoxUserPrefs: options.firefoxUserPrefs ? serializeArgument(options.firefoxUserPrefs).value : undefined,
|
||||||
};
|
};
|
||||||
return BrowserServer.from((await this._channel.launchServer(launchServerOptions)).server);
|
return BrowserServer.from((await this._channel.launchServer(launchServerOptions)).server);
|
||||||
}, logger);
|
}, logger);
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ interface BrowserType
|
||||||
username?: string
|
username?: string
|
||||||
password?: string
|
password?: string
|
||||||
downloadsPath?: string
|
downloadsPath?: string
|
||||||
|
firefoxUserPrefs?: SerializedValue
|
||||||
slowMo?: number
|
slowMo?: number
|
||||||
returns
|
returns
|
||||||
browser: Browser
|
browser: Browser
|
||||||
|
|
@ -176,6 +177,7 @@ interface BrowserType
|
||||||
username?: string
|
username?: string
|
||||||
password?: string
|
password?: string
|
||||||
downloadsPath?: string
|
downloadsPath?: string
|
||||||
|
firefoxUserPrefs?: SerializedValue
|
||||||
port?: number
|
port?: number
|
||||||
returns
|
returns
|
||||||
server: BrowserServer
|
server: BrowserServer
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import { BrowserContextBase } from '../../browserContext';
|
||||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||||
import { BrowserServerDispatcher } from './browserServerDispatcher';
|
import { BrowserServerDispatcher } from './browserServerDispatcher';
|
||||||
import { headersArrayToObject, envArrayToObject } from '../serializers';
|
import { headersArrayToObject, envArrayToObject } from '../serializers';
|
||||||
|
import { parseValue } from './jsHandleDispatcher';
|
||||||
|
|
||||||
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeInitializer> implements BrowserTypeChannel {
|
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeInitializer> implements BrowserTypeChannel {
|
||||||
constructor(scope: DispatcherScope, browserType: BrowserTypeBase) {
|
constructor(scope: DispatcherScope, browserType: BrowserTypeBase) {
|
||||||
|
|
@ -38,6 +39,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||||
...params,
|
...params,
|
||||||
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
||||||
env: params.env ? envArrayToObject(params.env) : undefined,
|
env: params.env ? envArrayToObject(params.env) : undefined,
|
||||||
|
firefoxUserPrefs: params.firefoxUserPrefs ? parseValue(params.firefoxUserPrefs) : undefined,
|
||||||
};
|
};
|
||||||
const browser = await this._object.launch(options);
|
const browser = await this._object.launch(options);
|
||||||
return { browser: new BrowserDispatcher(this._scope, browser as BrowserBase) };
|
return { browser: new BrowserDispatcher(this._scope, browser as BrowserBase) };
|
||||||
|
|
@ -59,6 +61,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||||
const options = {
|
const options = {
|
||||||
...params,
|
...params,
|
||||||
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
||||||
|
firefoxUserPrefs: params.firefoxUserPrefs ? parseValue(params.firefoxUserPrefs) : undefined,
|
||||||
env: params.env ? envArrayToObject(params.env) : undefined,
|
env: params.env ? envArrayToObject(params.env) : undefined,
|
||||||
};
|
};
|
||||||
return { server: new BrowserServerDispatcher(this._scope, await this._object.launchServer(options)) };
|
return { server: new BrowserServerDispatcher(this._scope, await this._object.launchServer(options)) };
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import { CRSession, CRSessionEvents } from '../../chromium/crConnection';
|
import { CRSession, CRSessionEvents } from '../../chromium/crConnection';
|
||||||
import { CDPSessionChannel, CDPSessionInitializer, SerializedValue } from '../channels';
|
import { CDPSessionChannel, CDPSessionInitializer, SerializedValue } from '../channels';
|
||||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||||
import { serializeResult, parseArgument } from './jsHandleDispatcher';
|
import { serializeResult, parseValue } from './jsHandleDispatcher';
|
||||||
|
|
||||||
export class CDPSessionDispatcher extends Dispatcher<CRSession, CDPSessionInitializer> implements CDPSessionChannel {
|
export class CDPSessionDispatcher extends Dispatcher<CRSession, CDPSessionInitializer> implements CDPSessionChannel {
|
||||||
constructor(scope: DispatcherScope, crSession: CRSession) {
|
constructor(scope: DispatcherScope, crSession: CRSession) {
|
||||||
|
|
@ -33,7 +33,7 @@ export class CDPSessionDispatcher extends Dispatcher<CRSession, CDPSessionInitia
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(params: { method: string, params?: SerializedValue }): Promise<{ result: SerializedValue }> {
|
async send(params: { method: string, params?: SerializedValue }): Promise<{ result: SerializedValue }> {
|
||||||
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)) };
|
return { result: serializeResult(await this._object.send(params.method as any, cdpParams)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,9 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, JSHandleInitiali
|
||||||
export function parseArgument(arg: SerializedArgument): any {
|
export function parseArgument(arg: SerializedArgument): any {
|
||||||
return parseSerializedValue(arg.value, arg.handles.map(a => (a as JSHandleDispatcher)._object));
|
return parseSerializedValue(arg.value, arg.handles.map(a => (a as JSHandleDispatcher)._object));
|
||||||
}
|
}
|
||||||
|
export function parseValue(v: SerializedValue): any {
|
||||||
|
return parseSerializedValue(v, []);
|
||||||
|
}
|
||||||
|
|
||||||
export function serializeResult(arg: any): SerializedValue {
|
export function serializeResult(arg: any): SerializedValue {
|
||||||
return serializeValue(arg, value => ({ fallThrough: value }), new Set());
|
return serializeValue(arg, value => ({ fallThrough: value }), new Set());
|
||||||
|
|
|
||||||
|
|
@ -73,26 +73,28 @@ export class Firefox extends BrowserTypeBase {
|
||||||
throw new Error('Pass userDataDir parameter instead of specifying -profile argument');
|
throw new Error('Pass userDataDir parameter instead of specifying -profile argument');
|
||||||
if (args.find(arg => arg.startsWith('-juggler')))
|
if (args.find(arg => arg.startsWith('-juggler')))
|
||||||
throw new Error('Use the port parameter instead of -juggler argument');
|
throw new Error('Use the port parameter instead of -juggler argument');
|
||||||
|
let firefoxUserPrefs = isPersistent ? undefined : options.firefoxUserPrefs;
|
||||||
if (proxy) {
|
if (proxy) {
|
||||||
options.firefoxUserPrefs = options.firefoxUserPrefs || {};
|
// TODO: we should support proxy in persistent context without overriding user prefs.
|
||||||
options.firefoxUserPrefs['network.proxy.type'] = 1;
|
firefoxUserPrefs = firefoxUserPrefs || {};
|
||||||
|
firefoxUserPrefs['network.proxy.type'] = 1;
|
||||||
const proxyServer = new URL(proxy.server);
|
const proxyServer = new URL(proxy.server);
|
||||||
const isSocks = proxyServer.protocol === 'socks5:';
|
const isSocks = proxyServer.protocol === 'socks5:';
|
||||||
if (isSocks) {
|
if (isSocks) {
|
||||||
options.firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname;
|
firefoxUserPrefs['network.proxy.socks'] = proxyServer.hostname;
|
||||||
options.firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10);
|
firefoxUserPrefs['network.proxy.socks_port'] = parseInt(proxyServer.port, 10);
|
||||||
} else {
|
} else {
|
||||||
options.firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname;
|
firefoxUserPrefs['network.proxy.http'] = proxyServer.hostname;
|
||||||
options.firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10);
|
firefoxUserPrefs['network.proxy.http_port'] = parseInt(proxyServer.port, 10);
|
||||||
options.firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname;
|
firefoxUserPrefs['network.proxy.ssl'] = proxyServer.hostname;
|
||||||
options.firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10);
|
firefoxUserPrefs['network.proxy.ssl_port'] = parseInt(proxyServer.port, 10);
|
||||||
}
|
}
|
||||||
if (proxy.bypass)
|
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[] = [];
|
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)});`);
|
lines.push(`user_pref(${JSON.stringify(name)}, ${JSON.stringify(value)});`);
|
||||||
fs.writeFileSync(path.join(userDataDir, 'user.js'), lines.join('\n'));
|
fs.writeFileSync(path.join(userDataDir, 'user.js'), lines.join('\n'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue