Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
node_modules
coverage
coverage
*.trace.json
*.devtoolslog.json
*.report.json
14 changes: 11 additions & 3 deletions lib/cli-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ const options = {
type: 'boolean',
describe: 'Output as JSON Lines',
group: 'Output:',
default: false
default: false,
alias: 'output.jsonl',
},
saveAssets: {
type: 'boolean',
describe: 'Save Lighthouse reports',
group: 'Output:',
default: false,
alias: 'output.saveAssets',
},
local: {
type: 'boolean',
Expand Down Expand Up @@ -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};
12 changes: 9 additions & 3 deletions lib/main.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
const {Counter} = require('./counter');
const {Runner} = require('./runner');
const {saveAssets} = require('./save-assets');
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(async ({result, artifacts}) => {
if (output.saveAssets) {
await saveAssets(result, artifacts);
}
return resultMapper(metrics)(result);
});
const format = outputFormatter(output.jsonl);
return new Runner(counter, getResult, format);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/run-lighthouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
2 changes: 1 addition & 1 deletion lib/run-pagespeed.js
Original file line number Diff line number Diff line change
Expand Up @@ -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};
17 changes: 17 additions & 0 deletions lib/save-assets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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');

async function saveAssets(result, artifacts) {
const resolvedPath = resolve(process.cwd(), getFilenamePrefix(result));
const report = JSON.stringify(result, null, 2);

writeFileSync(resolvedPath + '-0.report.json', report, 'utf-8');

if (artifacts) {
await assetSaver.saveAssets(artifacts, result.audits, resolvedPath);
}
}

module.exports = {saveAssets};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 5 additions & 1 deletion tests/__snapshots__/cli-options.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -16,6 +15,11 @@ Object {
"user-timing-marks": Object {},
"userTimingMarks": Object {},
},
"output": Object {
"jsonl": false,
"save-assets": false,
"saveAssets": false,
},
"runs": 9,
"url": "https://www.google.com",
"warmupRuns": 0,
Expand Down
21 changes: 21 additions & 0 deletions tests/__snapshots__/save-assets.test.js.snap
Original file line number Diff line number Diff line change
@@ -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",
]
`;
6 changes: 3 additions & 3 deletions tests/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ describe('main', () => {
getLighthouseResult: jest.fn(),
url: 'https://www.google.com',
metrics: {userTimingMarks: {}},
jsonl: false
output: {jsonl: false, reports: false},
};

it('returns runner', () => {
expect(main(options)).toMatchSnapshot();
});

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();
Expand Down
12 changes: 9 additions & 3 deletions tests/run-lighthouse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 3 additions & 3 deletions tests/run-pagespeed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
59 changes: 59 additions & 0 deletions tests/save-assets.test.js
Original file line number Diff line number Diff line change
@@ -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);
});
});