2017-05-10 05:13:34 +03:00
/ * *
2020-03-18 19:21:54 +03:00
* @ license Copyright 2017 The Lighthouse Authors . All Rights Reserved .
2017-06-06 03:43:00 +03:00
* Licensed under the Apache License , Version 2.0 ( the "License" ) ; you may not use this file except in compliance with the License . You may obtain a copy of the License at http : //www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing , software distributed under the License is distributed on an "AS IS" BASIS , WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied . See the License for the specific language governing permissions and limitations under the License .
2017-05-10 05:13:34 +03:00
* /
'use strict' ;
2017-11-21 05:10:03 +03:00
/* eslint-disable max-len */
2017-05-10 05:13:34 +03:00
const yargs = require ( 'yargs' ) ;
const pkg = require ( '../package.json' ) ;
2019-05-22 03:36:23 +03:00
const printer = require ( './printer.js' ) ;
2017-05-10 05:13:34 +03:00
2019-05-23 01:09:31 +03:00
/ * *
* Remove in Node 11 - [ ] . flatMap
* @ param { Array < Array < string >> } arr
* @ return { string [ ] }
* /
function flatten ( arr ) {
/** @type {string[]} */
const result = [ ] ;
return result . concat ( ... arr ) ;
}
2017-11-21 05:10:03 +03:00
/ * *
* @ param { string = } manualArgv
2018-08-17 03:59:54 +03:00
* @ return { LH . CliFlags }
2017-11-21 05:10:03 +03:00
* /
function getFlags ( manualArgv ) {
2019-05-23 01:09:31 +03:00
// @ts-ignore yargs() is incorrectly typed as not accepting a single string.
2017-06-28 09:16:13 +03:00
const y = manualArgv ? yargs ( manualArgv ) : yargs ;
2019-05-23 01:09:31 +03:00
// Intentionally left as type `any` because @types/yargs doesn't chain correctly.
const argv = y . help ( 'help' )
2017-05-10 05:13:34 +03:00
. version ( ( ) => pkg . version )
. showHelpOnFail ( false , 'Specify --help for available options' )
2018-05-09 21:14:16 +03:00
. usage ( 'lighthouse <url> <options>' )
2017-05-10 05:13:34 +03:00
. example (
'lighthouse <url> --view' , 'Opens the HTML report in a browser after the run completes' )
. example (
'lighthouse <url> --config-path=./myconfig.js' ,
'Runs Lighthouse with your own configuration: custom audits, report generation, etc.' )
. example (
'lighthouse <url> --output=json --output-path=./report.json --save-assets' ,
'Save trace, screenshots, and named JSON report.' )
. example (
2019-04-18 02:27:14 +03:00
'lighthouse <url> --emulated-form-factor=none --throttling-method=provided' ,
2018-04-20 21:08:08 +03:00
'Disable device emulation and all throttling' )
2017-05-10 05:13:34 +03:00
. example (
2019-01-10 22:43:04 +03:00
'lighthouse <url> --chrome-flags="--window-size=412,660"' ,
2017-05-10 05:13:34 +03:00
'Launch Chrome with a specific window size' )
. example (
'lighthouse <url> --quiet --chrome-flags="--headless"' ,
'Launch Headless Chrome, turn off logging' )
2018-01-19 22:50:32 +03:00
. example (
'lighthouse <url> --extra-headers "{\\"Cookie\\":\\"monster=blue\\", \\"x-men\\":\\"wolverine\\"}"' ,
'Stringify\'d JSON HTTP Header key/value pairs to send in requests' )
. example (
'lighthouse <url> --extra-headers=./path/to/file.json' ,
'Path to JSON file of HTTP Header key/value pairs to send in requests' )
2019-05-23 01:09:31 +03:00
. example (
'lighthouse <url> --only-categories=performance,pwa' ,
2019-07-31 23:32:46 +03:00
'Only run the specified categories. Available categories: accessibility, best-practices, performance, pwa, seo' )
2019-06-04 22:53:08 +03:00
/ * *
* Also accept a file for all of these flags . Yargs will merge in and override the file - based
* flags with the command - line flags .
*
* i . e . when command - line ` --throttling-method=provided ` and file ` throttlingMethod: "devtools" ` ,
* throttlingMethod will be ` provided ` .
*
* @ see https : //github.com/yargs/yargs/blob/a6e67f15a61558d0ba28bfe53385332f0ce5d431/docs/api.md#config
* /
. config ( 'cli-flags-path' )
2017-05-10 05:13:34 +03:00
// List of options
. group ( [ 'verbose' , 'quiet' ] , 'Logging:' )
. describe ( {
verbose : 'Displays verbose logging' ,
2017-11-21 05:10:03 +03:00
quiet : 'Displays no progress, debug logs or errors' ,
2017-05-10 05:13:34 +03:00
} )
. group (
2017-11-21 05:10:03 +03:00
[
2018-09-27 03:49:02 +03:00
'save-assets' , 'list-all-audits' , 'list-trace-categories' , 'print-config' , 'additional-trace-categories' ,
2018-09-26 16:48:05 +03:00
'config-path' , 'preset' , 'chrome-flags' , 'port' , 'hostname' , 'emulated-form-factor' ,
2018-02-08 03:13:33 +03:00
'max-wait-for-load' , 'enable-error-reporting' , 'gather-mode' , 'audit-mode' ,
2019-04-26 03:23:51 +03:00
'only-audits' , 'only-categories' , 'skip-audits' , 'budget-path' ,
2017-11-21 05:10:03 +03:00
] ,
'Configuration:' )
2017-05-10 05:13:34 +03:00
. describe ( {
2019-06-04 22:53:08 +03:00
'cli-flags-path' : 'The path to a JSON file that contains the desired CLI flags to apply. Flags specified at the command line will still override the file-based ones.' ,
2018-08-07 21:54:30 +03:00
// We don't allowlist specific locales. Why? So we can support the user who requests 'es-MX' (unsupported) and we'll fall back to 'es' (supported)
2018-07-18 02:35:18 +03:00
'locale' : 'The locale/language the report should be formatted in' ,
2017-10-27 03:01:03 +03:00
'enable-error-reporting' :
2017-11-22 00:16:24 +03:00
'Enables error reporting, overriding any saved preference. --no-enable-error-reporting will do the opposite. More: https://git.io/vFFTO' ,
2017-08-29 03:05:56 +03:00
'blocked-url-patterns' : 'Block any network requests to the specified URL patterns' ,
2017-05-10 05:13:34 +03:00
'disable-storage-reset' :
'Disable clearing the browser cache and other storage APIs before a run' ,
2018-09-26 16:48:05 +03:00
'emulated-form-factor' : 'Controls the emulated device form factor (mobile vs. desktop) if not disabled' ,
2018-04-20 21:08:08 +03:00
'throttling-method' : 'Controls throttling method' ,
'throttling.rttMs' : 'Controls simulated network RTT (TCP layer)' ,
'throttling.throughputKbps' : 'Controls simulated network download throughput' ,
'throttling.requestLatencyMs' : 'Controls emulated network RTT (HTTP layer)' ,
'throttling.downloadThroughputKbps' : 'Controls emulated network download throughput' ,
'throttling.uploadThroughputKbps' : 'Controls emulated network upload throughput' ,
'throttling.cpuSlowdownMultiplier' : 'Controls simulated + emulated CPU throttling' ,
2018-01-05 23:17:11 +03:00
'gather-mode' :
2018-03-20 03:13:09 +03:00
'Collect artifacts from a connected browser and save to disk. (Artifacts folder path may optionally be provided). If audit-mode is not also enabled, the run will quit early.' ,
'audit-mode' : 'Process saved artifacts from disk. (Artifacts folder path may be provided, otherwise defaults to ./latest-run/)' ,
2019-04-15 02:33:45 +03:00
'save-assets' : 'Save the trace contents & devtools logs to disk' ,
2017-05-10 05:13:34 +03:00
'list-all-audits' : 'Prints a list of all available audits and exits' ,
'list-trace-categories' : 'Prints a list of all required trace categories and exits' ,
'additional-trace-categories' :
'Additional categories to capture with the trace (comma-delimited).' ,
2019-04-15 02:33:45 +03:00
'config-path' : ` The path to the config JSON.
2019-03-02 04:17:52 +03:00
An example config file : lighthouse - core / config / lr - desktop - config . js ` ,
2019-04-26 03:23:51 +03:00
'budget-path' : ` The path to the budget.json file for LightWallet. ` ,
2019-03-02 04:17:52 +03:00
'preset' : ` Use a built-in configuration.
WARNING : If the -- config - path flag is provided , this preset will be ignored . ` ,
2017-05-10 05:13:34 +03:00
'chrome-flags' :
2018-11-30 22:51:26 +03:00
` Custom flags to pass to Chrome (space-delimited). For a full list of flags, see https://bit.ly/chrome-flags
2018-06-11 21:38:51 +03:00
Additionally , use the CHROME _PATH environment variable to use a specific Chrome binary . Requires Chromium version 66.0 or later . If omitted , any detected Chrome Canary or Chrome stable will be used . ` ,
2017-08-15 00:19:53 +03:00
'hostname' : 'The hostname to use for the debugging protocol.' ,
2017-05-10 05:13:34 +03:00
'port' : 'The port to use for the debugging protocol. Use 0 for a random port' ,
'max-wait-for-load' :
'The timeout (in milliseconds) to wait before the page is considered done loading and the run should continue. WARNING: Very high values can lead to large traces and instability' ,
2018-01-19 22:50:32 +03:00
'extra-headers' : 'Set extra HTTP Headers to pass with request' ,
2019-02-26 03:56:01 +03:00
'precomputed-lantern-data-path' : 'Path to the file where lantern simulation data should be read from, overwriting the lantern observed estimates for RTT and server latency.' ,
'lantern-data-output-path' : 'Path to the file where lantern simulation data should be written to, can be used in a future run with the `precomputed-lantern-data-path` flag.' ,
2018-03-28 01:15:52 +03:00
'only-audits' : 'Only run the specified audits' ,
2019-07-31 23:32:46 +03:00
'only-categories' : 'Only run the specified categories. Available categories: accessibility, best-practices, performance, pwa, seo' ,
2018-03-28 01:15:52 +03:00
'skip-audits' : 'Run everything except these audits' ,
2019-03-08 01:12:14 +03:00
'plugins' : 'Run the specified plugins' ,
2018-09-27 03:49:02 +03:00
'print-config' : 'Print the normalized config for the given config and options, then exit.' ,
2017-05-10 05:13:34 +03:00
} )
2018-01-05 23:17:11 +03:00
// set aliases
. alias ( { 'gather-mode' : 'G' , 'audit-mode' : 'A' } )
2017-05-10 05:13:34 +03:00
. group ( [ 'output' , 'output-path' , 'view' ] , 'Output:' )
. describe ( {
2020-01-09 02:27:02 +03:00
'output' : ` Reporter for the results, supports multiple values. choices: ${ printer . getValidOutputOptions ( ) . map ( s => ` " ${ s } " ` ) . join ( ', ' ) } ` ,
2017-05-10 05:13:34 +03:00
'output-path' : ` The file path to output the results. Use 'stdout' to write to stdout.
2017-11-21 05:10:03 +03:00
If using JSON output , default is stdout .
2019-04-22 22:41:28 +03:00
If using HTML or CSV output , default is a file in the working directory with a name based on the test URL and date .
2018-10-19 00:58:30 +03:00
If using multiple outputs , -- output - path is appended with the standard extension for each output type . "reports/my-run" - > "reports/my-run.report.html" , "reports/my-run.report.json" , etc .
2017-11-21 05:10:03 +03:00
Example : -- output - path = . / lighthouse - results . html ` ,
'view' : 'Open HTML report in your browser' ,
2017-05-10 05:13:34 +03:00
} )
// boolean values
. boolean ( [
2019-04-18 02:27:14 +03:00
'disable-storage-reset' , 'save-assets' , 'list-all-audits' ,
2018-09-27 03:49:02 +03:00
'list-trace-categories' , 'view' , 'verbose' , 'quiet' , 'help' , 'print-config' ,
2020-01-07 21:10:50 +03:00
'chrome-ignore-default-flags' ,
2017-05-10 05:13:34 +03:00
] )
2018-09-26 16:48:05 +03:00
. choices ( 'emulated-form-factor' , [ 'mobile' , 'desktop' , 'none' ] )
2018-04-20 21:08:08 +03:00
. choices ( 'throttling-method' , [ 'devtools' , 'provided' , 'simulate' ] )
2020-04-15 01:37:48 +03:00
. choices ( 'preset' , [ 'perf' , 'mixed-content' , 'experimental' ] )
2017-08-29 03:05:56 +03:00
// force as an array
2018-03-28 01:15:52 +03:00
// note MUST use camelcase versions or only the kebab-case version will be forced
. array ( 'blockedUrlPatterns' )
. array ( 'onlyAudits' )
. array ( 'onlyCategories' )
. array ( 'skipAudits' )
2018-05-09 20:29:46 +03:00
. array ( 'output' )
2019-03-08 01:12:14 +03:00
. array ( 'plugins' )
2018-03-28 01:15:52 +03:00
. string ( 'extraHeaders' )
2019-03-07 22:32:06 +03:00
. string ( 'channel' )
2019-02-26 03:56:01 +03:00
. string ( 'precomputedLanternDataPath' )
. string ( 'lanternDataOutputPath' )
2019-04-26 03:23:51 +03:00
. string ( 'budgetPath' )
2017-05-10 05:13:34 +03:00
// default values
. default ( 'chrome-flags' , '' )
2018-05-09 20:29:46 +03:00
. default ( 'output' , [ 'html' ] )
2017-05-15 00:22:00 +03:00
. default ( 'port' , 0 )
2017-08-15 00:19:53 +03:00
. default ( 'hostname' , 'localhost' )
2018-08-17 20:47:16 +03:00
. default ( 'enable-error-reporting' , undefined ) // Undefined so prompted by default
2019-03-07 22:32:06 +03:00
. default ( 'channel' , 'cli' )
2018-08-17 03:59:54 +03:00
. check ( /** @param {LH.CliFlags} argv */ ( argv ) => {
2018-06-14 00:28:49 +03:00
// Lighthouse doesn't need a URL if...
// - We're just listing the available options.
2018-09-27 03:49:02 +03:00
// - We're just printing the config.
// - We're in auditMode (and we have artifacts already)
// If one of these don't apply, if no URL, stop the program and ask for one.
const isPrintSomethingMode = argv . listAllAudits || argv . listTraceCategories || argv . printConfig ;
2018-06-14 00:28:49 +03:00
const isOnlyAuditMode = ! ! argv . auditMode && ! argv . gatherMode ;
2018-09-27 03:49:02 +03:00
if ( isPrintSomethingMode || isOnlyAuditMode ) {
return true ;
} else if ( argv . _ . length > 0 ) {
return true ;
2017-05-10 05:13:34 +03:00
}
2018-09-27 03:49:02 +03:00
throw new Error ( 'Please provide a url' ) ;
2017-05-10 05:13:34 +03:00
} )
. epilogue (
'For more information on Lighthouse, see https://developers.google.com/web/tools/lighthouse/.' )
. wrap ( yargs . terminalWidth ( ) )
. argv ;
2019-05-23 01:09:31 +03:00
// Support comma-separated values for some array flags by splitting on any ',' found.
/** @type {Array<keyof LH.CliFlags>} */
const arrayKeysThatSupportCsv = [
'onlyAudits' ,
'onlyCategories' ,
'output' ,
'plugins' ,
'skipAudits' ,
] ;
arrayKeysThatSupportCsv . forEach ( key => {
// If a key is defined as an array in yargs, the value (if provided)
// will always be a string array. However, we keep argv and input as any,
// since assigning back to argv as string[] would be unsound for enums,
// for example: output is LH.OutputMode[].
const input = argv [ key ] ;
// Truthy check is necessary. isArray convinces TS that this is an array.
if ( Array . isArray ( input ) ) {
argv [ key ] = flatten ( input . map ( value => value . split ( ',' ) ) ) ;
}
} ) ;
return argv ;
2017-05-10 05:13:34 +03:00
}
2017-11-21 05:10:03 +03:00
module . exports = {
getFlags ,
} ;