diff --git a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js index 2b0b8335a310..230403e1be26 100644 --- a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js +++ b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js @@ -25,7 +25,7 @@ module.exports = [ score: 0, details: { items: { - length: 6, + length: 8, }, }, }, diff --git a/lighthouse-core/audits/bootup-time.js b/lighthouse-core/audits/bootup-time.js index c5e178fef4ec..726de4370680 100644 --- a/lighthouse-core/audits/bootup-time.js +++ b/lighthouse-core/audits/bootup-time.js @@ -45,7 +45,7 @@ class BootupTime extends Audit { failureTitle: str_(UIStrings.failureTitle), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['traces'], + requiredArtifacts: ['traces', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js b/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js index bcd9de011e80..570df52461b2 100644 --- a/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +++ b/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js @@ -70,10 +70,9 @@ class RenderBlockingResources extends Audit { title: str_(UIStrings.title), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, description: str_(UIStrings.description), - // This audit also looks at CSSUsage but has a graceful fallback if it failed, so do not mark - // it as a "requiredArtifact". - // TODO: look into adding an `optionalArtifacts` property that captures this - requiredArtifacts: ['URL', 'TagsBlockingFirstPaint', 'traces'], + // TODO: look into adding an `optionalArtifacts` property that captures the non-required nature + // of CSSUsage + requiredArtifacts: ['URL', 'TagsBlockingFirstPaint', 'traces', 'devtoolsLogs', 'CSSUsage'], }; } diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 87604f5def44..b9730b5a5331 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -36,7 +36,7 @@ class UnminifiedCSS extends ByteEfficiencyAudit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces'], + requiredArtifacts: ['CSSUsage', 'devtoolsLogs', 'traces', 'URL'], }; } diff --git a/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js b/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js index 9350b2782076..86df6023256b 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +++ b/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js @@ -35,7 +35,7 @@ class UsesOptimizedImages extends ByteEfficiencyAudit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['OptimizedImages', 'ImageElements', 'devtoolsLogs', 'traces'], + requiredArtifacts: ['OptimizedImages', 'ImageElements', 'devtoolsLogs', 'traces', 'URL'], }; } diff --git a/lighthouse-core/audits/byte-efficiency/uses-webp-images.js b/lighthouse-core/audits/byte-efficiency/uses-webp-images.js index 50865298fc23..6da263b8b769 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-webp-images.js +++ b/lighthouse-core/audits/byte-efficiency/uses-webp-images.js @@ -35,7 +35,7 @@ class UsesWebPImages extends ByteEfficiencyAudit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['OptimizedImages', 'devtoolsLogs', 'traces'], + requiredArtifacts: ['OptimizedImages', 'devtoolsLogs', 'traces', 'URL', 'ImageElements'], }; } diff --git a/lighthouse-core/audits/metrics/estimated-input-latency.js b/lighthouse-core/audits/metrics/estimated-input-latency.js index 38efde2b3c26..5f99e4cb43c2 100644 --- a/lighthouse-core/audits/metrics/estimated-input-latency.js +++ b/lighthouse-core/audits/metrics/estimated-input-latency.js @@ -31,7 +31,7 @@ class EstimatedInputLatency extends Audit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['traces'], + requiredArtifacts: ['traces', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/metrics/first-cpu-idle.js b/lighthouse-core/audits/metrics/first-cpu-idle.js index 6557ba152ae9..5bc9bfa95d2c 100644 --- a/lighthouse-core/audits/metrics/first-cpu-idle.js +++ b/lighthouse-core/audits/metrics/first-cpu-idle.js @@ -30,7 +30,7 @@ class FirstCPUIdle extends Audit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['traces'], + requiredArtifacts: ['traces', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/metrics/first-meaningful-paint.js b/lighthouse-core/audits/metrics/first-meaningful-paint.js index fe83fc0f7ef3..0c160319ae4c 100644 --- a/lighthouse-core/audits/metrics/first-meaningful-paint.js +++ b/lighthouse-core/audits/metrics/first-meaningful-paint.js @@ -29,7 +29,7 @@ class FirstMeaningfulPaint extends Audit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['traces'], + requiredArtifacts: ['traces', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/metrics/max-potential-fid.js b/lighthouse-core/audits/metrics/max-potential-fid.js index 3a81771bf6ce..467ed148d9d6 100644 --- a/lighthouse-core/audits/metrics/max-potential-fid.js +++ b/lighthouse-core/audits/metrics/max-potential-fid.js @@ -34,7 +34,7 @@ class MaxPotentialFID extends Audit { title: str_(UIStrings.title), description: str_(UIStrings.description), scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, - requiredArtifacts: ['traces'], + requiredArtifacts: ['traces', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/seo/canonical.js b/lighthouse-core/audits/seo/canonical.js index 75ad89955737..2306c209a19b 100644 --- a/lighthouse-core/audits/seo/canonical.js +++ b/lighthouse-core/audits/seo/canonical.js @@ -53,7 +53,7 @@ class Canonical extends Audit { title: str_(UIStrings.title), failureTitle: str_(UIStrings.failureTitle), description: str_(UIStrings.description), - requiredArtifacts: ['LinkElements', 'URL'], + requiredArtifacts: ['LinkElements', 'URL', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/seo/font-size.js b/lighthouse-core/audits/seo/font-size.js index 8498fda2c094..f6808289c7da 100644 --- a/lighthouse-core/audits/seo/font-size.js +++ b/lighthouse-core/audits/seo/font-size.js @@ -225,7 +225,7 @@ class FontSize extends Audit { }; } - const viewportMeta = await ComputedViewportMeta.request(artifacts, context); + const viewportMeta = await ComputedViewportMeta.request(artifacts.MetaElements, context); if (!viewportMeta.isMobileOptimized) { return { score: 0, diff --git a/lighthouse-core/audits/seo/is-crawlable.js b/lighthouse-core/audits/seo/is-crawlable.js index efacb2c52e0d..8126cca66785 100644 --- a/lighthouse-core/audits/seo/is-crawlable.js +++ b/lighthouse-core/audits/seo/is-crawlable.js @@ -81,7 +81,7 @@ class IsCrawlable extends Audit { title: str_(UIStrings.title), failureTitle: str_(UIStrings.failureTitle), description: str_(UIStrings.description), - requiredArtifacts: ['MetaElements', 'RobotsTxt', 'URL'], + requiredArtifacts: ['MetaElements', 'RobotsTxt', 'URL', 'devtoolsLogs'], }; } diff --git a/lighthouse-core/audits/seo/tap-targets.js b/lighthouse-core/audits/seo/tap-targets.js index b8b72c805129..25afeaaf92a2 100644 --- a/lighthouse-core/audits/seo/tap-targets.js +++ b/lighthouse-core/audits/seo/tap-targets.js @@ -283,7 +283,7 @@ class TapTargets extends Audit { }; } - const viewportMeta = await ComputedViewportMeta.request(artifacts, context); + const viewportMeta = await ComputedViewportMeta.request(artifacts.MetaElements, context); if (!viewportMeta.isMobileOptimized) { return { score: 0, diff --git a/lighthouse-core/audits/viewport.js b/lighthouse-core/audits/viewport.js index 6839f56d7552..adef0f7c9064 100644 --- a/lighthouse-core/audits/viewport.js +++ b/lighthouse-core/audits/viewport.js @@ -30,7 +30,7 @@ class Viewport extends Audit { * @return {Promise} */ static async audit(artifacts, context) { - const viewportMeta = await ComputedViewportMeta.request(artifacts, context); + const viewportMeta = await ComputedViewportMeta.request(artifacts.MetaElements, context); if (!viewportMeta.hasViewportTag) { return { diff --git a/lighthouse-core/computed/viewport-meta.js b/lighthouse-core/computed/viewport-meta.js index 7bf2703aa59b..a75cecaea109 100644 --- a/lighthouse-core/computed/viewport-meta.js +++ b/lighthouse-core/computed/viewport-meta.js @@ -11,10 +11,10 @@ const makeComputedArtifact = require('./computed-artifact.js'); class ViewportMeta { /** - * @param {{MetaElements: LH.GathererArtifacts['MetaElements']}} artifacts + * @param {LH.GathererArtifacts['MetaElements']} MetaElements * @return {Promise} */ - static async compute_({MetaElements}) { + static async compute_(MetaElements) { const viewportMeta = MetaElements.find(meta => meta.name === 'viewport'); if (!viewportMeta) { diff --git a/lighthouse-core/runner.js b/lighthouse-core/runner.js index 1504607bc99c..924145bf9612 100644 --- a/lighthouse-core/runner.js +++ b/lighthouse-core/runner.js @@ -325,7 +325,15 @@ class Runner { ...sharedAuditContext, }; - const product = await audit.audit(artifacts, auditContext); + // Only pass the declared `requiredArtifacts` to the audit + // The type is masquerading as `LH.Artifacts` but will only contain a subset of the keys + // to prevent consumers from unnecessary type assertions. + const requiredArtifacts = audit.meta.requiredArtifacts + .reduce((requiredArtifacts, artifactName) => { + requiredArtifacts[artifactName] = artifacts[artifactName]; + return requiredArtifacts; + }, /** @type {LH.Artifacts} */ ({})); + const product = await audit.audit(requiredArtifacts, auditContext); auditResult = Audit.generateAuditResult(audit, product); } catch (err) { log.warn(audit.meta.id, `Caught exception: ${err.message}`); diff --git a/lighthouse-core/test/computed/viewport-meta-test.js b/lighthouse-core/test/computed/viewport-meta-test.js index 62b89c7ec802..3b210801165e 100644 --- a/lighthouse-core/test/computed/viewport-meta-test.js +++ b/lighthouse-core/test/computed/viewport-meta-test.js @@ -14,7 +14,7 @@ describe('ViewportMeta computed artifact', () => { const makeMetaElements = viewport => [{name: 'viewport', content: viewport}]; it('is not mobile optimized when page does not contain a viewport meta tag', async () => { - const {hasViewportTag, isMobileOptimized} = await ViewportMeta.compute_({MetaElements: []}); + const {hasViewportTag, isMobileOptimized} = await ViewportMeta.compute_([]); assert.equal(hasViewportTag, false); assert.equal(isMobileOptimized, false); }); @@ -23,7 +23,7 @@ describe('ViewportMeta computed artifact', () => { it('is not mobile optimized when HTML contains a non-mobile friendly viewport meta tag', async () => { const viewport = 'maximum-scale=1'; const {hasViewportTag, isMobileOptimized} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(hasViewportTag, true); assert.equal(isMobileOptimized, false); }); @@ -31,7 +31,7 @@ describe('ViewportMeta computed artifact', () => { it('is not mobile optimized when HTML contains an invalid viewport meta tag key', async () => { const viewport = 'nonsense=true'; const {hasViewportTag, isMobileOptimized} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(hasViewportTag, true); assert.equal(isMobileOptimized, false); }); @@ -39,7 +39,7 @@ describe('ViewportMeta computed artifact', () => { it('is not mobile optimized when HTML contains an invalid viewport meta tag value', async () => { const viewport = 'initial-scale=microscopic'; const {isMobileOptimized, parserWarnings} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(isMobileOptimized, false); assert.equal(parserWarnings[0], 'Invalid values found: {"initial-scale":"microscopic"}'); }); @@ -48,7 +48,7 @@ describe('ViewportMeta computed artifact', () => { it('is not mobile optimized when HTML contains an invalid viewport meta tag key and value', async () => { const viewport = 'nonsense=true, initial-scale=microscopic'; const {isMobileOptimized, parserWarnings} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(isMobileOptimized, false); assert.equal(parserWarnings[0], 'Invalid properties found: {"nonsense":"true"}'); assert.equal(parserWarnings[1], 'Invalid values found: {"initial-scale":"microscopic"}'); @@ -64,7 +64,7 @@ describe('ViewportMeta computed artifact', () => { await Promise.all(viewports.map(async viewport => { const {isMobileOptimized} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(isMobileOptimized, true); })); }); @@ -76,7 +76,7 @@ describe('ViewportMeta computed artifact', () => { ]; await Promise.all(viewports.map(async viewport => { const {isMobileOptimized, parserWarnings} = - await ViewportMeta.compute_({MetaElements: makeMetaElements(viewport)}); + await ViewportMeta.compute_(makeMetaElements(viewport)); assert.equal(isMobileOptimized, true); assert.equal(parserWarnings[0], undefined); })); diff --git a/lighthouse-core/test/fixtures/artifacts/alphabet-artifacts/artifacts.json b/lighthouse-core/test/fixtures/artifacts/alphabet-artifacts/artifacts.json new file mode 100644 index 000000000000..d02ccb860b2a --- /dev/null +++ b/lighthouse-core/test/fixtures/artifacts/alphabet-artifacts/artifacts.json @@ -0,0 +1,11 @@ +{ + "URL": { + "requestedUrl": "https://example.com/", + "finalUrl": "https://example.com/" + }, + "ArtifactA": "apple", + "ArtifactB": "banana", + "ArtifactC": "cherry", + "ArtifactD": "date", + "Stacks": [] +} diff --git a/lighthouse-core/test/runner-test.js b/lighthouse-core/test/runner-test.js index 720c85dd7fca..d7c30af496ae 100644 --- a/lighthouse-core/test/runner-test.js +++ b/lighthouse-core/test/runner-test.js @@ -339,6 +339,38 @@ describe('Runner', () => { assert.ok(auditResult.errorMessage.includes(errorMessage)); }); }); + + it('only passes the required artifacts to the audit', async () => { + class SimpleAudit extends Audit { + static get meta() { + return { + id: 'simple', + title: 'Requires some artifacts', + failureTitle: 'Artifacts', + description: 'Test for always throwing', + requiredArtifacts: ['ArtifactA', 'ArtifactC'], + }; + } + } + + const auditMockFn = SimpleAudit.audit = jest.fn().mockReturnValue({score: 1}); + const config = new Config({ + settings: { + auditMode: __dirname + '/fixtures/artifacts/alphabet-artifacts/', + }, + audits: [ + SimpleAudit, + ], + }); + + const results = await Runner.run({}, {config}); + expect(results.lhr).toMatchObject({audits: {simple: {score: 1}}}); + expect(auditMockFn).toHaveBeenCalled(); + expect(auditMockFn.mock.calls[0][0]).toEqual({ + ArtifactA: 'apple', + ArtifactC: 'cherry', + }); + }); }); describe('Bad audit behavior handling', () => {