Skip to content

Commit

Permalink
core(runner): add custom folder support to -G/-A (#4792)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulirish authored Mar 20, 2018
1 parent ab5071e commit 8b02a90
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 22 deletions.
6 changes: 3 additions & 3 deletions lighthouse-cli/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ function getFlags(manualArgv) {
'disable-cpu-throttling': 'Disable CPU throttling',
'disable-network-throttling': 'Disable network throttling',
'gather-mode':
'Collect artifacts from a connected browser and save to disk. If audit-mode is not also enabled, the run will quit early.',
'audit-mode': 'Process saved artifacts from disk',
'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/)',
'save-assets': 'Save the trace contents & screenshots to disk',
'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',
Expand Down Expand Up @@ -111,7 +111,7 @@ function getFlags(manualArgv) {
'disable-storage-reset', 'disable-device-emulation', 'disable-cpu-throttling',
'disable-network-throttling', 'save-assets', 'list-all-audits',
'list-trace-categories', 'perf', 'view', 'verbose', 'quiet', 'help',
'gather-mode', 'audit-mode', 'mixed-content',
'mixed-content',
])
.choices('output', printer.getValidOutputOptions())
// force as an array
Expand Down
44 changes: 30 additions & 14 deletions lighthouse-core/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ const path = require('path');
const URL = require('./lib/url-shim');
const Sentry = require('./lib/sentry');

const basePath = path.join(process.cwd(), 'latest-run');

class Runner {
static run(connection, opts) {
// Clean opts input.
Expand Down Expand Up @@ -68,11 +66,20 @@ class Runner {
// Gather phase
// Either load saved artifacts off disk, from config, or get from the browser
if (opts.flags.auditMode && !opts.flags.gatherMode) {
run = run.then(_ => Runner._loadArtifactsFromDisk());
const path = Runner._getArtifactsPath(opts.flags);
run = run.then(_ => Runner._loadArtifactsFromDisk(path));
} else if (opts.config.artifacts) {
run = run.then(_ => opts.config.artifacts);
} else {
run = run.then(_ => Runner._gatherArtifactsFromBrowser(opts, connection));
// -G means save these to ./latest-run, etc.
if (opts.flags.gatherMode) {
run = run.then(async artifacts => {
const path = Runner._getArtifactsPath(opts.flags);
await Runner._saveArtifacts(artifacts, path);
return artifacts;
});
}
}

// Potentially quit early
Expand Down Expand Up @@ -123,10 +130,11 @@ class Runner {

/**
* No browser required, just load the artifacts from disk
* @param {string} path
* @return {!Promise<!Artifacts>}
*/
static _loadArtifactsFromDisk() {
return assetSaver.loadArtifacts(basePath);
static _loadArtifactsFromDisk(path) {
return assetSaver.loadArtifacts(path);
}

/**
Expand All @@ -135,27 +143,23 @@ class Runner {
* @param {*} connection
* @return {!Promise<!Artifacts>}
*/
static _gatherArtifactsFromBrowser(opts, connection) {
static async _gatherArtifactsFromBrowser(opts, connection) {
if (!opts.config.passes) {
return Promise.reject(new Error('No browser artifacts are either provided or requested.'));
}

opts.driver = opts.driverMock || new Driver(connection);
return GatherRunner.run(opts.config.passes, opts).then(artifacts => {
const flags = opts.flags;
const shouldSave = flags.gatherMode;
const p = shouldSave ? Runner._saveArtifacts(artifacts): Promise.resolve();
return p.then(_ => artifacts);
});
return GatherRunner.run(opts.config.passes, opts);
}

/**
* Save collected artifacts to disk
* @param {!Artifacts} artifacts
* @param {string} path
* @return {!Promise>}
*/
static _saveArtifacts(artifacts) {
return assetSaver.saveArtifacts(artifacts, basePath);
static _saveArtifacts(artifacts, path) {
return assetSaver.saveArtifacts(artifacts, path);
}

/**
Expand Down Expand Up @@ -410,6 +414,18 @@ class Runner {
extraHeaders: flags.extraHeaders || {},
};
}

/**
* Get path to use for -G and -A modes. Defaults to $CWD/latest-run
* @param {Flags} flags
* @return {string}
*/
static _getArtifactsPath(flags) {
// This enables usage like: -GA=./custom-folder
if (typeof flags.auditMode === 'string') return path.resolve(process.cwd(), flags.auditMode);
if (typeof flags.gatherMode === 'string') return path.resolve(process.cwd(), flags.gatherMode);
return path.join(process.cwd(), 'latest-run');
}
}

module.exports = Runner;
17 changes: 14 additions & 3 deletions lighthouse-core/test/runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ const driverMock = require('./gather/fake-driver');
const Config = require('../config/config');
const Audit = require('../audits/audit');
const assetSaver = require('../lib/asset-saver');
const fs = require('fs');
const assert = require('assert');
const path = require('path');
const sinon = require('sinon');
const rimraf = require('rimraf');

const computedArtifacts = Runner.instantiateComputedArtifacts();

Expand Down Expand Up @@ -44,9 +46,15 @@ describe('Runner', () => {
}],
audits: ['content-width'],
});
const artifactsPath = '.tmp/test_artifacts';
const resolvedPath = path.resolve(process.cwd(), artifactsPath);

after(() => {
rimraf.sync(resolvedPath);
});

it('-G gathers, quits, and doesn\'t run audits', () => {
const opts = {url, config: generateConfig(), driverMock, flags: {gatherMode: true}};
const opts = {url, config: generateConfig(), driverMock, flags: {gatherMode: artifactsPath}};
return Runner.run(null, opts).then(_ => {
assert.equal(loadArtifactsSpy.called, false, 'loadArtifacts was called');

Expand All @@ -57,12 +65,15 @@ describe('Runner', () => {

assert.equal(gatherRunnerRunSpy.called, true, 'GatherRunner.run was not called');
assert.equal(runAuditSpy.called, false, '_runAudit was called');

assert.ok(fs.existsSync(resolvedPath));
assert.ok(fs.existsSync(`${resolvedPath}/artifacts.json`));
});
});

// uses the files on disk from the -G test. ;)
it('-A audits from saved artifacts and doesn\'t gather', () => {
const opts = {url, config: generateConfig(), driverMock, flags: {auditMode: true}};
const opts = {url, config: generateConfig(), driverMock, flags: {auditMode: artifactsPath}};
return Runner.run(null, opts).then(_ => {
assert.equal(loadArtifactsSpy.called, true, 'loadArtifacts was not called');
assert.equal(gatherRunnerRunSpy.called, false, 'GatherRunner.run was called');
Expand All @@ -73,7 +84,7 @@ describe('Runner', () => {

it('-GA is a normal run but it saves artifacts to disk', () => {
const opts = {url, config: generateConfig(), driverMock,
flags: {auditMode: true, gatherMode: true}};
flags: {auditMode: artifactsPath, gatherMode: artifactsPath}};
return Runner.run(null, opts).then(_ => {
assert.equal(loadArtifactsSpy.called, false, 'loadArtifacts was called');
assert.equal(gatherRunnerRunSpy.called, true, 'GatherRunner.run was not called');
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ lighthouse -A http://example.com

lighthouse -GA http://example.com
# Normal gather + audit run, but also saves collected artifacts to disk for subsequent -A runs.


# You can optionally provide a custom folder destination to -G/-A/-GA. Without a value, the default will be `$PWD/latest-run`.
lighthouse -GA=./gmailartifacts https://gmail.com
```


Expand Down
4 changes: 2 additions & 2 deletions typings/externs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ declare namespace LH {
enableErrorReporting: boolean;
listAllAudits: boolean;
listTraceCategories: boolean;
auditMode: boolean;
gatherMode: boolean;
auditMode: boolean|string;
gatherMode: boolean|string;
configPath?: string;
perf: boolean;
mixedContent: boolean;
Expand Down

0 comments on commit 8b02a90

Please sign in to comment.