From 82ade9bd9a8bc283d124758b8baae96bfd108ab7 Mon Sep 17 00:00:00 2001 From: Samar Panda Date: Mon, 28 Oct 2019 19:48:51 +0530 Subject: [PATCH] feat(audit): device support using lighthouse (#33) --- __tests__/Audit.test.js | 12 ++++++++++++ __tests__/Utils.test.js | 28 ++++++++++++++++++++++++++++ bin/is-website-vulnerable.js | 8 +++++++- src/Audit.js | 10 +++++++++- src/Utils.js | 14 ++++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) diff --git a/__tests__/Audit.test.js b/__tests__/Audit.test.js index 756fa4b..5df4ec8 100644 --- a/__tests__/Audit.test.js +++ b/__tests__/Audit.test.js @@ -40,4 +40,16 @@ describe('Audit', () => { expect(lighthouse.mock.calls[0][0]).toBe(url) }) + + test('a URL scan with device flag should result in calling lighthouse with that url & flag', async () => { + const url = 'https://abc.com' + const opts = {} + opts.emulatedFormFactor = 'mobile' + + const audit = new Audit() + await audit.scanUrl(url, opts) + + expect(lighthouse.mock.calls[0][0]).toBe(url) + expect(lighthouse.mock.calls[1][1]).toHaveProperty('emulatedFormFactor', 'mobile') + }) }) diff --git a/__tests__/Utils.test.js b/__tests__/Utils.test.js index 11b956e..3becdc8 100644 --- a/__tests__/Utils.test.js +++ b/__tests__/Utils.test.js @@ -55,4 +55,32 @@ describe('Utils', () => { const url = 'https://user:pass@google.com?version=1&minor=5&source=github#hash' expect(Utils.trimUtmParams(url)).toEqual(url) }) + + test('parseDevice & hasDevice function with no device flag', async () => { + const argv = {} + const defaultDevice = '' + expect(Utils.parseDevice(argv)).toEqual(defaultDevice) + expect(Utils.hasDevice(argv)).toEqual(false) + }) + + test('parseDevice & hasDevice with desktop flag', async () => { + const argv = { desktop: true } + const device = 'desktop' + expect(Utils.parseDevice(argv)).toEqual(device) + expect(Utils.hasDevice(argv)).toEqual(true) + }) + + test('parseDevice & hasDevice with mobile flag', async () => { + const argv = { mobile: true } + const device = 'mobile' + expect(Utils.parseDevice(argv)).toEqual(device) + expect(Utils.hasDevice(argv)).toEqual(true) + }) + + test('parseDevice & hasDevice with none flag', async () => { + const argv = { none: true } + const device = 'none' + expect(Utils.parseDevice(argv)).toEqual(device) + expect(Utils.hasDevice(argv)).toEqual(true) + }) }) diff --git a/bin/is-website-vulnerable.js b/bin/is-website-vulnerable.js index be3ca03..fd8a03d 100644 --- a/bin/is-website-vulnerable.js +++ b/bin/is-website-vulnerable.js @@ -21,10 +21,16 @@ if (!url) { process.exit(1) } +const opts = {} + +if (Utils.hasDevice(argv)) { + opts.emulatedFormFactor = Utils.parseDevice(argv) +} + const audit = new Audit() const showProgressBar = !argv.json audit - .scanUrl(url, showProgressBar) + .scanUrl(url, opts, showProgressBar) .then(results => { var renderer if (argv.json) { diff --git a/src/Audit.js b/src/Audit.js index d756a29..d924899 100644 --- a/src/Audit.js +++ b/src/Audit.js @@ -23,7 +23,7 @@ module.exports = class Audit { } } - async scanUrl(url, progress = false) { + async scanUrl(url, optflags = {}, progress = false) { // Start chrome-launcher Spinner // chrome-launcher Spinner @@ -58,6 +58,14 @@ module.exports = class Audit { const opts = {} opts.port = chromeInstance.port + if (Object.prototype.hasOwnProperty.call(optflags, 'emulatedFormFactor')) { + // https://github.com/GoogleChrome/lighthouse#cli-options refer --emulated-form-factor + debug(`setting up lighthouse device flag: ${opts.emulatedFormFactor}`) + opts.emulatedFormFactor = optflags.emulatedFormFactor + } else { + debug(`lighthouse default device flag: mobile`) + } + debug(`invoking lighthouse scan for: ${url}`) const scanResult = await lighthouse(url, opts, { extends: 'lighthouse:default', diff --git a/src/Utils.js b/src/Utils.js index a29d14a..883c3a5 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -28,5 +28,19 @@ module.exports = { const query = nonUtmQueryParams.length > 0 ? `?${nonUtmQueryParams.join('&')}` : '' const hash = parsedUrl.hash ? parsedUrl.hash : '' return `${parsedUrl.protocol}//${auth}${parsedUrl.host}${pathname}${query}${hash}` + }, + parseDevice: function(argv) { + let device = '' + if (argv.mobile) { + device = 'mobile' + } else if (argv.desktop) { + device = 'desktop' + } else if (argv.none) { + device = 'none' + } + return device + }, + hasDevice: function(argv) { + return argv.mobile || argv.desktop || argv.none || false } }