From 0acc2a17800607d1ea59498e7c2396b7b262cf78 Mon Sep 17 00:00:00 2001 From: Csaba Palfi Date: Sun, 14 Apr 2019 15:49:20 +0100 Subject: [PATCH 1/3] add cli option to save reports --- lib/cli-options.js | 14 +++++++++++--- lib/main.js | 12 +++++++++--- lib/save-report.js | 3 +++ tests/__snapshots__/cli-options.test.js.snap | 5 ++++- tests/main.test.js | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 lib/save-report.js diff --git a/lib/cli-options.js b/lib/cli-options.js index 7019c34..309e4b8 100644 --- a/lib/cli-options.js +++ b/lib/cli-options.js @@ -48,7 +48,15 @@ const options = { type: 'boolean', describe: 'Output as JSON Lines', group: 'Output:', - default: false + default: false, + alias: 'output.jsonl', + }, + reports: { + type: 'boolean', + describe: 'Save Lighthouse reports', + group: 'Output:', + default: false, + alias: 'output.reports', }, local: { type: 'boolean', @@ -81,9 +89,9 @@ function parseArgs({argv}) { .parse(); const url = positionalArgAt(args, 0); - const {runs, warmupRuns, metrics, jsonl, lighthouse} = args; + const {runs, warmupRuns, metrics, output, lighthouse} = args; - return {url, runs, warmupRuns, metrics, jsonl, lighthouse}; + return {url, runs, warmupRuns, metrics, output, lighthouse}; } module.exports = {parseArgs, check}; \ No newline at end of file diff --git a/lib/main.js b/lib/main.js index 1653acb..1be7040 100755 --- a/lib/main.js +++ b/lib/main.js @@ -1,17 +1,23 @@ const {Counter} = require('./counter'); const {Runner} = require('./runner'); +const {saveReport} = require('./save-report'); const {resultMapper} = require('./map-result'); const {outputFormatter} = require('./format-output'); function main({ runs, warmupRuns, getLighthouseResult, url, metrics, - jsonl, + output }) { const counter = new Counter(runs, warmupRuns); const getResult = () => - getLighthouseResult(url).then(resultMapper(metrics)); - const format = outputFormatter(jsonl); + getLighthouseResult(url).then((result) => { + if (output.reports) { + saveReport(result); + } + return resultMapper(metrics)(result); + }); + const format = outputFormatter(output.jsonl); return new Runner(counter, getResult, format); } diff --git a/lib/save-report.js b/lib/save-report.js new file mode 100644 index 0000000..43aae89 --- /dev/null +++ b/lib/save-report.js @@ -0,0 +1,3 @@ +function saveReport() {} + +module.exports = {saveReport}; \ No newline at end of file diff --git a/tests/__snapshots__/cli-options.test.js.snap b/tests/__snapshots__/cli-options.test.js.snap index 17de61a..bfe9b07 100644 --- a/tests/__snapshots__/cli-options.test.js.snap +++ b/tests/__snapshots__/cli-options.test.js.snap @@ -2,7 +2,6 @@ exports[`cli-options parseArgs returns defaults based on argv 1`] = ` Object { - "jsonl": false, "lighthouse": Object { "cpu-slow-down": 4, "cpuSlowDown": 4, @@ -16,6 +15,10 @@ Object { "user-timing-marks": Object {}, "userTimingMarks": Object {}, }, + "output": Object { + "jsonl": false, + "reports": false, + }, "runs": 9, "url": "https://www.google.com", "warmupRuns": 0, diff --git a/tests/main.test.js b/tests/main.test.js index 09a9920..70d1bd8 100644 --- a/tests/main.test.js +++ b/tests/main.test.js @@ -7,7 +7,7 @@ describe('main', () => { getLighthouseResult: jest.fn(), url: 'https://www.google.com', metrics: {userTimingMarks: {}}, - jsonl: false + output: {jsonl: false, reports: false}, }; it('returns runner', () => { From b233cb5f14cd721b91e29213f96ff3566afc110f Mon Sep 17 00:00:00 2001 From: Csaba Palfi Date: Sun, 14 Apr 2019 22:39:10 +0100 Subject: [PATCH 2/3] implement saving assets --- .gitignore | 5 ++++- lib/cli-options.js | 4 ++-- lib/main.js | 8 ++++---- lib/run-lighthouse.js | 4 ++-- lib/run-pagespeed.js | 2 +- lib/save-assets.js | 14 ++++++++++++++ lib/save-report.js | 3 --- package.json | 3 ++- tests/__snapshots__/cli-options.test.js.snap | 3 ++- tests/main.test.js | 4 ++-- tests/run-lighthouse.test.js | 12 +++++++++--- tests/run-pagespeed.test.js | 6 +++--- 12 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 lib/save-assets.js delete mode 100644 lib/save-report.js diff --git a/.gitignore b/.gitignore index 3091757..e6e0f68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ node_modules -coverage \ No newline at end of file +coverage +*.trace.json +*.devtoolslog.json +*.report.json \ No newline at end of file diff --git a/lib/cli-options.js b/lib/cli-options.js index 309e4b8..56670ef 100644 --- a/lib/cli-options.js +++ b/lib/cli-options.js @@ -51,12 +51,12 @@ const options = { default: false, alias: 'output.jsonl', }, - reports: { + saveAssets: { type: 'boolean', describe: 'Save Lighthouse reports', group: 'Output:', default: false, - alias: 'output.reports', + alias: 'output.saveAssets', }, local: { type: 'boolean', diff --git a/lib/main.js b/lib/main.js index 1be7040..c0c5019 100755 --- a/lib/main.js +++ b/lib/main.js @@ -1,6 +1,6 @@ const {Counter} = require('./counter'); const {Runner} = require('./runner'); -const {saveReport} = require('./save-report'); +const {saveAssets} = require('./save-assets'); const {resultMapper} = require('./map-result'); const {outputFormatter} = require('./format-output'); @@ -11,9 +11,9 @@ function main({ }) { const counter = new Counter(runs, warmupRuns); const getResult = () => - getLighthouseResult(url).then((result) => { - if (output.reports) { - saveReport(result); + getLighthouseResult(url).then(async ({result, artifacts}) => { + if (output.saveAssets) { + await saveAssets(result, artifacts); } return resultMapper(metrics)(result); }); diff --git a/lib/run-lighthouse.js b/lib/run-lighthouse.js index af07f02..f131ed8 100644 --- a/lib/run-lighthouse.js +++ b/lib/run-lighthouse.js @@ -22,11 +22,11 @@ async function runLighthouse({modulePath, cpuSlowDown}, url) { const chrome = await launch({chromeFlags: ['--headless']}); const options = {port: chrome.port, throttling}; - const {lhr: result} = await lighthouse(url, options, config); + const {lhr: result, artifacts} = await lighthouse(url, options, config); await chrome.kill(); - return result; + return {result, artifacts}; } module.exports = {runLighthouse, config}; diff --git a/lib/run-pagespeed.js b/lib/run-pagespeed.js index da524a1..af29bcd 100644 --- a/lib/run-pagespeed.js +++ b/lib/run-pagespeed.js @@ -8,7 +8,7 @@ async function runPagespeed(urlString) { const query = new URLSearchParams({url: url.toString(), strategy: 'mobile'}); const apiUrl = `${baseUrl}/?${query.toString()}`; const {payload} = await wreck.get(apiUrl, {json: true}); - return payload.lighthouseResult; + return {result: payload.lighthouseResult}; } module.exports = {runPagespeed}; \ No newline at end of file diff --git a/lib/save-assets.js b/lib/save-assets.js new file mode 100644 index 0000000..422ce9b --- /dev/null +++ b/lib/save-assets.js @@ -0,0 +1,14 @@ +const {resolve} = require('path'); +const {writeFileSync} = require('fs'); +const getFilenamePrefix = require('lighthouse/lighthouse-core/lib/file-namer').getFilenamePrefix; +const assetSaver = require('lighthouse/lighthouse-core/lib/asset-saver'); + +async function saveAssets(result, artifacts) { + const resolvedPath = resolve(process.cwd(), getFilenamePrefix(result)); + writeFileSync(resolvedPath + '.report.json', JSON.stringify(result, null, 2), 'utf-8'); + if (artifacts) { + await assetSaver.saveAssets(artifacts, result.audits, resolvedPath); + } +} + +module.exports = {saveAssets}; \ No newline at end of file diff --git a/lib/save-report.js b/lib/save-report.js deleted file mode 100644 index 43aae89..0000000 --- a/lib/save-report.js +++ /dev/null @@ -1,3 +0,0 @@ -function saveReport() {} - -module.exports = {saveReport}; \ No newline at end of file diff --git a/package.json b/package.json index d6b0b5e..6687b97 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "scripts": { "pretest": "eslint .", "test": "jest", - "coverage": "cat ./coverage/lcov.info | coveralls" + "coverage": "cat ./coverage/lcov.info | coveralls", + "clean": "rm -f *.trace.json *.devtoolslog.json *.report.json" }, "main": "index.js", "author": "Csaba Palfi", diff --git a/tests/__snapshots__/cli-options.test.js.snap b/tests/__snapshots__/cli-options.test.js.snap index bfe9b07..715bc7c 100644 --- a/tests/__snapshots__/cli-options.test.js.snap +++ b/tests/__snapshots__/cli-options.test.js.snap @@ -17,7 +17,8 @@ Object { }, "output": Object { "jsonl": false, - "reports": false, + "save-assets": false, + "saveAssets": false, }, "runs": 9, "url": "https://www.google.com", diff --git a/tests/main.test.js b/tests/main.test.js index 70d1bd8..5c413f5 100644 --- a/tests/main.test.js +++ b/tests/main.test.js @@ -15,13 +15,13 @@ describe('main', () => { }); it('runner.getResult calls getLighthouseResult then mapResult', async () => { - const lighthouseResult = { + const result = { categories: {performance: {score: 1}}, audits: {} }; const {getLighthouseResult} = options; - getLighthouseResult.mockResolvedValue(lighthouseResult); + getLighthouseResult.mockResolvedValue({result}); const runner = main(options); const mappedResult = await runner.getResult(); diff --git a/tests/run-lighthouse.test.js b/tests/run-lighthouse.test.js index 3646ab1..2704a63 100644 --- a/tests/run-lighthouse.test.js +++ b/tests/run-lighthouse.test.js @@ -9,13 +9,19 @@ describe('run-lighthouse', () => { it('runLightHouse launches chrome and runs Lighthouse', async () => { const url = 'https://www.google.com'; const lighthouseResult = {}; + const lighthouseArtifacts = {}; const options = {modulePath: 'lighthouse', cpuSlowDown: 4}; const chrome = {port: 1234, kill: jest.fn()}; launch.mockResolvedValue(chrome); - lighthouse.mockResolvedValue({lhr: lighthouseResult}); + lighthouse.mockResolvedValue({ + lhr: lighthouseResult, + artifacts: lighthouseArtifacts + }); - await expect(runLighthouse(options, url)) - .resolves.toBe(lighthouseResult); + const {result, artifacts} = await runLighthouse(options, url); + + expect(result).toBe(lighthouseResult); + expect(artifacts).toBe(lighthouseArtifacts); expect(launch).toHaveBeenCalledTimes(1); expect(launch.mock.calls[0]).toMatchSnapshot(); diff --git a/tests/run-pagespeed.test.js b/tests/run-pagespeed.test.js index ce56a2e..c075014 100644 --- a/tests/run-pagespeed.test.js +++ b/tests/run-pagespeed.test.js @@ -7,12 +7,12 @@ describe('run-pagespeed', () => { it('runPageSpeed calls API and returns Lighthouse result', async () => { jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000); - wreck.get = jest.fn() .mockResolvedValue({payload: {lighthouseResult}}); - expect(await runPagespeed('https://www.google.com')) - .toBe(lighthouseResult); + const {result} = await runPagespeed('https://www.google.com'); + + expect(result).toBe(lighthouseResult); expect(wreck.get).toHaveBeenCalledTimes(1) expect(wreck.get.mock.calls[0]).toMatchSnapshot(); }); From a121e1e0da86e39d6ea1b28f3beffec7df815ef6 Mon Sep 17 00:00:00 2001 From: Csaba Palfi Date: Sun, 14 Apr 2019 23:17:01 +0100 Subject: [PATCH 3/3] add tests --- lib/save-assets.js | 7 ++- tests/__snapshots__/save-assets.test.js.snap | 21 +++++++ tests/save-assets.test.js | 59 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 tests/__snapshots__/save-assets.test.js.snap create mode 100644 tests/save-assets.test.js diff --git a/lib/save-assets.js b/lib/save-assets.js index 422ce9b..8e89e29 100644 --- a/lib/save-assets.js +++ b/lib/save-assets.js @@ -1,11 +1,14 @@ const {resolve} = require('path'); const {writeFileSync} = require('fs'); -const getFilenamePrefix = require('lighthouse/lighthouse-core/lib/file-namer').getFilenamePrefix; +const {getFilenamePrefix} = require('lighthouse/lighthouse-core/lib/file-namer'); const assetSaver = require('lighthouse/lighthouse-core/lib/asset-saver'); async function saveAssets(result, artifacts) { const resolvedPath = resolve(process.cwd(), getFilenamePrefix(result)); - writeFileSync(resolvedPath + '.report.json', JSON.stringify(result, null, 2), 'utf-8'); + const report = JSON.stringify(result, null, 2); + + writeFileSync(resolvedPath + '-0.report.json', report, 'utf-8'); + if (artifacts) { await assetSaver.saveAssets(artifacts, result.audits, resolvedPath); } diff --git a/tests/__snapshots__/save-assets.test.js.snap b/tests/__snapshots__/save-assets.test.js.snap new file mode 100644 index 0000000..1fc43b9 --- /dev/null +++ b/tests/__snapshots__/save-assets.test.js.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`save-assets saves report and artifacts 1`] = ` +Array [ + "resolvedPath-0.report.json", + "{ + \\"audits\\": {} +}", + "utf-8", +] +`; + +exports[`save-assets saves report only if no artifacts 1`] = ` +Array [ + "resolvedPath-0.report.json", + "{ + \\"audits\\": {} +}", + "utf-8", +] +`; diff --git a/tests/save-assets.test.js b/tests/save-assets.test.js new file mode 100644 index 0000000..11f9327 --- /dev/null +++ b/tests/save-assets.test.js @@ -0,0 +1,59 @@ +const {resolve} = require('path'); +const {writeFileSync} = require('fs'); +const {getFilenamePrefix} = require('lighthouse/lighthouse-core/lib/file-namer'); +const assetSaver = require('lighthouse/lighthouse-core/lib/asset-saver'); +const {saveAssets} = require('../lib/save-assets'); + +jest.mock('path'); +jest.mock('fs'); +jest.mock('lighthouse/lighthouse-core/lib/file-namer'); +jest.mock('lighthouse/lighthouse-core/lib/asset-saver'); + + +describe('save-assets', () => { + const audits = {}; + const result = {audits}; + const fileNamePrefix = 'prefix'; + const resolvedPath = 'resolvedPath'; + + afterEach(() => jest.resetAllMocks()); + + function expectToSaveReport() { + expect(getFilenamePrefix).toHaveBeenCalledTimes(1); + expect(getFilenamePrefix.mock.calls[0][0]).toBe(result); + + expect(resolve).toHaveBeenCalledTimes(1); + expect(resolve.mock.calls[0]) + .toEqual([process.cwd(), fileNamePrefix]); + + expect(writeFileSync).toHaveBeenCalledTimes(1); + expect(writeFileSync.mock.calls[0]).toMatchSnapshot(); + } + + it('saves report only if no artifacts', async () => { + getFilenamePrefix.mockReturnValue(fileNamePrefix); + resolve.mockReturnValue(resolvedPath); + + await saveAssets(result); + + expectToSaveReport(); + }); + + it('saves report and artifacts', async () => { + const artifacts = {}; + getFilenamePrefix.mockReturnValue(fileNamePrefix); + resolve.mockReturnValue(resolvedPath); + + await saveAssets(result, artifacts); + + expectToSaveReport(); + + expect(assetSaver.saveAssets).toHaveBeenCalledTimes(1); + expect(assetSaver.saveAssets.mock.calls[0][0]) + .toBe(artifacts); + expect(assetSaver.saveAssets.mock.calls[0][1]) + .toBe(audits); + expect(assetSaver.saveAssets.mock.calls[0][2]) + .toBe(resolvedPath); + }); +}); \ No newline at end of file