From 4ef3c98bfd7d937f47499b3282be168940407e37 Mon Sep 17 00:00:00 2001 From: Brendan Kenny Date: Wed, 24 Aug 2016 17:03:48 -0700 Subject: [PATCH] support collecting network records per pass --- lighthouse-core/audits/audit.js | 6 +- .../audits/critical-request-chains.js | 3 +- .../audits/estimated-input-latency.js | 2 +- .../audits/first-meaningful-paint.js | 2 +- lighthouse-core/audits/screenshots.js | 2 +- lighthouse-core/audits/speed-index-metric.js | 2 +- lighthouse-core/audits/time-to-interactive.js | 4 +- lighthouse-core/audits/user-timings.js | 4 +- lighthouse-core/closure/typedefs/Artifacts.js | 3 + lighthouse-core/config/config.js | 31 +++++++- lighthouse-core/gather/drivers/driver.js | 2 - lighthouse-core/gather/gather-runner.js | 66 ++++++++-------- lighthouse-core/gather/gatherers/gatherer.js | 2 +- lighthouse-core/lib/log.js | 15 +++- .../audits/critical-request-chains-test.js | 3 + .../audits/estimated-input-latency-test.js | 2 +- .../audits/first-meaningful-paint-test.js | 2 +- .../test/audits/time-to-interactive-test.js | 4 +- .../test/audits/user-timing-test.js | 2 +- lighthouse-core/test/config/config-test.js | 79 ++++++++++++++++++- .../test/gather/gather-runner-test.js | 63 +++++++++------ lighthouse-core/test/lib/asset-saver-test.js | 2 +- lighthouse-core/test/runner-test.js | 2 +- 23 files changed, 221 insertions(+), 82 deletions(-) diff --git a/lighthouse-core/audits/audit.js b/lighthouse-core/audits/audit.js index cc41d8cd2e30..8d1867ad151b 100644 --- a/lighthouse-core/audits/audit.js +++ b/lighthouse-core/audits/audit.js @@ -16,14 +16,14 @@ */ 'use strict'; -const DEFAULT_TRACE = 'defaultPass'; +const DEFAULT_PASS = 'defaultPass'; class Audit { /** * @return {!String} */ - static get DEFAULT_TRACE() { - return DEFAULT_TRACE; + static get DEFAULT_PASS() { + return DEFAULT_PASS; } /** diff --git a/lighthouse-core/audits/critical-request-chains.js b/lighthouse-core/audits/critical-request-chains.js index 974bc5668a5f..5ead3e33e9f4 100644 --- a/lighthouse-core/audits/critical-request-chains.js +++ b/lighthouse-core/audits/critical-request-chains.js @@ -40,7 +40,8 @@ class CriticalRequestChains extends Audit { * @return {!AuditResult} The score from the audit, ranging from 0-100. */ static audit(artifacts) { - return artifacts.requestCriticalRequestChains(artifacts.networkRecords).then(chains => { + const networkRecord = artifacts.networkRecords[Audit.DEFAULT_PASS]; + return artifacts.requestCriticalRequestChains(networkRecord).then(chains => { let chainCount = 0; function walk(node, depth) { const children = Object.keys(node); diff --git a/lighthouse-core/audits/estimated-input-latency.js b/lighthouse-core/audits/estimated-input-latency.js index 10a27f9593e7..a00d4508e671 100644 --- a/lighthouse-core/audits/estimated-input-latency.js +++ b/lighthouse-core/audits/estimated-input-latency.js @@ -79,7 +79,7 @@ class EstimatedInputLatency extends Audit { * @return {!Promise} The score from the audit, ranging from 0-100. */ static audit(artifacts) { - const trace = artifacts.traces[this.DEFAULT_TRACE]; + const trace = artifacts.traces[this.DEFAULT_PASS]; return artifacts.requestSpeedline(trace) .then(speedline => EstimatedInputLatency.calculate(speedline, trace)) diff --git a/lighthouse-core/audits/first-meaningful-paint.js b/lighthouse-core/audits/first-meaningful-paint.js index b4f6796ab28c..613076682b07 100644 --- a/lighthouse-core/audits/first-meaningful-paint.js +++ b/lighthouse-core/audits/first-meaningful-paint.js @@ -53,7 +53,7 @@ class FirstMeaningfulPaint extends Audit { */ static audit(artifacts) { return new Promise((resolve, reject) => { - const traceContents = artifacts.traces[this.DEFAULT_TRACE].traceEvents; + const traceContents = artifacts.traces[this.DEFAULT_PASS].traceEvents; if (!traceContents || !Array.isArray(traceContents)) { throw new Error(FAILURE_MESSAGE); } diff --git a/lighthouse-core/audits/screenshots.js b/lighthouse-core/audits/screenshots.js index 9daa0b20e814..0a4786cf64e3 100644 --- a/lighthouse-core/audits/screenshots.js +++ b/lighthouse-core/audits/screenshots.js @@ -38,7 +38,7 @@ class Screenshots extends Audit { * @return {!Promise} */ static audit(artifacts) { - const trace = artifacts.traces[this.DEFAULT_TRACE]; + const trace = artifacts.traces[this.DEFAULT_PASS]; if (typeof trace === 'undefined') { return Promise.resolve(Screenshots.generateAuditResult({ rawValue: -1, diff --git a/lighthouse-core/audits/speed-index-metric.js b/lighthouse-core/audits/speed-index-metric.js index c84d0d236f52..de06320a45dc 100644 --- a/lighthouse-core/audits/speed-index-metric.js +++ b/lighthouse-core/audits/speed-index-metric.js @@ -47,7 +47,7 @@ class SpeedIndexMetric extends Audit { * @return {!Promise} The score from the audit, ranging from 0-100. */ static audit(artifacts) { - const trace = artifacts.traces[this.DEFAULT_TRACE]; + const trace = artifacts.traces[this.DEFAULT_PASS]; if (typeof trace === 'undefined') { return SpeedIndexMetric.generateAuditResult({ rawValue: -1, diff --git a/lighthouse-core/audits/time-to-interactive.js b/lighthouse-core/audits/time-to-interactive.js index cdb76dd6e6ce..98deddbb8cf2 100644 --- a/lighthouse-core/audits/time-to-interactive.js +++ b/lighthouse-core/audits/time-to-interactive.js @@ -57,7 +57,7 @@ class TTIMetric extends Audit { * @return {!Promise} The score from the audit, ranging from 0-100. */ static audit(artifacts) { - const trace = artifacts.traces[Audit.DEFAULT_TRACE]; + const trace = artifacts.traces[Audit.DEFAULT_PASS]; const pendingSpeedline = artifacts.requestSpeedline(trace); const pendingFMP = FMPMetric.audit(artifacts); @@ -74,7 +74,7 @@ class TTIMetric extends Audit { // Process the trace const tracingProcessor = new TracingProcessor(); - const trace = artifacts.traces[Audit.DEFAULT_TRACE]; + const trace = artifacts.traces[Audit.DEFAULT_PASS]; const model = tracingProcessor.init(trace); const endOfTraceTime = model.bounds.max; diff --git a/lighthouse-core/audits/user-timings.js b/lighthouse-core/audits/user-timings.js index 8d92113d7604..22da7361014c 100644 --- a/lighthouse-core/audits/user-timings.js +++ b/lighthouse-core/audits/user-timings.js @@ -129,8 +129,8 @@ class UserTimings extends Audit { static audit(artifacts) { return new Promise((resolve, reject) => { const traceContents = - artifacts.traces[this.DEFAULT_TRACE] && - artifacts.traces[this.DEFAULT_TRACE].traceEvents; + artifacts.traces[this.DEFAULT_PASS] && + artifacts.traces[this.DEFAULT_PASS].traceEvents; if (!traceContents || !Array.isArray(traceContents)) { throw new Error(FAILURE_MESSAGE); } diff --git a/lighthouse-core/closure/typedefs/Artifacts.js b/lighthouse-core/closure/typedefs/Artifacts.js index add787bd0068..6f8ed8c4dbd7 100644 --- a/lighthouse-core/closure/typedefs/Artifacts.js +++ b/lighthouse-core/closure/typedefs/Artifacts.js @@ -38,6 +38,9 @@ Artifacts.prototype.HTTPS; /** @type {!Array} */ Artifacts.prototype.traces; +/** @type {!Object} */ +Artifacts.prototype.networkRecords; + /** @type {!ManifestNode<(!Manifest|undefined)>} */ Artifacts.prototype.Manifest; diff --git a/lighthouse-core/config/config.js b/lighthouse-core/config/config.js index fe521f48d66b..428bb8b415b2 100644 --- a/lighthouse-core/config/config.js +++ b/lighthouse-core/config/config.js @@ -22,6 +22,7 @@ const recordsFromLogs = require('../lib/network-recorder').recordsFromLogs; const GatherRunner = require('../gather/gather-runner'); const log = require('../lib/log'); const path = require('path'); +const Audit = require('../audits/audit'); // cleanTrace is run to remove duplicate TracingStartedInPage events, // and to change TracingStartedInBrowser events into TracingStartedInPage. @@ -122,6 +123,21 @@ function validatePasses(passes, audits, rootPath) { } }); }); + + // Log if multiple passes require trace or network data and could overwrite one another. + const usedNames = new Set(); + passes.forEach((pass, index) => { + if (!pass.network && !pass.trace) { + return; + } + + const passName = pass.traceName || Audit.DEFAULT_PASS; + if (usedNames.has(passName)) { + log.warn('config', `passes[${index}] may overwrite trace or network ` + + `data of earlier pass without a unique traceName (repeated name: ${passName}.`); + } + usedNames.add(passName); + }); } function getGatherersNeededByAudits(audits) { @@ -238,8 +254,21 @@ function expandArtifacts(artifacts) { artifacts.traces[key] = trace; }); } + if (artifacts.performanceLog) { - artifacts.networkRecords = recordsFromLogs(require(artifacts.performanceLog)); + if (typeof artifacts.performanceLog === 'string') { + // Support older format of a single performance log. + const log = require(artifacts.performanceLog); + artifacts.networkRecords = { + [Audit.DEFAULT_PASS]: recordsFromLogs(log) + }; + } else { + artifacts.networkRecords = {}; + Object.keys(artifacts.performanceLog).forEach(key => { + const log = require(artifacts.performanceLog[key]); + artifacts.networkRecords[key] = recordsFromLogs(log); + }); + } } return artifacts; diff --git a/lighthouse-core/gather/drivers/driver.js b/lighthouse-core/gather/drivers/driver.js index cd3d422f51db..204a6e134cb8 100644 --- a/lighthouse-core/gather/drivers/driver.js +++ b/lighthouse-core/gather/drivers/driver.js @@ -213,8 +213,6 @@ class Driver { * If our main document URL redirects, we will update options.url accordingly * As such, options.url will always represent the post-redirected URL. * options.initialUrl is the pre-redirect URL that things started with - * - * Caveat: only works when network recording enabled for a pass */ enableUrlUpdateIfRedirected(opts) { this._networkRecorder.on('requestloaded', redirectRequest => { diff --git a/lighthouse-core/gather/gather-runner.js b/lighthouse-core/gather/gather-runner.js index 3791c6a04f68..20627eebd020 100644 --- a/lighthouse-core/gather/gather-runner.js +++ b/lighthouse-core/gather/gather-runner.js @@ -37,11 +37,11 @@ const path = require('path'); * B. GatherRunner.pass() * i. GatherRunner.loadPage() * a. navigate to about:blank - * b. beginTrace & beginNetworkCollect (if requested) + * b. beginTrace (if requested) & beginNetworkCollect * c. navigate to options.url (and wait for onload) * ii. all gatherer's pass() * C. GatherRunner.afterPass() - * i. endTrace & endNetworkCollect (if requested) + * i. endTrace (if requested) & endNetworkCollect * ii. all gatherer's afterPass() * * 3. Teardown @@ -57,9 +57,10 @@ class GatherRunner { return driver.gotoURL('about:blank') // Wait a bit for about:blank to "take hold" before switching back to the page. .then(_ => new Promise((resolve, reject) => setTimeout(resolve, 300))) - // Begin tracing and network recording if required. + // Begin tracing if required. .then(_ => options.config.trace && driver.beginTrace()) - .then(_ => options.config.network && driver.beginNetworkCollect(options)) + // Begin network recording. + .then(_ => driver.beginNetworkCollect(options)) // Navigate. .then(_ => driver.gotoURL(options.url, { waitForLoad: true, @@ -135,7 +136,8 @@ class GatherRunner { const driver = options.driver; const config = options.config; const gatherers = config.gatherers; - const loadData = {traces: {}}; + const loadData = {}; + let pass = Promise.resolve(); if (config.trace) { @@ -144,32 +146,24 @@ class GatherRunner { return driver.endTrace(); }).then(traceContents => { // Before Chrome 54.0.2816 (codereview.chromium.org/2161583004), - // traceContents was an array of trace events. After this point, - // traceContents is an object with a traceEvents property. Normalize - // to new format. - if (Array.isArray(traceContents)) { - traceContents = { - traceEvents: traceContents - }; - } - - const traceName = config.traceName || Audit.DEFAULT_TRACE; - loadData.traces[traceName] = traceContents; - loadData.traceEvents = traceContents.traceEvents; + // traceContents was an array of trace events; after, traceContents is + // an object with a traceEvents property. Normalize to object form. + loadData.trace = Array.isArray(traceContents) ? { + traceEvents: traceContents + } : traceContents; log.verbose('statusEnd', 'Retrieving trace'); }); } - if (config.network) { - const status = 'Retrieving network records'; - pass = pass.then(_ => { - log.log('status', status); - return driver.endNetworkCollect(); - }).then(networkRecords => { - loadData.networkRecords = networkRecords; - log.verbose('statusEnd', status); - }); - } + const status = 'Retrieving network records'; + pass = pass.then(_ => { + log.log('status', status); + return driver.endNetworkCollect(); + }).then(networkRecords => { + // Network records only given to gatherers if requested by config. + config.network && (loadData.networkRecords = networkRecords); + log.verbose('statusEnd', status); + }); pass = gatherers.reduce((chain, gatherer) => { const status = `Retrieving: ${gatherer.name}`; @@ -182,13 +176,16 @@ class GatherRunner { }); }, pass); - // Resolve on loadData. + // Resolve on tracing data using traceName from config. return pass.then(_ => loadData); } static run(passes, options) { const driver = options.driver; - const tracingData = {traces: {}}; + const tracingData = { + traces: {}, + networkRecords: {} + }; if (typeof options.url !== 'string' || options.url.length === 0) { return Promise.reject(new Error('You must provide a url to the driver')); @@ -227,10 +224,13 @@ class GatherRunner { .then(_ => GatherRunner.beforePass(runOptions)) .then(_ => GatherRunner.pass(runOptions)) .then(_ => GatherRunner.afterPass(runOptions)) - .then(loadData => { - // Merge pass trace and network data into tracingData. - config.trace && Object.assign(tracingData.traces, loadData.traces); - config.network && (tracingData.networkRecords = loadData.networkRecords); + .then(passData => { + // If requested by config, merge trace and network data for this + // pass into tracingData. + const passName = config.traceName || Audit.DEFAULT_PASS; + config.trace && (tracingData.traces[passName] = passData.trace); + config.network && (tracingData.networkRecords[passName] = passData.networkRecords); + if (passIndex === 0) { urlAfterRedirects = runOptions.url; } diff --git a/lighthouse-core/gather/gatherers/gatherer.js b/lighthouse-core/gather/gatherers/gatherer.js index 369cd366728c..6ed5d816151e 100644 --- a/lighthouse-core/gather/gatherers/gatherer.js +++ b/lighthouse-core/gather/gatherers/gatherer.js @@ -52,7 +52,7 @@ class Gatherer { * executed, and — if generated in this pass — the trace is ended. The trace * and record of network activity are provided in `loadData`. * @param {!Object} options - * @param {{networkRecords: !Array, traceEvents: !Array} loadData + * @param {{networkRecords: !Array, trace: {traceEvents: !Array}} loadData */ afterPass(options, loadData) { } diff --git a/lighthouse-core/lib/log.js b/lighthouse-core/lib/log.js index 8008017c4683..a528950e1e49 100644 --- a/lighthouse-core/lib/log.js +++ b/lighthouse-core/lib/log.js @@ -39,13 +39,23 @@ function _log(title, logargs) { } class Emitter extends EventEmitter { - // issueStatus fires off all status updates - // listen with `require('lib/log').events.addListener('status', callback)` + /** + * Fires off all status updates. Listen with + * `require('lib/log').events.addListener('status', callback)` + */ issueStatus(title, args) { if (title === 'status' || title === 'statusEnd') { this.emit(title, args); } } + + /** + * Fires off all warnings. Listen with + * `require('lib/log').events.addListener('warning', callback)` + */ + issueWarning(args) { + this.emit('warning', args); + } } module.exports = { @@ -57,6 +67,7 @@ module.exports = { }, warn(title) { + this.events.issueWarning(arguments); return _log(`${title}:warn`, arguments); }, diff --git a/lighthouse-core/test/audits/critical-request-chains-test.js b/lighthouse-core/test/audits/critical-request-chains-test.js index 9df8082df613..a527a7792eb6 100644 --- a/lighthouse-core/test/audits/critical-request-chains-test.js +++ b/lighthouse-core/test/audits/critical-request-chains-test.js @@ -50,6 +50,9 @@ const CriticalRequestChains = { }; const mockArtifacts = { + networkRecords: { + [Audit.DEFAULT_PASS]: [] + }, requestCriticalRequestChains: function() { return Promise.resolve(CriticalRequestChains); } diff --git a/lighthouse-core/test/audits/estimated-input-latency-test.js b/lighthouse-core/test/audits/estimated-input-latency-test.js index 36a4eaa79042..0c293157a664 100644 --- a/lighthouse-core/test/audits/estimated-input-latency-test.js +++ b/lighthouse-core/test/audits/estimated-input-latency-test.js @@ -26,7 +26,7 @@ let computedArtifacts = GatherRunner.instantiateComputedArtifacts(); function generateArtifactsWithTrace(trace) { return Object.assign(computedArtifacts, { traces: { - [Audit.DEFAULT_TRACE]: trace + [Audit.DEFAULT_PASS]: trace } }); } diff --git a/lighthouse-core/test/audits/first-meaningful-paint-test.js b/lighthouse-core/test/audits/first-meaningful-paint-test.js index 76410edfe64f..d5649b704acb 100644 --- a/lighthouse-core/test/audits/first-meaningful-paint-test.js +++ b/lighthouse-core/test/audits/first-meaningful-paint-test.js @@ -38,7 +38,7 @@ describe('Performance: first-meaningful-paint audit', () => { it('processes a valid trace file', done => { assert.doesNotThrow(_ => { - Audit.audit({traces: {[Audit.DEFAULT_TRACE]: {traceEvents}}}) + Audit.audit({traces: {[Audit.DEFAULT_PASS]: {traceEvents}}}) .then(response => { fmpResult = response; done(); diff --git a/lighthouse-core/test/audits/time-to-interactive-test.js b/lighthouse-core/test/audits/time-to-interactive-test.js index 641ace5574f3..ea9d779edfba 100644 --- a/lighthouse-core/test/audits/time-to-interactive-test.js +++ b/lighthouse-core/test/audits/time-to-interactive-test.js @@ -28,7 +28,7 @@ describe('Performance: time-to-interactive audit', () => { it('scores a -1 with invalid trace data', () => { return Audit.audit({ traces: { - [Audit.DEFAULT_TRACE]: { + [Audit.DEFAULT_PASS]: { traceEvents: '[{"pid": 15256,"tid": 1295,"t' } }, @@ -44,7 +44,7 @@ describe('Performance: time-to-interactive audit', () => { it('evaluates valid input correctly', () => { let artifacts = mockArtifacts; artifacts.traces = { - [Audit.DEFAULT_TRACE]: { + [Audit.DEFAULT_PASS]: { traceEvents: pwaTrace } }; diff --git a/lighthouse-core/test/audits/user-timing-test.js b/lighthouse-core/test/audits/user-timing-test.js index 42b1199c73a3..0e71f31aaf53 100644 --- a/lighthouse-core/test/audits/user-timing-test.js +++ b/lighthouse-core/test/audits/user-timing-test.js @@ -29,7 +29,7 @@ describe('Performance: user-timings audit', () => { }); it('evaluates valid input correctly', () => { - return Audit.audit({traces: {[Audit.DEFAULT_TRACE]: {traceEvents}}}) + return Audit.audit({traces: {[Audit.DEFAULT_PASS]: {traceEvents}}}) .then(response => { assert.equal(response.score, 2); assert.ok(!Number.isNaN(response.extendedInfo.value[0].startTime)); diff --git a/lighthouse-core/test/config/config-test.js b/lighthouse-core/test/config/config-test.js index 0dab4cace0e4..bd6e096f9b7a 100644 --- a/lighthouse-core/test/config/config-test.js +++ b/lighthouse-core/test/config/config-test.js @@ -19,6 +19,8 @@ const Config = require('../../config/config'); const assert = require('assert'); const path = require('path'); const defaultConfig = require('../../config/default.json'); +const log = require('../../lib/log'); +const Audit = require('../../audits/audit'); /* eslint-env mocha */ @@ -37,6 +39,61 @@ describe('Config', () => { assert.equal(defaultConfig.audits.length, config.audits.length); }); + it('warns when a traceName is used twice', () => { + const unlikelyPassName = 'unlikelyPassName'; + const configJson = { + passes: [{ + network: true, + traceName: unlikelyPassName, + gatherers: [] + }, { + network: true, + traceName: unlikelyPassName, + gatherers: [] + }], + audits: [] + }; + + return new Promise((resolve, reject) => { + const warningListener = function(args) { + const warningMsg = args[1]; + if (new RegExp(`overwrite.+${unlikelyPassName}`).test(warningMsg)) { + log.events.removeListener('warning', warningListener); + resolve(); + } + }; + log.events.addListener('warning', warningListener); + + const _ = new Config(configJson); + }); + }); + + it('warns when traced twice with no traceNames', () => { + const configJson = { + passes: [{ + network: true, + gatherers: [] + }, { + network: true, + gatherers: [] + }], + audits: [] + }; + + return new Promise((resolve, reject) => { + const warningListener = function(args) { + const warningMsg = args[1]; + if (new RegExp(`overwrite.+${Audit.DEFAULT_PASS}`).test(warningMsg)) { + log.events.removeListener('warning', warningListener); + resolve(); + } + }; + log.events.addListener('warning', warningListener); + + const _ = new Config(configJson); + }); + }); + it('throws for unknown gatherers', () => { const config = { passes: [{ @@ -151,7 +208,27 @@ describe('Config', () => { }); const traceUserTimings = require('../fixtures/traces/trace-user-timings.json'); assert.deepStrictEqual(config.artifacts.traces.defaultPass.traceEvents, traceUserTimings); - assert.equal(config.artifacts.networkRecords.length, 76); + assert.equal(config.artifacts.networkRecords.defaultPass.length, 76); + }); + + it('expands artifacts with multiple named passes', () => { + const config = new Config({ + artifacts: { + traces: { + defaultPass: path.resolve(__dirname, '../fixtures/traces/trace-user-timings.json'), + otherPass: path.resolve(__dirname, '../fixtures/traces/trace-user-timings.json') + }, + performanceLog: { + defaultPass: path.resolve(__dirname, '../fixtures/perflog.json'), + otherPass: path.resolve(__dirname, '../fixtures/perflog.json') + } + } + }); + const traceUserTimings = require('../fixtures/traces/trace-user-timings.json'); + assert.deepStrictEqual(config.artifacts.traces.defaultPass.traceEvents, traceUserTimings); + assert.deepStrictEqual(config.artifacts.traces.otherPass.traceEvents, traceUserTimings); + assert.equal(config.artifacts.networkRecords.defaultPass.length, 76); + assert.equal(config.artifacts.networkRecords.otherPass.length, 76); }); it('handles traces with no TracingStartedInPage events', () => { diff --git a/lighthouse-core/test/gather/gather-runner-test.js b/lighthouse-core/test/gather/gather-runner-test.js index ec456adf6f1f..80d3315d4263 100644 --- a/lighthouse-core/test/gather/gather-runner-test.js +++ b/lighthouse-core/test/gather/gather-runner-test.js @@ -20,7 +20,6 @@ const Gatherer = require('../../gather/gatherers/gatherer'); const GatherRunner = require('../../gather/gather-runner'); -const Audit = require('../../audits/audit'); const assert = require('assert'); const Config = require('../../config/config'); const path = require('path'); @@ -53,6 +52,9 @@ describe('GatherRunner', function() { const driver = { gotoURL() { return Promise.resolve(true); + }, + beginNetworkCollect() { + return Promise.resolve(); } }; @@ -86,6 +88,9 @@ describe('GatherRunner', function() { gotoURL(url) { assert(url, expected.pop()); return Promise.resolve(true); + }, + beginNetworkCollect() { + return Promise.resolve(); } }; @@ -142,6 +147,9 @@ describe('GatherRunner', function() { }, gotoURL() { return Promise.resolve(); + }, + beginNetworkCollect() { + return Promise.resolve(); } }; @@ -161,6 +169,9 @@ describe('GatherRunner', function() { endTrace() { calledTrace = true; return Promise.resolve({x: 1}); + }, + endNetworkCollect() { + return Promise.resolve(); } }; @@ -173,27 +184,7 @@ describe('GatherRunner', function() { return GatherRunner.afterPass({driver, config}).then(vals => { assert.equal(calledTrace, true); - assert.deepEqual(vals.traces[Audit.DEFAULT_TRACE], {x: 1}); - }); - }); - - it('respects trace names', () => { - const driver = { - endTrace() { - return Promise.resolve({x: 1}); - } - }; - - const config = { - trace: true, - traceName: 'notTheDefaultPass', - gatherers: [{ - afterPass() {} - }] - }; - - return GatherRunner.afterPass({driver, config}).then(vals => { - assert.deepEqual(vals.traces.notTheDefaultPass, {x: 1}); + assert.deepEqual(vals.trace, {x: 1}); }); }); @@ -291,6 +282,31 @@ describe('GatherRunner', function() { }); }); + it('respects trace names', () => { + const passes = [{ + network: true, + trace: true, + traceName: 'firstPass', + loadPage: true, + gatherers: [new TestGatherer()] + }, { + network: true, + trace: true, + traceName: 'secondPass', + loadPage: true, + gatherers: [new TestGatherer()] + }]; + const options = {driver: fakeDriver, url: 'https://example.com', flags: {}, config: {}}; + + return GatherRunner.run(passes, options) + .then(artifacts => { + assert.ok(artifacts.traces.firstPass); + assert.ok(artifacts.networkRecords.firstPass); + assert.ok(artifacts.traces.secondPass); + assert.ok(artifacts.networkRecords.secondPass); + }); + }); + it('rejects if an audit does not provide an artifact', () => { const t1 = new TestGathererNoArtifact(); const config = new Config({}); @@ -357,7 +373,8 @@ describe('GatherRunner', function() { return GatherRunner.run(passes, options) .then(artifacts => { - const p = artifacts.requestCriticalRequestChains(artifacts.networkRecords); + const networkRecords = artifacts.networkRecords.firstPass; + const p = artifacts.requestCriticalRequestChains(networkRecords); return p.then(chains => { // fakeDriver will include networkRecords built from fixtures/perflog.json assert.ok(chains['93149.1']); diff --git a/lighthouse-core/test/lib/asset-saver-test.js b/lighthouse-core/test/lib/asset-saver-test.js index 4fbce8f2e479..e937037a04b3 100644 --- a/lighthouse-core/test/lib/asset-saver-test.js +++ b/lighthouse-core/test/lib/asset-saver-test.js @@ -44,7 +44,7 @@ describe('asset-saver helper', () => { }; const artifacts = { traces: { - [Audit.DEFAULT_TRACE]: { + [Audit.DEFAULT_PASS]: { traceEvents } }, diff --git a/lighthouse-core/test/runner-test.js b/lighthouse-core/test/runner-test.js index 2b561aff16a5..bbee787f9d20 100644 --- a/lighthouse-core/test/runner-test.js +++ b/lighthouse-core/test/runner-test.js @@ -76,7 +76,7 @@ describe('Runner', () => { artifacts: { traces: { - [Audit.DEFAULT_TRACE]: path.join(__dirname, '/fixtures/traces/trace-user-timings.json') + [Audit.DEFAULT_PASS]: path.join(__dirname, '/fixtures/traces/trace-user-timings.json') } } });