Conversation
49567a9 to
e8a056c
Compare
patrickhulce
left a comment
There was a problem hiding this comment.
nice this is awesome!! been soooooo excited for this 🎉 🕺 🕺 🕺 🎉
| this._passes = configJSON.passes || null; | ||
| this._auditResults = configJSON.auditResults || null; | ||
| if (this._auditResults && !Array.isArray(this._auditResults)) { | ||
| throw new Error('config.auditResults must be an array'); |
There was a problem hiding this comment.
Is anyone using this should we wait for a major version? I'm fine nuking, but seems like it could still be supported
There was a problem hiding this comment.
Ideally it would stick around, at least until 3.0. auditResults can skip everything and go right to the scoring (basically -R)
There was a problem hiding this comment.
(it's also helpful for tests where you just want to test the -R part)
There was a problem hiding this comment.
I'd prefer to just kill auditResults. Turns out we dont really have tests using it (except one).
auditResults is this weird inbetween value that's only different from the LHR because of these few lines: https://github.com/GoogleChrome/lighthouse/blob/gar/lighthouse-core/runner.js#L128-L155
if we REALLY want to support -R then we'd definitely not put auditResults on the config instance because it's bizarre. (obv that would break backcompat (for those mystery users)). if we want to do this i'd prefer to do it in a followup
lighthouse-core/lib/asset-saver.js
Outdated
| artifacts.traces = {}; | ||
|
|
||
| const filenames = fs.readdirSync(basePath); | ||
| const promises = filenames.filter(filename => filename.endsWith('-trace.json')).map(filename => { |
There was a problem hiding this comment.
should we do both traces and devtoolsLogs this way? It'd be nice to be consistent with how the assets are saved to disk in non-GAR mode but also less useful since there's nothing you can do with just the devtoolslog
nit: we also liked .trace.json/.devtoolslog.json if we want to stick with it here too :)
lighthouse-core/lib/asset-saver.js
Outdated
| log.log('artifacts file saved to disk', fullPath); | ||
| function saveArtifacts(artifacts, basePath) { | ||
| assert.notEqual(basePath, '/'); | ||
| rimraf.sync(basePath); |
There was a problem hiding this comment.
since we actually know about all the files we create, can we just delete those instead of the whole directory?
lighthouse-core/runner.js
Outdated
| const shouldGatherAndQuit = opts.flags.gatherMode && !opts.flags.auditMode; | ||
| const shouldOnlyAudit = opts.flags.auditMode && !opts.flags.gatherMode; | ||
| const shouldDefaultRunButSaveArtifacts = opts.flags.auditMode && opts.flags.gatherMode; | ||
| const shouldDoTypicalRun = !opts.flags.gatherMode && !opts.flags.auditMode; |
There was a problem hiding this comment.
can we pick either Typical or Default :)
lighthouse-core/runner.js
Outdated
|
|
||
| return artifacts; | ||
| if (shouldLoadArtifactsFromDisk) { | ||
| config.removePasses(); |
There was a problem hiding this comment.
seems like this should be unnecessary given we've exploded the various should* branches into variables above?
| const basePath = path.join(process.cwd(), 'latest-run'); | ||
|
|
||
| class Runner { | ||
| static run(connection, opts) { |
There was a problem hiding this comment.
this method is a bit big for its 👖 these days, it seems like it can roughly be broken down into
- loadOrGatherArtifacts
- potentiallySaveArtifacts
- potentiallyComputeAudits
- combine results
do you think it'd be easier to handle the config.gatherMode type flags individually in each of these 4 hypothetical methods rather than exploding the matrix of choices? the plain english variable names of "this is what is happening" is kinda nice right now, but its quite a long function
There was a problem hiding this comment.
Agreed on no real need to make a variable for each possible state. Rather than just four, can't we just have
- loadArtifacts
- gatherArtifacts
- saveArtifacts
- runAudits
- score
- createLHR
and just have run() run the ones that are needed for each flag?
There was a problem hiding this comment.
sg. say hello to
_loadArtifactsFromDisk
_gatherArtifactsFromBrowser
_saveArtifacts
_runAudits
_scoreAndCategorize
| }); | ||
| }); | ||
|
|
||
| it('should return formatted audit results when given no categories', function() { |
There was a problem hiding this comment.
oh wow you don't even get any category results? yeah let's nuke this
There was a problem hiding this comment.
the original test was added to ensure that you'd still get json output even if there were no categories in the config (e.g. you don't care about categories). Is that still possible?
There was a problem hiding this comment.
added a new test to assert things finish even if no categories in the config
lighthouse-core/runner.js
Outdated
| }); | ||
| // Entering: Gather phase | ||
| if (!config.passes && !config.artifacts && !shouldLoadArtifactsFromDisk) { | ||
| const err = new Error('You must require either gather passes or provide saved artifacts.'); |
There was a problem hiding this comment.
"You must require" seems a bit odd, "You must provide either ..." or "The config requires ... " perhaps?
There was a problem hiding this comment.
how about
No browser artifacts are either provided or requested.
There was a problem hiding this comment.
sg, even further?
No browser artifacts provided or requested.
| assert.equal(artifacts.networkRecords['firstPass'], undefined); | ||
| assert.equal(artifacts.networkRecords['secondPass'], undefined); | ||
| assert.equal(artifacts.networkRecords, undefined); | ||
| assert.equal(artifacts.networkRecords, undefined); |
There was a problem hiding this comment.
nit: remove one of these
|
|
||
| describe('Runner', () => { | ||
| const saveArtifactsSpy = sinon.spy(assetSaver, 'saveArtifacts'); | ||
| const loadArtifactsSpy = sinon.spy(assetSaver, 'loadArtifacts'); |
There was a problem hiding this comment.
oh these are straight spies, I thought you were stubbing
I'd have a slight preference for stubbing loadArtifacts and asserting the LHR looks like we'd expect it to than 100% relying on 'was called' assertions
There was a problem hiding this comment.
i think we'll have to discuss this in person, as all runner tests do actually run gatherrunner.run, runAudits, generateReport, etc. So only going with stubs for these seems inconsistent.
Also, we'll have to mimic what these methods do on the test side if we want to see that everything works (for example: how do we test that lighthouse -G completes successfully unless it can read the files off disk?)
There was a problem hiding this comment.
I'm all for having at least some integration testing of this 👍
Maybe we'll chat in person but seems like there's room for both
| }); | ||
| }); | ||
|
|
||
| it('should return formatted audit results when given no categories', function() { |
There was a problem hiding this comment.
the original test was added to ensure that you'd still get json output even if there were no categories in the config (e.g. you don't care about categories). Is that still possible?
lighthouse-cli/cli-flags.ts
Outdated
| 'disable-cpu-throttling': 'Disable CPU throttling', | ||
| 'disable-network-throttling': 'Disable network throttling', | ||
| 'gather-mode': | ||
| 'Collect artifacts from a connected browser, save, & quit. However, if audit-mode is also enabled, then the run will complete after saving artifacts to disk.', |
There was a problem hiding this comment.
not sure how to parse the second part of this
lighthouse-cli/run.ts
Outdated
|
|
||
| await saveResults(results, artifacts!, flags); | ||
| await launchedChrome.kill(); | ||
| if (shouldSaveResults){ |
There was a problem hiding this comment.
can this be combined with the logic of whether or not to save already in saveResults?
lighthouse-cli/run.ts
Outdated
|
|
||
| return results; | ||
| } catch (err) { | ||
| return handleError(err); |
There was a problem hiding this comment.
does this work? handleError calls process.exit()
| this._passes = configJSON.passes || null; | ||
| this._auditResults = configJSON.auditResults || null; | ||
| if (this._auditResults && !Array.isArray(this._auditResults)) { | ||
| throw new Error('config.auditResults must be an array'); |
There was a problem hiding this comment.
Ideally it would stick around, at least until 3.0. auditResults can skip everything and go right to the scoring (basically -R)
lighthouse-core/lib/asset-saver.js
Outdated
| // do everything else | ||
| delete artifacts.traces; | ||
| // The networkRecords artifacts have circular references | ||
| fs.writeFileSync(`${basePath}/artifacts.json`, stringifySafe(artifacts), 'utf8'); |
There was a problem hiding this comment.
stringifySafe will be broken on re-import if we actually have circular references, so should just use JSON.stringify (and hopefully we've done things correctly :)
|
|
||
| const p = Promise.all(savePromies).then(_ => { | ||
| // do everything else | ||
| delete artifacts.traces; |
There was a problem hiding this comment.
can't delete traces on artifacts, maybe make a copy of the object?
| const basePath = path.join(process.cwd(), 'latest-run'); | ||
|
|
||
| class Runner { | ||
| static run(connection, opts) { |
There was a problem hiding this comment.
Agreed on no real need to make a variable for each possible state. Rather than just four, can't we just have
- loadArtifacts
- gatherArtifacts
- saveArtifacts
- runAudits
- score
- createLHR
and just have run() run the ones that are needed for each flag?
| passes: [{ | ||
| gatherers: ['viewport-dimensions'], | ||
| }], | ||
| audits: [ |
There was a problem hiding this comment.
how does this test audit output without running a gatherer or audit?
There was a problem hiding this comment.
it does run a gatherer and an audit. :o
| this._passes = configJSON.passes || null; | ||
| this._auditResults = configJSON.auditResults || null; | ||
| if (this._auditResults && !Array.isArray(this._auditResults)) { | ||
| throw new Error('config.auditResults must be an array'); |
There was a problem hiding this comment.
(it's also helpful for tests where you just want to test the -R part)
|
will there be docs about this? This feature is really great if you run it in a cloud environment! |
lighthouse-core/lib/asset-saver.js
Outdated
| log.log('artifacts file saved to disk', fullPath); | ||
| function saveArtifacts(artifacts, basePath) { | ||
| if (!fs.existsSync(basePath)) { | ||
| fs.mkdirSync(basePath); |
There was a problem hiding this comment.
we should use mkdirp.sync here to make sure we can create dirs recursively (we should already have it as a dependency)
| if (!fs.existsSync(basePath)) { | ||
| fs.mkdirSync(basePath); | ||
| } | ||
| rimraf.sync(`${basePath}/*${traceSuffix}`); |
There was a problem hiding this comment.
I believe chrome launcher had a lot of issues on windows when using sync rimraf. Should we move to async?
There was a problem hiding this comment.
rimraf's bumps since then were around this issue so i am hoping we're good now. https://github.com/isaacs/rimraf/commits/master
|
Okay folks.. A fresh update here. The big changes to runner are in this commit: a3da663 Otherwise, the remaining feedback has been addressed as well. |
lighthouse-cli/cli-flags.ts
Outdated
| '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 quit early.', |
There was a problem hiding this comment.
the run will quit early?
lighthouse-cli/run.ts
Outdated
|
|
||
| export function saveResults(results: Results, artifacts: Object, flags: Flags) { | ||
| const shouldSaveResults = flags.auditMode || (flags.gatherMode == flags.auditMode); | ||
| if (shouldSaveResults) return; |
There was a problem hiding this comment.
wait this seems backwards, shouldn't it be if (!shouldSaveResults)?
if not, maybe just method of variable name needs some tweaking :)
lighthouse-cli/run.ts
Outdated
| } | ||
|
|
||
| return handleError(err); | ||
| await potentiallyKillChrome(launchedChrome) return handleError(err); |
|
hey @devtools-bot why'd you change this :P |
|
Ready for another look. |
lighthouse-core/lib/asset-saver.js
Outdated
|
|
||
| // save everything else | ||
| promise = promise.then(_ => { | ||
| fs.writeFileSync(`${basePath}/${artifactsFilename}`, JSON.stringify(artifacts), 'utf8'); |
There was a problem hiding this comment.
care about prettifying?
a consequence of this I just ran into is that some artifacts are objects like Map/Set that aren't reconstituted. we'll have to move away from that. it might just be me with unminified-javascript right now :)
| const URL = require('./lib/url-shim'); | ||
| const Sentry = require('./lib/sentry'); | ||
|
|
||
| const basePath = path.join(process.cwd(), 'latest-run'); |
There was a problem hiding this comment.
let's add this to .gitignore :)
fixes #1806
The mystical -GAR feature. Actually its just -GA for now.
Here's how this works:
--gather-modeand--audit-modeare the long versions of-Gand-A.config.auditResultsis removed. it was weird.saveArtifacts, and addedloadArtifactsTodo:
Future work:
-G=./artifacts-save-path/-A=./artifacts-load-path/