diff --git a/lighthouse-cli/test/smokehouse/offline-local/offline-expectations.js b/lighthouse-cli/test/smokehouse/offline-local/offline-expectations.js index 2866857a0d4e..9c456a769d48 100644 --- a/lighthouse-cli/test/smokehouse/offline-local/offline-expectations.js +++ b/lighthouse-cli/test/smokehouse/offline-local/offline-expectations.js @@ -81,22 +81,22 @@ module.exports = [ score: 0, }, 'aria-valid-attr': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'aria-allowed-attr': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'color-contrast': { score: 1, }, 'image-alt': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'label': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'tabindex': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'content-width': { score: 1, @@ -144,10 +144,10 @@ module.exports = [ score: 0, }, 'aria-valid-attr': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'aria-allowed-attr': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'color-contrast': { score: 1, @@ -156,10 +156,10 @@ module.exports = [ score: 0, }, 'label': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'tabindex': { - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, 'content-width': { score: 1, diff --git a/lighthouse-cli/test/smokehouse/pwa-expectations.js b/lighthouse-cli/test/smokehouse/pwa-expectations.js index 2d820f772b12..43d601aed17b 100644 --- a/lighthouse-cli/test/smokehouse/pwa-expectations.js +++ b/lighthouse-cli/test/smokehouse/pwa-expectations.js @@ -102,15 +102,15 @@ module.exports = [ // "manual" audits. Just verify in the results. 'pwa-cross-browser': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-page-transitions': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-each-page-has-url': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, }, }, @@ -207,15 +207,15 @@ module.exports = [ // "manual" audits. Just verify in the results. 'pwa-cross-browser': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-page-transitions': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-each-page-has-url': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, }, }, diff --git a/lighthouse-cli/test/smokehouse/pwa2-expectations.js b/lighthouse-cli/test/smokehouse/pwa2-expectations.js index d482f64a0e64..bca5ea5ee17c 100644 --- a/lighthouse-cli/test/smokehouse/pwa2-expectations.js +++ b/lighthouse-cli/test/smokehouse/pwa2-expectations.js @@ -104,15 +104,15 @@ module.exports = [ // "manual" audits. Just verify in the results. 'pwa-cross-browser': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-page-transitions': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-each-page-has-url': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, }, }, @@ -215,15 +215,15 @@ module.exports = [ // "manual" audits. Just verify in the results. 'pwa-cross-browser': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-page-transitions': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-each-page-has-url': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, }, }, diff --git a/lighthouse-cli/test/smokehouse/pwa3-expectations.js b/lighthouse-cli/test/smokehouse/pwa3-expectations.js index ad7de011d2fa..9d8530acf1b9 100644 --- a/lighthouse-cli/test/smokehouse/pwa3-expectations.js +++ b/lighthouse-cli/test/smokehouse/pwa3-expectations.js @@ -102,15 +102,15 @@ module.exports = [ // "manual" audits. Just verify in the results. 'pwa-cross-browser': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-page-transitions': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, 'pwa-each-page-has-url': { score: 0, - manual: true, + scoreDisplayMode: 'manual', }, }, }, diff --git a/lighthouse-cli/test/smokehouse/seo/expectations.js b/lighthouse-cli/test/smokehouse/seo/expectations.js index 133a00476a77..69ee0f8f2acc 100644 --- a/lighthouse-cli/test/smokehouse/seo/expectations.js +++ b/lighthouse-cli/test/smokehouse/seo/expectations.js @@ -73,7 +73,7 @@ module.exports = [ }, 'robots-txt': { rawValue: true, - notApplicable: true, + scoreDisplayMode: 'not-applicable', }, }, }, diff --git a/lighthouse-core/audits/audit.js b/lighthouse-core/audits/audit.js index 4766f8661371..a0e62abcc582 100644 --- a/lighthouse-core/audits/audit.js +++ b/lighthouse-core/audits/audit.js @@ -26,12 +26,15 @@ class Audit { } /** - * @return {LH.Audit.ScoringModes} + * @return {LH.Audit.ScoreDisplayModes} */ static get SCORING_MODES() { return { NUMERIC: 'numeric', BINARY: 'binary', + MANUAL: 'manual', + INFORMATIVE: 'informative', + NOT_APPLICABLE: 'not-applicable', }; } @@ -125,7 +128,7 @@ class Audit { /** * @param {typeof Audit} audit * @param {LH.Audit.Product} result - * @return {{score: number, scoreDisplayMode: LH.Audit.ScoringModeValue}} + * @return {{score: number, scoreDisplayMode: LH.Audit.ScoreDisplayMode}} */ static _normalizeAuditScore(audit, result) { // Cast true/false to 1/0 @@ -155,14 +158,12 @@ class Audit { throw new Error('generateAuditResult requires a rawValue'); } - // eslint-disable-next-line prefer-const let {score, scoreDisplayMode} = Audit._normalizeAuditScore(audit, result); // If the audit was determined to not apply to the page, we'll reset it as informative only - let informative = audit.meta.informative; if (result.notApplicable) { score = 1; - informative = true; + scoreDisplayMode = Audit.SCORING_MODES.NOT_APPLICABLE; result.rawValue = true; } @@ -181,9 +182,6 @@ class Audit { debugString: result.debugString, extendedInfo: result.extendedInfo, scoreDisplayMode, - informative, - manual: audit.meta.manual, - notApplicable: result.notApplicable, name: audit.meta.name, description: auditDescription, helpText: audit.meta.helpText, diff --git a/lighthouse-core/audits/byte-efficiency/offscreen-images.js b/lighthouse-core/audits/byte-efficiency/offscreen-images.js index 83c61c7dd6ff..3d7eecde0c73 100644 --- a/lighthouse-core/audits/byte-efficiency/offscreen-images.js +++ b/lighthouse-core/audits/byte-efficiency/offscreen-images.js @@ -29,7 +29,6 @@ class OffscreenImages extends ByteEfficiencyAudit { return { name: 'offscreen-images', description: 'Defer offscreen images', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Consider lazy-loading offscreen and hidden images after all critical resources have ' + diff --git a/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js b/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js index 647e6afd0aaa..1ab379563b18 100644 --- a/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +++ b/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js @@ -53,7 +53,6 @@ class RenderBlockingResources extends Audit { return { name: 'render-blocking-resources', description: 'Eliminate render-blocking resources', - informative: true, scoreDisplayMode: Audit.SCORING_MODES.NUMERIC, helpText: 'Resources are blocking the first paint of your page. Consider ' + diff --git a/lighthouse-core/audits/byte-efficiency/unminified-css.js b/lighthouse-core/audits/byte-efficiency/unminified-css.js index 7c553f4ba850..d061e56100ec 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-css.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-css.js @@ -22,7 +22,6 @@ class UnminifiedCSS extends ByteEfficiencyAudit { return { name: 'unminified-css', description: 'Minify CSS', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Minifying CSS files can reduce network payload sizes. ' + '[Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).', diff --git a/lighthouse-core/audits/byte-efficiency/unminified-javascript.js b/lighthouse-core/audits/byte-efficiency/unminified-javascript.js index ffc717818fa2..2168815d557a 100644 --- a/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +++ b/lighthouse-core/audits/byte-efficiency/unminified-javascript.js @@ -30,7 +30,7 @@ class UnminifiedJavaScript extends ByteEfficiencyAudit { return { name: 'unminified-javascript', description: 'Minify JavaScript', - informative: true, + scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Minifying JavaScript files can reduce payload sizes and script parse time. ' + '[Learn more](https://developers.google.com/speed/docs/insights/MinifyResources).', diff --git a/lighthouse-core/audits/byte-efficiency/unused-css-rules.js b/lighthouse-core/audits/byte-efficiency/unused-css-rules.js index 8106887a4806..db41e01d343c 100644 --- a/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +++ b/lighthouse-core/audits/byte-efficiency/unused-css-rules.js @@ -20,7 +20,6 @@ class UnusedCSSRules extends ByteEfficiencyAudit { return { name: 'unused-css-rules', description: 'Unused CSS rules', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Remove unused rules from stylesheets to reduce unnecessary ' + 'bytes consumed by network activity. ' + diff --git a/lighthouse-core/audits/byte-efficiency/unused-javascript.js b/lighthouse-core/audits/byte-efficiency/unused-javascript.js index e645a760f5e5..a05f98dc1c07 100644 --- a/lighthouse-core/audits/byte-efficiency/unused-javascript.js +++ b/lighthouse-core/audits/byte-efficiency/unused-javascript.js @@ -17,7 +17,6 @@ class UnusedJavaScript extends ByteEfficiencyAudit { return { name: 'unused-javascript', description: 'Unused JavaScript', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Remove unused JavaScript to reduce bytes consumed by network activity.', requiredArtifacts: ['JsUsage', 'devtoolsLogs'], diff --git a/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js b/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js index 491862fbdcf8..b32bb2c0c471 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js +++ b/lighthouse-core/audits/byte-efficiency/uses-optimized-images.js @@ -23,7 +23,6 @@ class UsesOptimizedImages extends ByteEfficiencyAudit { return { name: 'uses-optimized-images', description: 'Efficiently encode images', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Optimized images load faster and consume less cellular data. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/optimize-images).', diff --git a/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js b/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js index a973095a7538..7a8954e1eb65 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +++ b/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js @@ -27,7 +27,6 @@ class UsesResponsiveImages extends ByteEfficiencyAudit { return { name: 'uses-responsive-images', description: 'Properly size images', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Serve images that are appropriately-sized to save cellular data ' + diff --git a/lighthouse-core/audits/byte-efficiency/uses-text-compression.js b/lighthouse-core/audits/byte-efficiency/uses-text-compression.js index 60fbbe062ba1..163001359023 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +++ b/lighthouse-core/audits/byte-efficiency/uses-text-compression.js @@ -22,7 +22,6 @@ class ResponsesAreCompressed extends ByteEfficiencyAudit { static get meta() { return { name: 'uses-text-compression', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, description: 'Enable text compression', helpText: 'Text-based responses should be served with compression (gzip, deflate or brotli)' + diff --git a/lighthouse-core/audits/byte-efficiency/uses-webp-images.js b/lighthouse-core/audits/byte-efficiency/uses-webp-images.js index 34541920b43c..09a79a663665 100644 --- a/lighthouse-core/audits/byte-efficiency/uses-webp-images.js +++ b/lighthouse-core/audits/byte-efficiency/uses-webp-images.js @@ -22,7 +22,6 @@ class UsesWebPImages extends ByteEfficiencyAudit { return { name: 'uses-webp-images', description: 'Serve images in next-gen formats', - informative: true, scoreDisplayMode: ByteEfficiencyAudit.SCORING_MODES.NUMERIC, helpText: 'Image formats like JPEG 2000, JPEG XR, and WebP often provide better ' + 'compression than PNG or JPEG, which means faster downloads and less data consumption. ' + diff --git a/lighthouse-core/audits/critical-request-chains.js b/lighthouse-core/audits/critical-request-chains.js index bcc82694486c..748fa757618f 100644 --- a/lighthouse-core/audits/critical-request-chains.js +++ b/lighthouse-core/audits/critical-request-chains.js @@ -16,7 +16,7 @@ class CriticalRequestChains extends Audit { return { name: 'critical-request-chains', description: 'Critical Request Chains', - informative: true, + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, helpText: 'The Critical Request Chains below show you what resources are ' + 'issued with a high priority. Consider reducing ' + 'the length of chains, reducing the download size of resources, or ' + diff --git a/lighthouse-core/audits/manual/manual-audit.js b/lighthouse-core/audits/manual/manual-audit.js index 7f885ebd9c0e..0786fe335fbc 100644 --- a/lighthouse-core/audits/manual/manual-audit.js +++ b/lighthouse-core/audits/manual/manual-audit.js @@ -14,12 +14,11 @@ const Audit = require('../audit'); class ManualAudit extends Audit { /** - * @return {Pick} + * @return {Pick} */ static get partialMeta() { return { - informative: true, - manual: true, + scoreDisplayMode: Audit.SCORING_MODES.MANUAL, requiredArtifacts: [], }; } diff --git a/lighthouse-core/audits/metrics.js b/lighthouse-core/audits/metrics.js index 49bc60688752..c48e69229b91 100644 --- a/lighthouse-core/audits/metrics.js +++ b/lighthouse-core/audits/metrics.js @@ -14,7 +14,7 @@ class Metrics extends Audit { static get meta() { return { name: 'metrics', - informative: true, + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, description: 'Metrics', helpText: 'Collects all available metrics.', requiredArtifacts: ['traces', 'devtoolsLogs'], diff --git a/lighthouse-core/audits/mixed-content.js b/lighthouse-core/audits/mixed-content.js index bf1d8e7b5b57..f676ee7a7077 100644 --- a/lighthouse-core/audits/mixed-content.js +++ b/lighthouse-core/audits/mixed-content.js @@ -24,7 +24,6 @@ class MixedContent extends Audit { return { name: 'mixed-content', description: 'All resources loaded are secure', - informative: true, failureDescription: 'Some insecure resources can be upgraded to HTTPS', helpText: `Mixed content warnings can prevent you from upgrading to HTTPS. This audit shows which insecure resources this page uses that can be diff --git a/lighthouse-core/audits/network-requests.js b/lighthouse-core/audits/network-requests.js index 6659c92c439f..a60a41bbb361 100644 --- a/lighthouse-core/audits/network-requests.js +++ b/lighthouse-core/audits/network-requests.js @@ -15,7 +15,7 @@ class NetworkRequests extends Audit { static get meta() { return { name: 'network-requests', - informative: true, + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, description: 'Network Requests', helpText: 'Lists the network requests that were made during page load.', requiredArtifacts: ['devtoolsLogs'], diff --git a/lighthouse-core/audits/screenshot-thumbnails.js b/lighthouse-core/audits/screenshot-thumbnails.js index 0511dcea4ed9..693957e71f09 100644 --- a/lighthouse-core/audits/screenshot-thumbnails.js +++ b/lighthouse-core/audits/screenshot-thumbnails.js @@ -21,7 +21,7 @@ class ScreenshotThumbnails extends Audit { static get meta() { return { name: 'screenshot-thumbnails', - informative: true, + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, description: 'Screenshot Thumbnails', helpText: 'This is what the load of your site looked like.', requiredArtifacts: ['traces', 'devtoolsLogs'], diff --git a/lighthouse-core/audits/time-to-first-byte.js b/lighthouse-core/audits/time-to-first-byte.js index c325f3cc7afa..1372cfbf52f1 100644 --- a/lighthouse-core/audits/time-to-first-byte.js +++ b/lighthouse-core/audits/time-to-first-byte.js @@ -18,7 +18,6 @@ class TTFBMetric extends Audit { return { name: 'time-to-first-byte', description: 'Keep server response times low (TTFB)', - informative: true, helpText: 'Time To First Byte identifies the time at which your server sends a response.' + ' [Learn more](https://developers.google.com/web/tools/chrome-devtools/network-performance/issues).', requiredArtifacts: ['devtoolsLogs', 'URL'], diff --git a/lighthouse-core/audits/user-timings.js b/lighthouse-core/audits/user-timings.js index 33e14211aee5..7eb7cd347a73 100644 --- a/lighthouse-core/audits/user-timings.js +++ b/lighthouse-core/audits/user-timings.js @@ -17,12 +17,12 @@ class UserTimings extends Audit { static get meta() { return { name: 'user-timings', + scoreDisplayMode: Audit.SCORING_MODES.INFORMATIVE, description: 'User Timing marks and measures', helpText: 'Consider instrumenting your app with the User Timing API to create custom, ' + 'real-world measurements of key user experiences. ' + '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing).', requiredArtifacts: ['traces'], - informative: true, }; } diff --git a/lighthouse-core/audits/uses-rel-preconnect.js b/lighthouse-core/audits/uses-rel-preconnect.js index 8f83b7cbdee8..a7b4b2445863 100644 --- a/lighthouse-core/audits/uses-rel-preconnect.js +++ b/lighthouse-core/audits/uses-rel-preconnect.js @@ -24,7 +24,6 @@ class UsesRelPreconnectAudit extends Audit { return { name: 'uses-rel-preconnect', description: 'Avoid multiple, costly round trips to any origin', - informative: true, helpText: 'Consider adding preconnect or dns-prefetch resource hints to establish early ' + `connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).`, diff --git a/lighthouse-core/audits/uses-rel-preload.js b/lighthouse-core/audits/uses-rel-preload.js index 2724d26e808a..1221e42371dd 100644 --- a/lighthouse-core/audits/uses-rel-preload.js +++ b/lighthouse-core/audits/uses-rel-preload.js @@ -17,7 +17,6 @@ class UsesRelPreloadAudit extends Audit { return { name: 'uses-rel-preload', description: 'Preload key requests', - informative: true, helpText: 'Consider using to prioritize fetching late-discovered ' + 'resources sooner. [Learn more](https://developers.google.com/web/updates/2016/03/link-rel-preload).', requiredArtifacts: ['devtoolsLogs', 'traces', 'URL'], diff --git a/lighthouse-core/config/config.js b/lighthouse-core/config/config.js index 1f74f00970c5..9de9ab95309e 100644 --- a/lighthouse-core/config/config.js +++ b/lighthouse-core/config/config.js @@ -63,10 +63,15 @@ function validateCategories(categories, audits, groups) { } const auditImpl = audit.implementation; - if (categoryId === 'accessibility' && !auditRef.group && !auditImpl.meta.manual) { + const isManual = auditImpl.meta.scoreDisplayMode === 'manual'; + if (categoryId === 'accessibility' && !auditRef.group && !isManual) { throw new Error(`${auditRef.id} accessibility audit does not have a group`); } + if (auditRef.weight > 0 && isManual) { + throw new Error(`${auditRef.id} is manual but has a positive weight`); + } + if (auditRef.group && !groups[auditRef.group]) { throw new Error(`${auditRef.id} references unknown group ${auditRef.group}`); } @@ -94,8 +99,7 @@ function assertValidAudit(auditDefinition, auditPath) { // If it'll have a ✔ or ✖ displayed alongside the result, it should have failureDescription if (typeof auditDefinition.meta.failureDescription !== 'string' && - auditDefinition.meta.informative !== true && - auditDefinition.meta.scoreDisplayMode !== Audit.SCORING_MODES.NUMERIC) { + auditDefinition.meta.scoreDisplayMode === Audit.SCORING_MODES.BINARY) { throw new Error(`${auditName} has no failureDescription and should.`); } diff --git a/lighthouse-core/report/html/renderer/category-renderer.js b/lighthouse-core/report/html/renderer/category-renderer.js index 443267a9a7bd..d03606f59c99 100644 --- a/lighthouse-core/report/html/renderer/category-renderer.js +++ b/lighthouse-core/report/html/renderer/category-renderer.js @@ -50,14 +50,9 @@ class CategoryRenderer { header.appendChild(this.detailsRenderer.render(audit.result.details)); } - this.dom.find('.lh-audit__index', auditEl).textContent = `${index + 1}`; + auditEl.classList.add(`lh-audit--${audit.result.scoreDisplayMode}`); - if (audit.result.informative) { - auditEl.classList.add('lh-audit--informative'); - } - if (audit.result.manual) { - auditEl.classList.add('lh-audit--manual'); - } + this.dom.find('.lh-audit__index', auditEl).textContent = `${index + 1}`; this._setRatingClass(auditEl, audit.result.score, scoreDisplayMode, audit.result.error); @@ -255,7 +250,7 @@ class CategoryRenderer { this.createPermalinkSpan(element, category.id); element.appendChild(this.renderCategoryScore(category)); - const manualAudits = category.audits.filter(audit => audit.result.manual); + const manualAudits = category.audits.filter(item => item.result.scoreDisplayMode === 'manual'); const nonManualAudits = category.audits.filter(audit => !manualAudits.includes(audit)); const auditsGroupedByGroup = /** @type {!Object audit.group === 'diagnostics' && audit.result.score < 1) .sort((a, b) => { - const scoreA = a.result.informative ? 100 : a.result.score; - const scoreB = b.result.informative ? 100 : b.result.score; + const scoreA = a.result.scoreDisplayMode === 'informative' ? 100 : a.result.score; + const scoreB = b.result.scoreDisplayMode === 'informative' ? 100 : b.result.score; return scoreA - scoreB; }); diff --git a/lighthouse-core/report/html/renderer/report-renderer.js b/lighthouse-core/report/html/renderer/report-renderer.js index 9ad97e5f1042..6c8072a54adb 100644 --- a/lighthouse-core/report/html/renderer/report-renderer.js +++ b/lighthouse-core/report/html/renderer/report-renderer.js @@ -207,9 +207,6 @@ if (typeof module !== 'undefined' && module.exports) { * rawValue: (number|boolean|undefined), * name: string, * description: string, - * informative: (boolean|undefined), - * manual: (boolean|undefined), - * notApplicable: (boolean|undefined), * debugString: (string|undefined), * displayValue: (string|Array), * helpText: string, diff --git a/lighthouse-core/scoring.js b/lighthouse-core/scoring.js index 43d4e25173b3..1748d38fcdf5 100644 --- a/lighthouse-core/scoring.js +++ b/lighthouse-core/scoring.js @@ -6,6 +6,8 @@ 'use strict'; +const Audit = require('./audits/audit'); + /** * Clamp figure to 2 decimal places * @param {number} val @@ -54,7 +56,7 @@ class ReportScoring { // will still be included in the final report json and displayed in the report as // "Not Applicable". const result = resultsByAuditId[member.id]; - if (result.notApplicable) { + if (result.scoreDisplayMode === Audit.SCORING_MODES.NOT_APPLICABLE) { member.weight = 0; } return member; diff --git a/lighthouse-core/test/audits/audit-test.js b/lighthouse-core/test/audits/audit-test.js index 9b0a879735e5..592614b3e334 100644 --- a/lighthouse-core/test/audits/audit-test.js +++ b/lighthouse-core/test/audits/audit-test.js @@ -90,6 +90,6 @@ describe('Audit', () => { const providedResult = {rawValue: true, notApplicable: true}; const result = Audit.generateAuditResult(B, providedResult); assert.equal(result.score, 1); - assert.equal(result.informative, true); + assert.equal(result.scoreDisplayMode, 'not-applicable'); }); }); diff --git a/lighthouse-core/test/audits/manual-audit-test.js b/lighthouse-core/test/audits/manual-audit-test.js index dfc9eea4e56e..5319e26f8d8d 100644 --- a/lighthouse-core/test/audits/manual-audit-test.js +++ b/lighthouse-core/test/audits/manual-audit-test.js @@ -24,7 +24,6 @@ describe('ManualAudit', () => { it('sets defaults', () => { assert.equal(TestAudit.meta.name, 'manual-audit'); assert.equal(TestAudit.meta.requiredArtifacts.length, 0); - assert.equal(TestAudit.meta.informative, true); - assert.equal(TestAudit.meta.manual, true); + assert.equal(TestAudit.meta.scoreDisplayMode, 'manual'); }); }); diff --git a/lighthouse-core/test/config/config-test.js b/lighthouse-core/test/config/config-test.js index 56e5c8c3450a..4c6a1cc49017 100644 --- a/lighthouse-core/test/config/config-test.js +++ b/lighthouse-core/test/config/config-test.js @@ -271,6 +271,19 @@ describe('Config', () => { }), /unknown group missing-group/); }); + it('throws when a manual audit has weight', () => { + return assert.throws(_ => new Config({ + audits: ['manual/pwa-cross-browser'], + categories: { + accessibility: { + audits: [ + {id: 'pwa-cross-browser', weight: 10}, + ], + }, + }, + }), /cross-browser .*has a positive weight/); + }); + it('filters the config', () => { const config = new Config({ settings: { diff --git a/lighthouse-core/test/report/html/renderer/category-renderer-test.js b/lighthouse-core/test/report/html/renderer/category-renderer-test.js index eaf893c4ff61..81c498ea091d 100644 --- a/lighthouse-core/test/report/html/renderer/category-renderer-test.js +++ b/lighthouse-core/test/report/html/renderer/category-renderer-test.js @@ -80,7 +80,7 @@ describe('CategoryRenderer', () => { it('renders an informative audit', () => { const auditDOM = renderer.renderAudit({ id: 'informative', score: 0, - result: {description: 'It informs', helpText: 'help text', informative: true}, + result: {description: 'It informs', helpText: 'help text', scoreDisplayMode: 'informative'}, }); assert.ok(auditDOM.matches('.lh-audit--informative')); @@ -133,7 +133,7 @@ describe('CategoryRenderer', () => { const pwaCategory = sampleResults.reportCategories.find(cat => cat.id === 'pwa'); const categoryDOM = renderer.render(pwaCategory, sampleResults.reportGroups); assert.ok(categoryDOM.querySelector('.lh-audit-group--manual .lh-audit-group__summary')); - assert.equal(categoryDOM.querySelectorAll('.lh-audit--informative.lh-audit--manual').length, 3, + assert.equal(categoryDOM.querySelectorAll('.lh-audit--manual').length, 3, 'score shows informative and dash icon'); const perfCategory = sampleResults.reportCategories.find(cat => cat.id === 'performance'); @@ -147,9 +147,9 @@ describe('CategoryRenderer', () => { assert.ok(categoryDOM.querySelector('.lh-audit-group--notapplicable .lh-audit-group__summary')); const notApplicableCount = a11yCategory.audits.reduce((sum, audit) => - sum += audit.result.notApplicable ? 1 : 0, 0); + sum += audit.result.scoreDisplayMode === 'not-applicable' ? 1 : 0, 0); assert.equal( - categoryDOM.querySelectorAll('.lh-audit-group--notapplicable .lh-audit--informative').length, + categoryDOM.querySelectorAll('.lh-audit-group--notapplicable .lh-audit').length, notApplicableCount, 'score shows informative and dash icon' ); @@ -184,7 +184,7 @@ describe('CategoryRenderer', () => { it.skip('renders the failed audits grouped by group', () => { const categoryDOM = renderer.render(category, sampleResults.reportGroups); const failedAudits = category.audits.filter(audit => { - return audit.result.score !== 1 && !audit.result.notApplicable; + return audit.result.score !== 1 && !audit.result.scoreDisplayMode === 'not-applicable'; }); const failedAuditTags = new Set(failedAudits.map(audit => audit.group)); @@ -195,7 +195,7 @@ describe('CategoryRenderer', () => { it('renders the passed audits grouped by group', () => { const categoryDOM = renderer.render(category, sampleResults.reportGroups); const passedAudits = category.audits.filter(audit => - !audit.result.notApplicable && audit.result.score === 1); + audit.result.scoreDisplayMode !== 'not-applicable' && audit.result.score === 1); const passedAuditTags = new Set(passedAudits.map(audit => audit.group)); const passedAuditGroups = categoryDOM.querySelectorAll('.lh-passed-audits .lh-audit-group'); diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json index e00451e5da4d..41fcfdbba24c 100644 --- a/lighthouse-core/test/results/sample_v2.json +++ b/lighthouse-core/test/results/sample_v2.json @@ -132,8 +132,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, + "scoreDisplayMode": "informative", "name": "screenshot-thumbnails", "description": "Screenshot Thumbnails", "helpText": "This is what the load of your site looked like.", @@ -267,7 +266,6 @@ } }, "scoreDisplayMode": "binary", - "informative": true, "name": "time-to-first-byte", "description": "Keep server response times low (TTFB)", "helpText": "Time To First Byte identifies the time at which your server sends a response. [Learn more](https://developers.google.com/web/tools/chrome-devtools/network-performance/issues).", @@ -314,8 +312,7 @@ "extendedInfo": { "value": [] }, - "scoreDisplayMode": "binary", - "informative": true, + "scoreDisplayMode": "informative", "name": "user-timings", "description": "User Timing marks and measures", "helpText": "Consider instrumenting your app with the User Timing API to create custom, real-world measurements of key user experiences. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/user-timing).", @@ -481,8 +478,7 @@ } } }, - "scoreDisplayMode": "binary", - "informative": true, + "scoreDisplayMode": "informative", "name": "critical-request-chains", "description": "Critical Request Chains", "helpText": "The Critical Request Chains below show you what resources are issued with a high priority. Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains).", @@ -1078,7 +1074,6 @@ "value": [] }, "scoreDisplayMode": "numeric", - "informative": true, "name": "uses-rel-preload", "description": "Preload key requests", "helpText": "Consider using to prioritize fetching late-discovered resources sooner. [Learn more](https://developers.google.com/web/updates/2016/03/link-rel-preload).", @@ -1102,7 +1097,6 @@ "value": [] }, "scoreDisplayMode": "numeric", - "informative": true, "name": "uses-rel-preconnect", "description": "Avoid multiple, costly round trips to any origin", "helpText": "Consider adding preconnect or dns-prefetch resource hints to establish early connections to important third-party origins. [Learn more](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect).", @@ -1299,8 +1293,7 @@ } ] }, - "scoreDisplayMode": "binary", - "informative": true, + "scoreDisplayMode": "informative", "name": "network-requests", "description": "Network Requests", "helpText": "Lists the network requests that were made during page load.", @@ -1517,8 +1510,7 @@ "score": 1, "displayValue": "", "rawValue": 4927.278, - "scoreDisplayMode": "binary", - "informative": true, + "scoreDisplayMode": "informative", "name": "metrics", "description": "Metrics", "helpText": "Collects all available metrics.", @@ -1624,9 +1616,7 @@ "score": 0, "displayValue": "", "rawValue": false, - "scoreDisplayMode": "binary", - "informative": true, - "manual": true, + "scoreDisplayMode": "manual", "name": "pwa-cross-browser", "description": "Site works cross-browser", "helpText": "To reach the most number of users, sites should work across every major browser. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)." @@ -1635,9 +1625,7 @@ "score": 0, "displayValue": "", "rawValue": false, - "scoreDisplayMode": "binary", - "informative": true, - "manual": true, + "scoreDisplayMode": "manual", "name": "pwa-page-transitions", "description": "Page transitions don't feel like they block on the network", "helpText": "Transitions should feel snappy as you tap around, even on a slow network, a key to perceived performance. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)." @@ -1646,9 +1634,7 @@ "score": 0, "displayValue": "", "rawValue": false, - "scoreDisplayMode": "binary", - "informative": true, - "manual": true, + "scoreDisplayMode": "manual", "name": "pwa-each-page-has-url", "description": "Each page has a URL", "helpText": "Ensure individual pages are deep linkable via the URLs and that URLs are unique for the purpose of shareability on social media. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)." @@ -1657,9 +1643,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "accesskeys", "description": "`[accesskey]` values are unique", "helpText": "Access keys let users quickly focus a part of the page. For proper navigation, each access key must be unique. [Learn more](https://dequeuniversity.com/rules/axe/2.2/accesskeys?application=lighthouse)." @@ -1668,9 +1652,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-allowed-attr", "description": "`[aria-*]` attributes match their roles", "helpText": "Each ARIA `role` supports a specific subset of `aria-*` attributes. Mismatching these invalidates the `aria-*` attributes. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-allowed-attr?application=lighthouse)." @@ -1679,9 +1661,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-required-attr", "description": "`[role]`s have all required `[aria-*]` attributes", "helpText": "Some ARIA roles have required attributes that describe the state of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-attr?application=lighthouse)." @@ -1690,9 +1670,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-required-children", "description": "Elements with `[role]` that require specific children `[role]`s, are present", "helpText": "Some ARIA parent roles must contain specific child roles to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-children?application=lighthouse)." @@ -1701,9 +1679,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-required-parent", "description": "`[role]`s are contained by their required parent element", "helpText": "Some ARIA child roles must be contained by specific parent roles to properly perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-parent?application=lighthouse)." @@ -1712,9 +1688,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-roles", "description": "`[role]` values are valid", "helpText": "ARIA roles must have valid values in order to perform their intended accessibility functions. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-roles?application=lighthouse)." @@ -1723,9 +1697,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-valid-attr-value", "description": "`[aria-*]` attributes have valid values", "helpText": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid values. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr-value?application=lighthouse)." @@ -1734,9 +1706,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "aria-valid-attr", "description": "`[aria-*]` attributes are valid and not misspelled", "helpText": "Assistive technologies, like screen readers, can't interpret ARIA attributes with invalid names. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr?application=lighthouse)." @@ -1745,9 +1715,7 @@ "score": 1, "displayValue": "", "rawValue": true, - "scoreDisplayMode": "binary", - "informative": true, - "notApplicable": true, + "scoreDisplayMode": "not-applicable", "name": "audio-caption", "description": "`