mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(launcher): allow options to be passed into puppeteer.defaultArgs (#2950)
This commit is contained in:
committed by
Andrey Lushnikov
parent
2e0007669d
commit
6825088644
120
lib/Launcher.js
120
lib/Launcher.js
@@ -48,9 +48,6 @@ const DEFAULT_ARGS = [
|
||||
'--metrics-recording-only',
|
||||
'--no-first-run',
|
||||
'--safebrowsing-disable-auto-update',
|
||||
];
|
||||
|
||||
const AUTOMATION_ARGS = [
|
||||
'--enable-automation',
|
||||
'--password-store=basic',
|
||||
'--use-mock-keychain',
|
||||
@@ -58,52 +55,43 @@ const AUTOMATION_ARGS = [
|
||||
|
||||
class Launcher {
|
||||
/**
|
||||
* @param {!(LaunchOptions & BrowserOptions)=} options
|
||||
* @param {!(LaunchOptions & ChromeArgOptions & BrowserOptions)=} options
|
||||
* @return {!Promise<!Browser>}
|
||||
*/
|
||||
static async launch(options) {
|
||||
options = Object.assign({}, options || {});
|
||||
static async launch(options = {}) {
|
||||
const {
|
||||
ignoreDefaultArgs = false,
|
||||
args = [],
|
||||
dumpio = false,
|
||||
executablePath = null,
|
||||
pipe = false,
|
||||
env = process.env,
|
||||
handleSIGINT = true,
|
||||
handleSIGTERM = true,
|
||||
handleSIGHUP = true,
|
||||
ignoreHTTPSErrors = false,
|
||||
defaultViewport = {width: 800, height: 600},
|
||||
slowMo = 0,
|
||||
timeout = 30000
|
||||
} = options;
|
||||
|
||||
const chromeArguments = !ignoreDefaultArgs ? this.defaultArgs(options) : args;
|
||||
let temporaryUserDataDir = null;
|
||||
const chromeArguments = [];
|
||||
if (!options.ignoreDefaultArgs)
|
||||
chromeArguments.push(...DEFAULT_ARGS);
|
||||
if (!options.ignoreDefaultArgs)
|
||||
chromeArguments.push(...AUTOMATION_ARGS);
|
||||
|
||||
if (!options.ignoreDefaultArgs || !chromeArguments.some(argument => argument.startsWith('--remote-debugging-')))
|
||||
chromeArguments.push(options.pipe ? '--remote-debugging-pipe' : '--remote-debugging-port=0');
|
||||
|
||||
if (!options.args || !options.args.some(arg => arg.startsWith('--user-data-dir'))) {
|
||||
if (!options.userDataDir)
|
||||
temporaryUserDataDir = await mkdtempAsync(CHROME_PROFILE_PATH);
|
||||
|
||||
chromeArguments.push(`--user-data-dir=${options.userDataDir || temporaryUserDataDir}`);
|
||||
if (!chromeArguments.some(argument => argument.startsWith('--remote-debugging-')))
|
||||
chromeArguments.push(pipe ? '--remote-debugging-pipe' : '--remote-debugging-port=0');
|
||||
if (!chromeArguments.some(arg => arg.startsWith('--user-data-dir'))) {
|
||||
temporaryUserDataDir = await mkdtempAsync(CHROME_PROFILE_PATH);
|
||||
chromeArguments.push(`--user-data-dir=${temporaryUserDataDir}`);
|
||||
}
|
||||
if (options.devtools === true) {
|
||||
chromeArguments.push('--auto-open-devtools-for-tabs');
|
||||
options.headless = false;
|
||||
}
|
||||
if (typeof options.headless !== 'boolean' || options.headless) {
|
||||
chromeArguments.push(
|
||||
'--headless',
|
||||
'--hide-scrollbars',
|
||||
'--mute-audio'
|
||||
);
|
||||
if (os.platform() === 'win32')
|
||||
chromeArguments.push('--disable-gpu');
|
||||
}
|
||||
if (Array.isArray(options.args) && options.args.every(arg => arg.startsWith('-')))
|
||||
chromeArguments.push('about:blank');
|
||||
|
||||
let chromeExecutable = options.executablePath;
|
||||
if (typeof chromeExecutable !== 'string') {
|
||||
let chromeExecutable = executablePath;
|
||||
if (!executablePath) {
|
||||
const browserFetcher = new BrowserFetcher();
|
||||
const revisionInfo = browserFetcher.revisionInfo(ChromiumRevision);
|
||||
assert(revisionInfo.local, `Chromium revision is not downloaded. Run "npm install" or "yarn install"`);
|
||||
chromeExecutable = revisionInfo.executablePath;
|
||||
}
|
||||
if (Array.isArray(options.args))
|
||||
chromeArguments.push(...options.args);
|
||||
|
||||
const usePipe = chromeArguments.includes('--remote-debugging-pipe');
|
||||
const stdio = usePipe ? ['ignore', 'ignore', 'ignore', 'pipe', 'pipe'] : ['pipe', 'pipe', 'pipe'];
|
||||
@@ -115,12 +103,12 @@ class Launcher {
|
||||
// process group, making it possible to kill child process tree with `.kill(-pid)` command.
|
||||
// @see https://nodejs.org/api/child_process.html#child_process_options_detached
|
||||
detached: process.platform !== 'win32',
|
||||
env: options.env || process.env,
|
||||
env,
|
||||
stdio
|
||||
}
|
||||
);
|
||||
|
||||
if (options.dumpio) {
|
||||
if (dumpio) {
|
||||
chromeProcess.stderr.pipe(process.stderr);
|
||||
chromeProcess.stdout.pipe(process.stdout);
|
||||
}
|
||||
@@ -141,22 +129,16 @@ class Launcher {
|
||||
});
|
||||
|
||||
const listeners = [ helper.addEventListener(process, 'exit', killChrome) ];
|
||||
if (options.handleSIGINT !== false)
|
||||
if (handleSIGINT)
|
||||
listeners.push(helper.addEventListener(process, 'SIGINT', () => { killChrome(); process.exit(130); }));
|
||||
if (options.handleSIGTERM !== false)
|
||||
if (handleSIGTERM)
|
||||
listeners.push(helper.addEventListener(process, 'SIGTERM', gracefullyCloseChrome));
|
||||
if (options.handleSIGHUP !== false)
|
||||
if (handleSIGHUP)
|
||||
listeners.push(helper.addEventListener(process, 'SIGHUP', gracefullyCloseChrome));
|
||||
/** @type {?Connection} */
|
||||
let connection = null;
|
||||
try {
|
||||
const {
|
||||
ignoreHTTPSErrors = false,
|
||||
defaultViewport = {width: 800, height: 600},
|
||||
slowMo = 0
|
||||
} = options;
|
||||
if (!usePipe) {
|
||||
const timeout = helper.isNumber(options.timeout) ? options.timeout : 30000;
|
||||
const browserWSEndpoint = await waitForWSEndpoint(chromeProcess, timeout);
|
||||
connection = await Connection.createForWebSocket(browserWSEndpoint, slowMo);
|
||||
} else {
|
||||
@@ -228,10 +210,34 @@ class Launcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!ChromeArgOptions=} options
|
||||
* @return {!Array<string>}
|
||||
*/
|
||||
static defaultArgs() {
|
||||
return DEFAULT_ARGS.concat(AUTOMATION_ARGS);
|
||||
static defaultArgs(options = {}) {
|
||||
const {
|
||||
devtools = false,
|
||||
headless = !devtools,
|
||||
args = [],
|
||||
userDataDir = null
|
||||
} = options;
|
||||
const chromeArguments = [...DEFAULT_ARGS];
|
||||
if (userDataDir)
|
||||
chromeArguments.push(`--user-data-dir=${userDataDir}`);
|
||||
if (devtools)
|
||||
chromeArguments.push('--auto-open-devtools-for-tabs');
|
||||
if (headless) {
|
||||
chromeArguments.push(
|
||||
'--headless',
|
||||
'--hide-scrollbars',
|
||||
'--mute-audio'
|
||||
);
|
||||
if (os.platform() === 'win32')
|
||||
chromeArguments.push('--disable-gpu');
|
||||
}
|
||||
if (args.every(arg => arg.startsWith('-')))
|
||||
chromeArguments.push('about:blank');
|
||||
chromeArguments.push(...args);
|
||||
return chromeArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,19 +323,23 @@ function waitForWSEndpoint(chromeProcess, timeout) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} LaunchOptions
|
||||
* @typedef {Object} ChromeArgOptions
|
||||
* @property {boolean=} headless
|
||||
* @property {Array<string>=} args
|
||||
* @property {string=} userDataDir
|
||||
* @property {boolean=} devtools
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} LaunchOptions
|
||||
* @property {string=} executablePath
|
||||
* @property {!Array<string>=} args
|
||||
* @property {boolean=} ignoreDefaultArgs
|
||||
* @property {boolean=} handleSIGINT
|
||||
* @property {boolean=} handleSIGTERM
|
||||
* @property {boolean=} handleSIGHUP
|
||||
* @property {number=} timeout
|
||||
* @property {boolean=} dumpio
|
||||
* @property {string=} userDataDir
|
||||
* @property {!Object<string, string | undefined>=} env
|
||||
* @property {boolean=} devtools
|
||||
* @property {boolean=} pipe
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user