Skip to content

Commit 78a8bd7

Browse files
jeremywiebepatrickhulce
authored andcommitted
Fix: Basic chrome-flags parsing for embedded quotes (#2754)
* Basic chrome-flags parsing for embedded quotes * Fix formatting in run.ts * Use yargs instead of hand-rolled arg parsing * Fix up formatting * Shorten up parseChromeFlags thanks to @patrickhulce * Add unit tests for Chrome flag parsing * check undefined. * update comment
1 parent db3f324 commit 78a8bd7

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

lighthouse-cli/run.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import * as Printer from './printer';
1111
import {Results} from './types/types';
1212
import {Flags} from './cli-flags';
1313
import {launch, LaunchedChrome} from '../chrome-launcher/chrome-launcher';
14+
15+
const yargs = require('yargs');
1416
const lighthouse = require('../lighthouse-core');
1517
const log = require('lighthouse-logger');
1618
const getFilenamePrefix = require('../lighthouse-core/lib/file-namer.js').getFilenamePrefix;
@@ -27,13 +29,40 @@ interface LighthouseError extends Error {
2729
code?: string
2830
}
2931

32+
// Boolean values that are true are rendered without a value (--debug vs. --debug=true)
33+
function formatArg(arg: string, value: any): string {
34+
if (value === true) {
35+
return `--${arg}`
36+
}
37+
38+
// Only quote the value if it contains spaces
39+
if (value.indexOf(' ') !== -1) {
40+
value = `"${value}"`
41+
}
42+
43+
return `--${arg}=${value}`
44+
}
45+
46+
// exported for testing
47+
export function parseChromeFlags(flags: string) {
48+
let args = yargs(flags).argv;
49+
const allKeys = Object.keys(args);
50+
51+
// Remove unneeded arguments (yargs includes a _ arg, $-prefixed args, and camelCase dupes)
52+
return allKeys.filter(k => k !== '_' && !k.startsWith('$') && !/[A-Z]/.test(k))
53+
.map(k => formatArg(k, args[k]));
54+
}
55+
3056
/**
3157
* Attempts to connect to an instance of Chrome with an open remote-debugging
3258
* port. If none is found, launches a debuggable instance.
3359
*/
3460
async function getDebuggableChrome(flags: Flags) {
35-
return await launch(
36-
{port: flags.port, chromeFlags: flags.chromeFlags.split(' '), logLevel: flags.logLevel});
61+
return await launch({
62+
port: flags.port,
63+
chromeFlags: parseChromeFlags(flags.chromeFlags),
64+
logLevel: flags.logLevel
65+
});
3766
}
3867

3968
function showConnectionError() {

lighthouse-cli/test/cli/run-test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const path = require('path');
1111
const fs = require('fs');
1212

1313
const run = require('../../run');
14+
const parseChromeFlags = require('../../run').parseChromeFlags;
1415
const fastConfig = {
1516
'extends': 'lighthouse:default',
1617
'settings': {
@@ -43,3 +44,31 @@ describe('CLI run', function() {
4344
});
4445
}).timeout(60000);
4546
});
47+
48+
describe('Parsing --chrome-flags', () => {
49+
it('returns boolean flags that are true as a bare flag', () => {
50+
assert.deepStrictEqual(['--debug'], parseChromeFlags('--debug'));
51+
});
52+
53+
it('returns boolean flags that are false with value', () => {
54+
assert.deepStrictEqual(['--debug=false'], parseChromeFlags('--debug=false'));
55+
});
56+
57+
it('returns boolean flags that empty when passed undefined', () => {
58+
assert.deepStrictEqual([], parseChromeFlags());
59+
});
60+
61+
it('returns flags correctly for issue 2817', () => {
62+
assert.deepStrictEqual(
63+
['--host-resolver-rules="MAP www.example.org:443 127.0.0.1:8443"'],
64+
parseChromeFlags('--host-resolver-rules="MAP www.example.org:443 127.0.0.1:8443"')
65+
);
66+
});
67+
68+
it('returns all flags as provided', () => {
69+
assert.deepStrictEqual(
70+
['--spaces="1 2 3 4"', '--debug=false', '--verbose', '--more-spaces="9 9 9"'],
71+
parseChromeFlags('--spaces="1 2 3 4" --debug=false --verbose --more-spaces="9 9 9"')
72+
);
73+
});
74+
});

0 commit comments

Comments
 (0)