diff --git a/cli/test/smokehouse/config/exclusions.js b/cli/test/smokehouse/config/exclusions.js index b7394776eb31..730f7267f183 100644 --- a/cli/test/smokehouse/config/exclusions.js +++ b/cli/test/smokehouse/config/exclusions.js @@ -20,6 +20,7 @@ const exclusions = { 'redirects-client-paint-server', 'redirects-multiple-server', 'redirects-single-server', 'redirects-single-client', 'redirects-history-push-state', 'redirects-scripts', + 'redirects-http', // Disabled because these tests use settings that cannot be fully configured in // DevTools (e.g. throttling method "provided"). 'metrics-tricky-tti', 'metrics-tricky-tti-late-fcp', 'screenshot', diff --git a/cli/test/smokehouse/core-tests.js b/cli/test/smokehouse/core-tests.js index 9d4ae94ebc26..1e243357eed8 100644 --- a/cli/test/smokehouse/core-tests.js +++ b/cli/test/smokehouse/core-tests.js @@ -52,6 +52,7 @@ import pwaRocks from './test-definitions/pwa-rocks.js'; import pwaSvgomg from './test-definitions/pwa-svgomg.js'; import redirectsClientPaintServer from './test-definitions/redirects-client-paint-server.js'; import redirectsHistoryPushState from './test-definitions/redirects-history-push-state.js'; +import redirectsHttp from './test-definitions/redirects-http.js'; import redirectsMultipleServer from './test-definitions/redirects-multiple-server.js'; import redirectsScripts from './test-definitions/redirects-scripts.js'; import redirectsSelf from './test-definitions/redirects-self.js'; @@ -116,6 +117,7 @@ const smokeTests = [ pwaSvgomg, redirectsClientPaintServer, redirectsHistoryPushState, + redirectsHttp, redirectsMultipleServer, redirectsScripts, redirectsSelf, diff --git a/cli/test/smokehouse/test-definitions/offline-online-only.js b/cli/test/smokehouse/test-definitions/offline-online-only.js index 89e1b9fab618..3de59f788b69 100644 --- a/cli/test/smokehouse/test-definitions/offline-online-only.js +++ b/cli/test/smokehouse/test-definitions/offline-online-only.js @@ -13,6 +13,7 @@ const config = { ], onlyAudits: [ 'is-on-https', + 'redirects-http', 'viewport', 'user-timings', 'critical-request-chains', @@ -43,6 +44,11 @@ const expectations = { 'is-on-https': { score: 1, }, + 'redirects-http': { + // localhost, so redirect check is n/a. + score: null, + scoreDisplayMode: 'notApplicable', + }, 'geolocation-on-start': { score: 1, }, diff --git a/cli/test/smokehouse/test-definitions/redirects-http.js b/cli/test/smokehouse/test-definitions/redirects-http.js new file mode 100644 index 000000000000..e53de28a2c28 --- /dev/null +++ b/cli/test/smokehouse/test-definitions/redirects-http.js @@ -0,0 +1,38 @@ +/** + * @license + * Copyright 2024 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @type {Smokehouse.ExpectedRunnerResult} + */ +const expectations = { + artifacts: { + URL: { + requestedUrl: 'http://jakearchibald.github.io/svgomg/', + mainDocumentUrl: 'https://jakearchibald.github.io/svgomg/', + finalDisplayedUrl: 'https://jakearchibald.github.io/svgomg/', + }, + }, + lhr: { + // Intentionally start out on http to test the redirect. + requestedUrl: 'http://jakearchibald.github.io/svgomg/', + finalDisplayedUrl: 'https://jakearchibald.github.io/svgomg/', + runWarnings: [ + 'The page may not be loading as expected because your test URL (http://jakearchibald.github.io/svgomg/) was redirected to https://jakearchibald.github.io/svgomg/. Try testing the second URL directly.', + ], + audits: { + 'redirects-http': { + score: 1, + }, + }, + }, +}; + +export default { + id: 'redirects-http', + expectations, +}; + + diff --git a/core/audits/redirects-http.js b/core/audits/redirects-http.js new file mode 100644 index 000000000000..a19363449417 --- /dev/null +++ b/core/audits/redirects-http.js @@ -0,0 +1,75 @@ +/** + * @license Copyright 2024 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +import {Audit} from './audit.js'; +import * as i18n from '../lib/i18n/i18n.js'; +import UrlUtils from '../lib/url-utils.js'; + +const UIStrings = { + /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is redirected to HTTPS. */ + title: 'Redirects HTTP traffic to HTTPS', + /** Title of a Lighthouse audit that provides detail on HTTP to HTTPS redirects. This descriptive title is shown to users when HTTP traffic is not redirected to HTTPS. */ + failureTitle: 'Does not redirect HTTP traffic to HTTPS', + /** Description of a Lighthouse audit that tells the user why they should direct HTTP traffic to HTTPS. This is displayed after a user expands the section to see more. No character length limits. 'Learn More' becomes link text to additional documentation. */ + description: 'Make sure that you redirect all HTTP ' + + 'traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).', +}; + +const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings); + +/** + * An audit for checking if a site starting on http redirects to https. The audit + * is marked not applicable if the requestedUrl is already https. + */ +class RedirectsHTTP extends Audit { + /** + * @return {LH.Audit.Meta} + */ + static get meta() { + return { + id: 'redirects-http', + title: str_(UIStrings.title), + failureTitle: str_(UIStrings.failureTitle), + description: str_(UIStrings.description), + requiredArtifacts: ['URL'], + supportedModes: ['navigation'], + }; + } + + /** + * @param {LH.Artifacts} artifacts + * @return {LH.Audit.Product} + */ + static audit(artifacts) { + if (!artifacts.URL.requestedUrl) { + throw new Error('Missing requestedUrl'); + } + + const requestedUrl = new URL(artifacts.URL.requestedUrl); + const finalDisplayedUrl = new URL(artifacts.URL.finalDisplayedUrl); + + // Not applicable unless starting on http. + const startedInsecure = requestedUrl.protocol === 'http:'; + + // Relax requirements on localhost. + const isLocalhost = UrlUtils.isLikeLocalhost(finalDisplayedUrl.hostname); + + if (!startedInsecure || isLocalhost) { + return { + score: null, + notApplicable: true, + }; + } + + const endedSecure = finalDisplayedUrl.protocol === 'https:'; + return { + score: Number(endedSecure), + }; + } +} + +export default RedirectsHTTP; +export {UIStrings}; diff --git a/core/config/default-config.js b/core/config/default-config.js index e41fdac98eb6..caaa5266cd4b 100644 --- a/core/config/default-config.js +++ b/core/config/default-config.js @@ -168,6 +168,7 @@ const defaultConfig = { ], audits: [ 'is-on-https', + 'redirects-http', 'viewport', 'metrics/first-contentful-paint', 'metrics/largest-contentful-paint', @@ -574,6 +575,7 @@ const defaultConfig = { auditRefs: [ // Trust & Safety {id: 'is-on-https', weight: 5, group: 'best-practices-trust-safety'}, + {id: 'redirects-http', weight: 1, group: 'best-practices-trust-safety'}, {id: 'geolocation-on-start', weight: 1, group: 'best-practices-trust-safety'}, {id: 'notification-on-start', weight: 1, group: 'best-practices-trust-safety'}, {id: 'csp-xss', weight: 0, group: 'best-practices-trust-safety'}, diff --git a/core/test/audits/redirects-http-test.js b/core/test/audits/redirects-http-test.js new file mode 100644 index 000000000000..fbb5fc7afb47 --- /dev/null +++ b/core/test/audits/redirects-http-test.js @@ -0,0 +1,63 @@ +/** + * @license Copyright 2024 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +import {strict as assert} from 'assert'; + +import RedirectsHTTP from '../../audits/redirects-http.js'; + +describe('Security: HTTP->HTTPS audit', () => { + it('fails when no redirect detected', () => { + return assert.equal(RedirectsHTTP.audit({ + URL: { + requestedUrl: 'http://example.com/', + finalDisplayedUrl: 'http://example.com/', + }, + }).score, 0); + }); + + it('passes when redirect detected', () => { + return assert.equal(RedirectsHTTP.audit({ + URL: { + requestedUrl: 'http://paulirish.com/', + finalDisplayedUrl: 'https://paulirish.com/', + }, + }).score, 1); + }); + + it('not applicable on localhost', () => { + const product = RedirectsHTTP.audit({ + URL: { + requestedUrl: 'http://localhost:8080/page.html', + finalDisplayedUrl: 'https://localhost:8080/page.html', + }, + }); + + assert.equal(product.score, null); + assert.equal(product.notApplicable, true); + }); + + it('not applicable if requestedUrl is secure', () => { + const product = RedirectsHTTP.audit({ + URL: { + requestedUrl: 'https://example.com/', + finalDisplayedUrl: 'https://example.com/', + }, + }); + + assert.equal(product.score, null); + assert.equal(product.notApplicable, true); + }); + + it('throws if requestedUrl is missing', () => { + assert.throws(() => { + RedirectsHTTP.audit({ + URL: { + finalDisplayedUrl: 'https://example.com/', + }, + }); + }, new Error('Missing requestedUrl')); + }); +}); diff --git a/core/test/fixtures/user-flows/reports/sample-flow-result.json b/core/test/fixtures/user-flows/reports/sample-flow-result.json index dce6dc1f5259..6711f858d785 100644 --- a/core/test/fixtures/user-flows/reports/sample-flow-result.json +++ b/core/test/fixtures/user-flows/reports/sample-flow-result.json @@ -32,6 +32,13 @@ "items": [] } }, + "redirects-http": { + "id": "redirects-http", + "title": "Redirects HTTP traffic to HTTPS", + "description": "Make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, "viewport": { "id": "viewport", "title": "Has a `` tag with `width` or `initial-scale`", @@ -4426,6 +4433,11 @@ "weight": 5, "group": "best-practices-trust-safety" }, + { + "id": "redirects-http", + "weight": 0, + "group": "best-practices-trust-safety" + }, { "id": "geolocation-on-start", "weight": 1, @@ -5602,547 +5614,547 @@ }, { "startTime": 64, - "name": "lh:audit:viewport", + "name": "lh:audit:redirects-http", "duration": 1, "entryType": "measure" }, { "startTime": 65, - "name": "lh:computed:ViewportMeta", + "name": "lh:audit:viewport", "duration": 1, "entryType": "measure" }, { "startTime": 66, - "name": "lh:audit:first-contentful-paint", + "name": "lh:computed:ViewportMeta", "duration": 1, "entryType": "measure" }, { "startTime": 67, - "name": "lh:computed:FirstContentfulPaint", + "name": "lh:audit:first-contentful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 68, - "name": "lh:computed:ProcessedTrace", + "name": "lh:computed:FirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 69, - "name": "lh:computed:ProcessedNavigation", + "name": "lh:computed:ProcessedTrace", "duration": 1, "entryType": "measure" }, { "startTime": 70, - "name": "lh:computed:LanternFirstContentfulPaint", + "name": "lh:computed:ProcessedNavigation", "duration": 1, "entryType": "measure" }, { "startTime": 71, - "name": "lh:computed:PageDependencyGraph", + "name": "lh:computed:LanternFirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 72, - "name": "lh:computed:LoadSimulator", + "name": "lh:computed:PageDependencyGraph", "duration": 1, "entryType": "measure" }, { "startTime": 73, - "name": "lh:computed:NetworkAnalysis", + "name": "lh:computed:LoadSimulator", "duration": 1, "entryType": "measure" }, { "startTime": 74, - "name": "lh:audit:largest-contentful-paint", + "name": "lh:computed:NetworkAnalysis", "duration": 1, "entryType": "measure" }, { "startTime": 75, - "name": "lh:computed:LargestContentfulPaint", + "name": "lh:audit:largest-contentful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 76, - "name": "lh:computed:LanternLargestContentfulPaint", + "name": "lh:computed:LargestContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 77, - "name": "lh:audit:first-meaningful-paint", + "name": "lh:computed:LanternLargestContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 78, - "name": "lh:computed:FirstMeaningfulPaint", + "name": "lh:audit:first-meaningful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 79, - "name": "lh:computed:LanternFirstMeaningfulPaint", + "name": "lh:computed:FirstMeaningfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 80, - "name": "lh:audit:speed-index", + "name": "lh:computed:LanternFirstMeaningfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 81, - "name": "lh:computed:SpeedIndex", + "name": "lh:audit:speed-index", "duration": 1, "entryType": "measure" }, { "startTime": 82, - "name": "lh:computed:LanternSpeedIndex", + "name": "lh:computed:SpeedIndex", "duration": 1, "entryType": "measure" }, { "startTime": 83, - "name": "lh:computed:Speedline", + "name": "lh:computed:LanternSpeedIndex", "duration": 1, "entryType": "measure" }, { "startTime": 84, - "name": "lh:audit:screenshot-thumbnails", + "name": "lh:computed:Speedline", "duration": 1, "entryType": "measure" }, { "startTime": 85, - "name": "lh:audit:final-screenshot", + "name": "lh:audit:screenshot-thumbnails", "duration": 1, "entryType": "measure" }, { "startTime": 86, - "name": "lh:computed:Screenshots", + "name": "lh:audit:final-screenshot", "duration": 1, "entryType": "measure" }, { "startTime": 87, - "name": "lh:audit:total-blocking-time", + "name": "lh:computed:Screenshots", "duration": 1, "entryType": "measure" }, { "startTime": 88, - "name": "lh:computed:TotalBlockingTime", + "name": "lh:audit:total-blocking-time", "duration": 1, "entryType": "measure" }, { "startTime": 89, - "name": "lh:computed:LanternTotalBlockingTime", + "name": "lh:computed:TotalBlockingTime", "duration": 1, "entryType": "measure" }, { "startTime": 90, - "name": "lh:computed:LanternInteractive", + "name": "lh:computed:LanternTotalBlockingTime", "duration": 1, "entryType": "measure" }, { "startTime": 91, - "name": "lh:audit:max-potential-fid", + "name": "lh:computed:LanternInteractive", "duration": 1, "entryType": "measure" }, { "startTime": 92, - "name": "lh:computed:MaxPotentialFID", + "name": "lh:audit:max-potential-fid", "duration": 1, "entryType": "measure" }, { "startTime": 93, - "name": "lh:computed:LanternMaxPotentialFID", + "name": "lh:computed:MaxPotentialFID", "duration": 1, "entryType": "measure" }, { "startTime": 94, - "name": "lh:audit:cumulative-layout-shift", + "name": "lh:computed:LanternMaxPotentialFID", "duration": 1, "entryType": "measure" }, { "startTime": 95, - "name": "lh:computed:CumulativeLayoutShift", + "name": "lh:audit:cumulative-layout-shift", "duration": 1, "entryType": "measure" }, { "startTime": 96, - "name": "lh:audit:errors-in-console", + "name": "lh:computed:CumulativeLayoutShift", "duration": 1, "entryType": "measure" }, { "startTime": 97, - "name": "lh:computed:JSBundles", + "name": "lh:audit:errors-in-console", "duration": 1, "entryType": "measure" }, { "startTime": 98, - "name": "lh:audit:server-response-time", + "name": "lh:computed:JSBundles", "duration": 1, "entryType": "measure" }, { "startTime": 99, - "name": "lh:computed:MainResource", + "name": "lh:audit:server-response-time", "duration": 1, "entryType": "measure" }, { "startTime": 100, - "name": "lh:audit:interactive", + "name": "lh:computed:MainResource", "duration": 1, "entryType": "measure" }, { "startTime": 101, - "name": "lh:computed:Interactive", + "name": "lh:audit:interactive", "duration": 1, "entryType": "measure" }, { "startTime": 102, - "name": "lh:audit:user-timings", + "name": "lh:computed:Interactive", "duration": 1, "entryType": "measure" }, { "startTime": 103, - "name": "lh:computed:UserTimings", + "name": "lh:audit:user-timings", "duration": 1, "entryType": "measure" }, { "startTime": 104, - "name": "lh:audit:critical-request-chains", + "name": "lh:computed:UserTimings", "duration": 1, "entryType": "measure" }, { "startTime": 105, - "name": "lh:computed:CriticalRequestChains", + "name": "lh:audit:critical-request-chains", "duration": 1, "entryType": "measure" }, { "startTime": 106, - "name": "lh:audit:redirects", + "name": "lh:computed:CriticalRequestChains", "duration": 1, "entryType": "measure" }, { "startTime": 107, - "name": "lh:audit:installable-manifest", + "name": "lh:audit:redirects", "duration": 1, "entryType": "measure" }, { "startTime": 108, - "name": "lh:audit:splash-screen", + "name": "lh:audit:installable-manifest", "duration": 1, "entryType": "measure" }, { "startTime": 109, - "name": "lh:computed:ManifestValues", + "name": "lh:audit:splash-screen", "duration": 1, "entryType": "measure" }, { "startTime": 110, - "name": "lh:audit:themed-omnibox", + "name": "lh:computed:ManifestValues", "duration": 1, "entryType": "measure" }, { "startTime": 111, - "name": "lh:audit:maskable-icon", + "name": "lh:audit:themed-omnibox", "duration": 1, "entryType": "measure" }, { "startTime": 112, - "name": "lh:audit:content-width", + "name": "lh:audit:maskable-icon", "duration": 1, "entryType": "measure" }, { "startTime": 113, - "name": "lh:audit:image-aspect-ratio", + "name": "lh:audit:content-width", "duration": 1, "entryType": "measure" }, { "startTime": 114, - "name": "lh:audit:image-size-responsive", + "name": "lh:audit:image-aspect-ratio", "duration": 1, "entryType": "measure" }, { "startTime": 115, - "name": "lh:audit:deprecations", + "name": "lh:audit:image-size-responsive", "duration": 1, "entryType": "measure" }, { "startTime": 116, - "name": "lh:audit:third-party-cookies", + "name": "lh:audit:deprecations", "duration": 1, "entryType": "measure" }, { "startTime": 117, - "name": "lh:audit:mainthread-work-breakdown", + "name": "lh:audit:third-party-cookies", "duration": 1, "entryType": "measure" }, { "startTime": 118, - "name": "lh:computed:MainThreadTasks", + "name": "lh:audit:mainthread-work-breakdown", "duration": 1, "entryType": "measure" }, { "startTime": 119, - "name": "lh:audit:bootup-time", + "name": "lh:computed:MainThreadTasks", "duration": 1, "entryType": "measure" }, { "startTime": 120, - "name": "lh:computed:TBTImpactTasks", + "name": "lh:audit:bootup-time", "duration": 1, "entryType": "measure" }, { "startTime": 121, - "name": "lh:audit:uses-rel-preconnect", + "name": "lh:computed:TBTImpactTasks", "duration": 1, "entryType": "measure" }, { "startTime": 122, - "name": "lh:audit:font-display", + "name": "lh:audit:uses-rel-preconnect", "duration": 1, "entryType": "measure" }, { "startTime": 123, - "name": "lh:audit:diagnostics", + "name": "lh:audit:font-display", "duration": 1, "entryType": "measure" }, { "startTime": 124, - "name": "lh:audit:network-requests", + "name": "lh:audit:diagnostics", "duration": 1, "entryType": "measure" }, { "startTime": 125, - "name": "lh:computed:EntityClassification", + "name": "lh:audit:network-requests", "duration": 1, "entryType": "measure" }, { "startTime": 126, - "name": "lh:audit:network-rtt", + "name": "lh:computed:EntityClassification", "duration": 1, "entryType": "measure" }, { "startTime": 127, - "name": "lh:audit:network-server-latency", + "name": "lh:audit:network-rtt", "duration": 1, "entryType": "measure" }, { "startTime": 128, - "name": "lh:audit:main-thread-tasks", + "name": "lh:audit:network-server-latency", "duration": 1, "entryType": "measure" }, { "startTime": 129, - "name": "lh:audit:metrics", + "name": "lh:audit:main-thread-tasks", "duration": 1, "entryType": "measure" }, { "startTime": 130, - "name": "lh:computed:TimingSummary", + "name": "lh:audit:metrics", "duration": 1, "entryType": "measure" }, { "startTime": 131, - "name": "lh:computed:FirstContentfulPaintAllFrames", + "name": "lh:computed:TimingSummary", "duration": 1, "entryType": "measure" }, { "startTime": 132, - "name": "lh:computed:LargestContentfulPaintAllFrames", + "name": "lh:computed:FirstContentfulPaintAllFrames", "duration": 1, "entryType": "measure" }, { "startTime": 133, - "name": "lh:computed:LCPBreakdown", + "name": "lh:computed:LargestContentfulPaintAllFrames", "duration": 1, "entryType": "measure" }, { "startTime": 134, - "name": "lh:computed:TimeToFirstByte", + "name": "lh:computed:LCPBreakdown", "duration": 1, "entryType": "measure" }, { "startTime": 135, - "name": "lh:computed:LCPImageRecord", + "name": "lh:computed:TimeToFirstByte", "duration": 1, "entryType": "measure" }, { "startTime": 136, - "name": "lh:audit:performance-budget", + "name": "lh:computed:LCPImageRecord", "duration": 1, "entryType": "measure" }, { "startTime": 137, - "name": "lh:computed:ResourceSummary", + "name": "lh:audit:performance-budget", "duration": 1, "entryType": "measure" }, { "startTime": 138, - "name": "lh:audit:timing-budget", + "name": "lh:computed:ResourceSummary", "duration": 1, "entryType": "measure" }, { "startTime": 139, - "name": "lh:audit:resource-summary", + "name": "lh:audit:timing-budget", "duration": 1, "entryType": "measure" }, { "startTime": 140, - "name": "lh:audit:third-party-summary", + "name": "lh:audit:resource-summary", "duration": 1, "entryType": "measure" }, { "startTime": 141, - "name": "lh:audit:third-party-facades", + "name": "lh:audit:third-party-summary", "duration": 1, "entryType": "measure" }, { "startTime": 142, - "name": "lh:audit:largest-contentful-paint-element", + "name": "lh:audit:third-party-facades", "duration": 1, "entryType": "measure" }, { "startTime": 143, - "name": "lh:audit:lcp-lazy-loaded", + "name": "lh:audit:largest-contentful-paint-element", "duration": 1, "entryType": "measure" }, { "startTime": 144, - "name": "lh:audit:layout-shifts", + "name": "lh:audit:lcp-lazy-loaded", "duration": 1, "entryType": "measure" }, { "startTime": 145, - "name": "lh:computed:TraceEngineResult", + "name": "lh:audit:layout-shifts", "duration": 1, "entryType": "measure" }, { "startTime": 146, - "name": "lh:audit:long-tasks", + "name": "lh:computed:TraceEngineResult", "duration": 1, "entryType": "measure" }, { "startTime": 147, - "name": "lh:audit:non-composited-animations", + "name": "lh:audit:long-tasks", "duration": 1, "entryType": "measure" }, { "startTime": 148, - "name": "lh:audit:unsized-images", + "name": "lh:audit:non-composited-animations", "duration": 1, "entryType": "measure" }, { "startTime": 149, - "name": "lh:audit:valid-source-maps", + "name": "lh:audit:unsized-images", "duration": 1, "entryType": "measure" }, { "startTime": 150, - "name": "lh:audit:prioritize-lcp-image", + "name": "lh:audit:valid-source-maps", "duration": 1, "entryType": "measure" }, { "startTime": 151, - "name": "lh:audit:csp-xss", + "name": "lh:audit:prioritize-lcp-image", "duration": 1, "entryType": "measure" }, { "startTime": 152, - "name": "lh:audit:script-treemap-data", + "name": "lh:audit:csp-xss", "duration": 1, "entryType": "measure" }, { "startTime": 153, - "name": "lh:computed:ModuleDuplication", + "name": "lh:audit:script-treemap-data", "duration": 1, "entryType": "measure" }, { "startTime": 154, - "name": "lh:computed:UnusedJavascriptSummary", + "name": "lh:computed:ModuleDuplication", "duration": 1, "entryType": "measure" }, @@ -6226,684 +6238,690 @@ }, { "startTime": 168, - "name": "lh:audit:pwa-cross-browser", + "name": "lh:computed:UnusedJavascriptSummary", "duration": 1, "entryType": "measure" }, { "startTime": 169, - "name": "lh:audit:pwa-page-transitions", + "name": "lh:audit:pwa-cross-browser", "duration": 1, "entryType": "measure" }, { "startTime": 170, - "name": "lh:audit:pwa-each-page-has-url", + "name": "lh:audit:pwa-page-transitions", "duration": 1, "entryType": "measure" }, { "startTime": 171, - "name": "lh:audit:accesskeys", + "name": "lh:audit:pwa-each-page-has-url", "duration": 1, "entryType": "measure" }, { "startTime": 172, - "name": "lh:audit:aria-allowed-attr", + "name": "lh:audit:accesskeys", "duration": 1, "entryType": "measure" }, { "startTime": 173, - "name": "lh:audit:aria-allowed-role", + "name": "lh:audit:aria-allowed-attr", "duration": 1, "entryType": "measure" }, { "startTime": 174, - "name": "lh:audit:aria-command-name", + "name": "lh:audit:aria-allowed-role", "duration": 1, "entryType": "measure" }, { "startTime": 175, - "name": "lh:audit:aria-dialog-name", + "name": "lh:audit:aria-command-name", "duration": 1, "entryType": "measure" }, { "startTime": 176, - "name": "lh:audit:aria-hidden-body", + "name": "lh:audit:aria-dialog-name", "duration": 1, "entryType": "measure" }, { "startTime": 177, - "name": "lh:audit:aria-hidden-focus", + "name": "lh:audit:aria-hidden-body", "duration": 1, "entryType": "measure" }, { "startTime": 178, - "name": "lh:audit:aria-input-field-name", + "name": "lh:audit:aria-hidden-focus", "duration": 1, "entryType": "measure" }, { "startTime": 179, - "name": "lh:audit:aria-meter-name", + "name": "lh:audit:aria-input-field-name", "duration": 1, "entryType": "measure" }, { "startTime": 180, - "name": "lh:audit:aria-progressbar-name", + "name": "lh:audit:aria-meter-name", "duration": 1, "entryType": "measure" }, { "startTime": 181, - "name": "lh:audit:aria-required-attr", + "name": "lh:audit:aria-progressbar-name", "duration": 1, "entryType": "measure" }, { "startTime": 182, - "name": "lh:audit:aria-required-children", + "name": "lh:audit:aria-required-attr", "duration": 1, "entryType": "measure" }, { "startTime": 183, - "name": "lh:audit:aria-required-parent", + "name": "lh:audit:aria-required-children", "duration": 1, "entryType": "measure" }, { "startTime": 184, - "name": "lh:audit:aria-roles", + "name": "lh:audit:aria-required-parent", "duration": 1, "entryType": "measure" }, { "startTime": 185, - "name": "lh:audit:aria-text", + "name": "lh:audit:aria-roles", "duration": 1, "entryType": "measure" }, { "startTime": 186, - "name": "lh:audit:aria-toggle-field-name", + "name": "lh:audit:aria-text", "duration": 1, "entryType": "measure" }, { "startTime": 187, - "name": "lh:audit:aria-tooltip-name", + "name": "lh:audit:aria-toggle-field-name", "duration": 1, "entryType": "measure" }, { "startTime": 188, - "name": "lh:audit:aria-treeitem-name", + "name": "lh:audit:aria-tooltip-name", "duration": 1, "entryType": "measure" }, { "startTime": 189, - "name": "lh:audit:aria-valid-attr-value", + "name": "lh:audit:aria-treeitem-name", "duration": 1, "entryType": "measure" }, { "startTime": 190, - "name": "lh:audit:aria-valid-attr", + "name": "lh:audit:aria-valid-attr-value", "duration": 1, "entryType": "measure" }, { "startTime": 191, - "name": "lh:audit:button-name", + "name": "lh:audit:aria-valid-attr", "duration": 1, "entryType": "measure" }, { "startTime": 192, - "name": "lh:audit:bypass", + "name": "lh:audit:button-name", "duration": 1, "entryType": "measure" }, { "startTime": 193, - "name": "lh:audit:color-contrast", + "name": "lh:audit:bypass", "duration": 1, "entryType": "measure" }, { "startTime": 194, - "name": "lh:audit:definition-list", + "name": "lh:audit:color-contrast", "duration": 1, "entryType": "measure" }, { "startTime": 195, - "name": "lh:audit:dlitem", + "name": "lh:audit:definition-list", "duration": 1, "entryType": "measure" }, { "startTime": 196, - "name": "lh:audit:document-title", + "name": "lh:audit:dlitem", "duration": 1, "entryType": "measure" }, { "startTime": 197, - "name": "lh:audit:duplicate-id-aria", + "name": "lh:audit:document-title", "duration": 1, "entryType": "measure" }, { "startTime": 198, - "name": "lh:audit:empty-heading", + "name": "lh:audit:duplicate-id-aria", "duration": 1, "entryType": "measure" }, { "startTime": 199, - "name": "lh:audit:form-field-multiple-labels", + "name": "lh:audit:empty-heading", "duration": 1, "entryType": "measure" }, { "startTime": 200, - "name": "lh:audit:frame-title", + "name": "lh:audit:form-field-multiple-labels", "duration": 1, "entryType": "measure" }, { "startTime": 201, - "name": "lh:audit:heading-order", + "name": "lh:audit:frame-title", "duration": 1, "entryType": "measure" }, { "startTime": 202, - "name": "lh:audit:html-has-lang", + "name": "lh:audit:heading-order", "duration": 1, "entryType": "measure" }, { "startTime": 203, - "name": "lh:audit:html-lang-valid", + "name": "lh:audit:html-has-lang", "duration": 1, "entryType": "measure" }, { "startTime": 204, - "name": "lh:audit:html-xml-lang-mismatch", + "name": "lh:audit:html-lang-valid", "duration": 1, "entryType": "measure" }, { "startTime": 205, - "name": "lh:audit:identical-links-same-purpose", + "name": "lh:audit:html-xml-lang-mismatch", "duration": 1, "entryType": "measure" }, { "startTime": 206, - "name": "lh:audit:image-alt", + "name": "lh:audit:identical-links-same-purpose", "duration": 1, "entryType": "measure" }, { "startTime": 207, - "name": "lh:audit:image-redundant-alt", + "name": "lh:audit:image-alt", "duration": 1, "entryType": "measure" }, { "startTime": 208, - "name": "lh:audit:input-button-name", + "name": "lh:audit:image-redundant-alt", "duration": 1, "entryType": "measure" }, { "startTime": 209, - "name": "lh:audit:input-image-alt", + "name": "lh:audit:input-button-name", "duration": 1, "entryType": "measure" }, { "startTime": 210, - "name": "lh:audit:label-content-name-mismatch", + "name": "lh:audit:input-image-alt", "duration": 1, "entryType": "measure" }, { "startTime": 211, - "name": "lh:audit:label", + "name": "lh:audit:label-content-name-mismatch", "duration": 1, "entryType": "measure" }, { "startTime": 212, - "name": "lh:audit:landmark-one-main", + "name": "lh:audit:label", "duration": 1, "entryType": "measure" }, { "startTime": 213, - "name": "lh:audit:link-name", + "name": "lh:audit:landmark-one-main", "duration": 1, "entryType": "measure" }, { "startTime": 214, - "name": "lh:audit:link-in-text-block", + "name": "lh:audit:link-name", "duration": 1, "entryType": "measure" }, { "startTime": 215, - "name": "lh:audit:list", + "name": "lh:audit:link-in-text-block", "duration": 1, "entryType": "measure" }, { "startTime": 216, - "name": "lh:audit:listitem", + "name": "lh:audit:list", "duration": 1, "entryType": "measure" }, { "startTime": 217, - "name": "lh:audit:meta-refresh", + "name": "lh:audit:listitem", "duration": 1, "entryType": "measure" }, { "startTime": 218, - "name": "lh:audit:meta-viewport", + "name": "lh:audit:meta-refresh", "duration": 1, "entryType": "measure" }, { "startTime": 219, - "name": "lh:audit:object-alt", + "name": "lh:audit:meta-viewport", "duration": 1, "entryType": "measure" }, { "startTime": 220, - "name": "lh:audit:select-name", + "name": "lh:audit:object-alt", "duration": 1, "entryType": "measure" }, { "startTime": 221, - "name": "lh:audit:skip-link", + "name": "lh:audit:select-name", "duration": 1, "entryType": "measure" }, { "startTime": 222, - "name": "lh:audit:tabindex", + "name": "lh:audit:skip-link", "duration": 1, "entryType": "measure" }, { "startTime": 223, - "name": "lh:audit:table-duplicate-name", + "name": "lh:audit:tabindex", "duration": 1, "entryType": "measure" }, { "startTime": 224, - "name": "lh:audit:table-fake-caption", + "name": "lh:audit:table-duplicate-name", "duration": 1, "entryType": "measure" }, { "startTime": 225, - "name": "lh:audit:target-size", + "name": "lh:audit:table-fake-caption", "duration": 1, "entryType": "measure" }, { "startTime": 226, - "name": "lh:audit:td-has-header", + "name": "lh:audit:target-size", "duration": 1, "entryType": "measure" }, { "startTime": 227, - "name": "lh:audit:td-headers-attr", + "name": "lh:audit:td-has-header", "duration": 1, "entryType": "measure" }, { "startTime": 228, - "name": "lh:audit:th-has-data-cells", + "name": "lh:audit:td-headers-attr", "duration": 1, "entryType": "measure" }, { "startTime": 229, - "name": "lh:audit:valid-lang", + "name": "lh:audit:th-has-data-cells", "duration": 1, "entryType": "measure" }, { "startTime": 230, - "name": "lh:audit:video-caption", + "name": "lh:audit:valid-lang", "duration": 1, "entryType": "measure" }, { "startTime": 231, - "name": "lh:audit:custom-controls-labels", + "name": "lh:audit:video-caption", "duration": 1, "entryType": "measure" }, { "startTime": 232, - "name": "lh:audit:custom-controls-roles", + "name": "lh:audit:custom-controls-labels", "duration": 1, "entryType": "measure" }, { "startTime": 233, - "name": "lh:audit:focus-traps", + "name": "lh:audit:custom-controls-roles", "duration": 1, "entryType": "measure" }, { "startTime": 234, - "name": "lh:audit:focusable-controls", + "name": "lh:audit:focus-traps", "duration": 1, "entryType": "measure" }, { "startTime": 235, - "name": "lh:audit:interactive-element-affordance", + "name": "lh:audit:focusable-controls", "duration": 1, "entryType": "measure" }, { "startTime": 236, - "name": "lh:audit:logical-tab-order", + "name": "lh:audit:interactive-element-affordance", "duration": 1, "entryType": "measure" }, { "startTime": 237, - "name": "lh:audit:managed-focus", + "name": "lh:audit:logical-tab-order", "duration": 1, "entryType": "measure" }, { "startTime": 238, - "name": "lh:audit:offscreen-content-hidden", + "name": "lh:audit:managed-focus", "duration": 1, "entryType": "measure" }, { "startTime": 239, - "name": "lh:audit:use-landmarks", + "name": "lh:audit:offscreen-content-hidden", "duration": 1, "entryType": "measure" }, { "startTime": 240, - "name": "lh:audit:visual-order-follows-dom", + "name": "lh:audit:use-landmarks", "duration": 1, "entryType": "measure" }, { "startTime": 241, - "name": "lh:audit:uses-long-cache-ttl", + "name": "lh:audit:visual-order-follows-dom", "duration": 1, "entryType": "measure" }, { "startTime": 242, - "name": "lh:audit:total-byte-weight", + "name": "lh:audit:uses-long-cache-ttl", "duration": 1, "entryType": "measure" }, { "startTime": 243, - "name": "lh:audit:offscreen-images", + "name": "lh:audit:total-byte-weight", "duration": 1, "entryType": "measure" }, { "startTime": 244, - "name": "lh:audit:render-blocking-resources", + "name": "lh:audit:offscreen-images", "duration": 1, "entryType": "measure" }, { "startTime": 245, - "name": "lh:computed:UnusedCSS", + "name": "lh:audit:render-blocking-resources", "duration": 1, "entryType": "measure" }, { "startTime": 246, - "name": "lh:computed:FirstContentfulPaint", + "name": "lh:computed:UnusedCSS", "duration": 1, "entryType": "measure" }, { "startTime": 247, - "name": "lh:audit:unminified-css", + "name": "lh:computed:FirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 248, - "name": "lh:audit:unminified-javascript", + "name": "lh:audit:unminified-css", "duration": 1, "entryType": "measure" }, { "startTime": 249, - "name": "lh:audit:unused-css-rules", + "name": "lh:audit:unminified-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 250, - "name": "lh:audit:unused-javascript", + "name": "lh:audit:unused-css-rules", "duration": 1, "entryType": "measure" }, { "startTime": 251, - "name": "lh:audit:modern-image-formats", + "name": "lh:audit:unused-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 252, - "name": "lh:audit:uses-optimized-images", + "name": "lh:audit:modern-image-formats", "duration": 1, "entryType": "measure" }, { "startTime": 253, - "name": "lh:audit:uses-text-compression", + "name": "lh:audit:uses-optimized-images", "duration": 1, "entryType": "measure" }, { "startTime": 254, - "name": "lh:audit:uses-responsive-images", + "name": "lh:audit:uses-text-compression", "duration": 1, "entryType": "measure" }, { "startTime": 255, - "name": "lh:computed:ImageRecords", + "name": "lh:audit:uses-responsive-images", "duration": 1, "entryType": "measure" }, { "startTime": 256, - "name": "lh:audit:efficient-animated-content", + "name": "lh:computed:ImageRecords", "duration": 1, "entryType": "measure" }, { "startTime": 257, - "name": "lh:audit:duplicated-javascript", + "name": "lh:audit:efficient-animated-content", "duration": 1, "entryType": "measure" }, { "startTime": 258, - "name": "lh:audit:legacy-javascript", + "name": "lh:audit:duplicated-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 259, - "name": "lh:audit:doctype", + "name": "lh:audit:legacy-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 260, - "name": "lh:audit:charset", + "name": "lh:audit:doctype", "duration": 1, "entryType": "measure" }, { "startTime": 261, - "name": "lh:audit:dom-size", + "name": "lh:audit:charset", "duration": 1, "entryType": "measure" }, { "startTime": 262, - "name": "lh:audit:geolocation-on-start", + "name": "lh:audit:dom-size", "duration": 1, "entryType": "measure" }, { "startTime": 263, - "name": "lh:audit:inspector-issues", + "name": "lh:audit:geolocation-on-start", "duration": 1, "entryType": "measure" }, { "startTime": 264, - "name": "lh:audit:no-document-write", + "name": "lh:audit:inspector-issues", "duration": 1, "entryType": "measure" }, { "startTime": 265, - "name": "lh:audit:js-libraries", + "name": "lh:audit:no-document-write", "duration": 1, "entryType": "measure" }, { "startTime": 266, - "name": "lh:audit:notification-on-start", + "name": "lh:audit:js-libraries", "duration": 1, "entryType": "measure" }, { "startTime": 267, - "name": "lh:audit:paste-preventing-inputs", + "name": "lh:audit:notification-on-start", "duration": 1, "entryType": "measure" }, { "startTime": 268, - "name": "lh:audit:uses-passive-event-listeners", + "name": "lh:audit:paste-preventing-inputs", "duration": 1, "entryType": "measure" }, { "startTime": 269, - "name": "lh:audit:meta-description", + "name": "lh:audit:uses-passive-event-listeners", "duration": 1, "entryType": "measure" }, { "startTime": 270, - "name": "lh:audit:http-status-code", + "name": "lh:audit:meta-description", "duration": 1, "entryType": "measure" }, { "startTime": 271, - "name": "lh:audit:font-size", + "name": "lh:audit:http-status-code", "duration": 1, "entryType": "measure" }, { "startTime": 272, - "name": "lh:audit:link-text", + "name": "lh:audit:font-size", "duration": 1, "entryType": "measure" }, { "startTime": 273, - "name": "lh:audit:crawlable-anchors", + "name": "lh:audit:link-text", "duration": 1, "entryType": "measure" }, { "startTime": 274, - "name": "lh:audit:is-crawlable", + "name": "lh:audit:crawlable-anchors", "duration": 1, "entryType": "measure" }, { "startTime": 275, - "name": "lh:audit:robots-txt", + "name": "lh:audit:is-crawlable", "duration": 1, "entryType": "measure" }, { "startTime": 276, - "name": "lh:audit:hreflang", + "name": "lh:audit:robots-txt", "duration": 1, "entryType": "measure" }, { "startTime": 277, - "name": "lh:audit:canonical", + "name": "lh:audit:hreflang", "duration": 1, "entryType": "measure" }, { "startTime": 278, - "name": "lh:audit:structured-data", + "name": "lh:audit:canonical", "duration": 1, "entryType": "measure" }, { "startTime": 279, - "name": "lh:audit:bf-cache", + "name": "lh:audit:structured-data", "duration": 1, "entryType": "measure" }, { "startTime": 280, + "name": "lh:audit:bf-cache", + "duration": 1, + "entryType": "measure" + }, + { + "startTime": 281, "name": "lh:runner:generate", "duration": 1, "entryType": "measure" } ], - "total": 281 + "total": 282 }, "i18n": { "rendererFormattedStrings": { @@ -6974,6 +6992,12 @@ "core/audits/is-on-https.js | description": [ "audits[is-on-https].description" ], + "core/audits/redirects-http.js | title": [ + "audits[redirects-http].title" + ], + "core/audits/redirects-http.js | description": [ + "audits[redirects-http].description" + ], "core/audits/viewport.js | title": [ "audits.viewport.title" ], @@ -17550,6 +17574,13 @@ "items": [] } }, + "redirects-http": { + "id": "redirects-http", + "title": "Redirects HTTP traffic to HTTPS", + "description": "Make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, "viewport": { "id": "viewport", "title": "Has a `` tag with `width` or `initial-scale`", @@ -21981,6 +22012,11 @@ "weight": 5, "group": "best-practices-trust-safety" }, + { + "id": "redirects-http", + "weight": 0, + "group": "best-practices-trust-safety" + }, { "id": "geolocation-on-start", "weight": 1, @@ -23137,547 +23173,547 @@ }, { "startTime": 62, - "name": "lh:audit:viewport", + "name": "lh:audit:redirects-http", "duration": 1, "entryType": "measure" }, { "startTime": 63, - "name": "lh:computed:ViewportMeta", + "name": "lh:audit:viewport", "duration": 1, "entryType": "measure" }, { "startTime": 64, - "name": "lh:audit:first-contentful-paint", + "name": "lh:computed:ViewportMeta", "duration": 1, "entryType": "measure" }, { "startTime": 65, - "name": "lh:computed:FirstContentfulPaint", + "name": "lh:audit:first-contentful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 66, - "name": "lh:computed:ProcessedTrace", + "name": "lh:computed:FirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 67, - "name": "lh:computed:ProcessedNavigation", + "name": "lh:computed:ProcessedTrace", "duration": 1, "entryType": "measure" }, { "startTime": 68, - "name": "lh:computed:LanternFirstContentfulPaint", + "name": "lh:computed:ProcessedNavigation", "duration": 1, "entryType": "measure" }, { "startTime": 69, - "name": "lh:computed:PageDependencyGraph", + "name": "lh:computed:LanternFirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 70, - "name": "lh:computed:LoadSimulator", + "name": "lh:computed:PageDependencyGraph", "duration": 1, "entryType": "measure" }, { "startTime": 71, - "name": "lh:computed:NetworkAnalysis", + "name": "lh:computed:LoadSimulator", "duration": 1, "entryType": "measure" }, { "startTime": 72, - "name": "lh:audit:largest-contentful-paint", + "name": "lh:computed:NetworkAnalysis", "duration": 1, "entryType": "measure" }, { "startTime": 73, - "name": "lh:computed:LargestContentfulPaint", + "name": "lh:audit:largest-contentful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 74, - "name": "lh:computed:LanternLargestContentfulPaint", + "name": "lh:computed:LargestContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 75, - "name": "lh:audit:first-meaningful-paint", + "name": "lh:computed:LanternLargestContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 76, - "name": "lh:computed:FirstMeaningfulPaint", + "name": "lh:audit:first-meaningful-paint", "duration": 1, "entryType": "measure" }, { "startTime": 77, - "name": "lh:computed:LanternFirstMeaningfulPaint", + "name": "lh:computed:FirstMeaningfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 78, - "name": "lh:audit:speed-index", + "name": "lh:computed:LanternFirstMeaningfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 79, - "name": "lh:computed:SpeedIndex", + "name": "lh:audit:speed-index", "duration": 1, "entryType": "measure" }, { "startTime": 80, - "name": "lh:computed:LanternSpeedIndex", + "name": "lh:computed:SpeedIndex", "duration": 1, "entryType": "measure" }, { "startTime": 81, - "name": "lh:computed:Speedline", + "name": "lh:computed:LanternSpeedIndex", "duration": 1, "entryType": "measure" }, { "startTime": 82, - "name": "lh:audit:screenshot-thumbnails", + "name": "lh:computed:Speedline", "duration": 1, "entryType": "measure" }, { "startTime": 83, - "name": "lh:audit:final-screenshot", + "name": "lh:audit:screenshot-thumbnails", "duration": 1, "entryType": "measure" }, { "startTime": 84, - "name": "lh:computed:Screenshots", + "name": "lh:audit:final-screenshot", "duration": 1, "entryType": "measure" }, { "startTime": 85, - "name": "lh:audit:total-blocking-time", + "name": "lh:computed:Screenshots", "duration": 1, "entryType": "measure" }, { "startTime": 86, - "name": "lh:computed:TotalBlockingTime", + "name": "lh:audit:total-blocking-time", "duration": 1, "entryType": "measure" }, { "startTime": 87, - "name": "lh:computed:LanternTotalBlockingTime", + "name": "lh:computed:TotalBlockingTime", "duration": 1, "entryType": "measure" }, { "startTime": 88, - "name": "lh:computed:LanternInteractive", + "name": "lh:computed:LanternTotalBlockingTime", "duration": 1, "entryType": "measure" }, { "startTime": 89, - "name": "lh:audit:max-potential-fid", + "name": "lh:computed:LanternInteractive", "duration": 1, "entryType": "measure" }, { "startTime": 90, - "name": "lh:computed:MaxPotentialFID", + "name": "lh:audit:max-potential-fid", "duration": 1, "entryType": "measure" }, { "startTime": 91, - "name": "lh:computed:LanternMaxPotentialFID", + "name": "lh:computed:MaxPotentialFID", "duration": 1, "entryType": "measure" }, { "startTime": 92, - "name": "lh:audit:cumulative-layout-shift", + "name": "lh:computed:LanternMaxPotentialFID", "duration": 1, "entryType": "measure" }, { "startTime": 93, - "name": "lh:computed:CumulativeLayoutShift", + "name": "lh:audit:cumulative-layout-shift", "duration": 1, "entryType": "measure" }, { "startTime": 94, - "name": "lh:audit:errors-in-console", + "name": "lh:computed:CumulativeLayoutShift", "duration": 1, "entryType": "measure" }, { "startTime": 95, - "name": "lh:computed:JSBundles", + "name": "lh:audit:errors-in-console", "duration": 1, "entryType": "measure" }, { "startTime": 96, - "name": "lh:audit:server-response-time", + "name": "lh:computed:JSBundles", "duration": 1, "entryType": "measure" }, { "startTime": 97, - "name": "lh:computed:MainResource", + "name": "lh:audit:server-response-time", "duration": 1, "entryType": "measure" }, { "startTime": 98, - "name": "lh:audit:interactive", + "name": "lh:computed:MainResource", "duration": 1, "entryType": "measure" }, { "startTime": 99, - "name": "lh:computed:Interactive", + "name": "lh:audit:interactive", "duration": 1, "entryType": "measure" }, { "startTime": 100, - "name": "lh:audit:user-timings", + "name": "lh:computed:Interactive", "duration": 1, "entryType": "measure" }, { "startTime": 101, - "name": "lh:computed:UserTimings", + "name": "lh:audit:user-timings", "duration": 1, "entryType": "measure" }, { "startTime": 102, - "name": "lh:audit:critical-request-chains", + "name": "lh:computed:UserTimings", "duration": 1, "entryType": "measure" }, { "startTime": 103, - "name": "lh:computed:CriticalRequestChains", + "name": "lh:audit:critical-request-chains", "duration": 1, "entryType": "measure" }, { "startTime": 104, - "name": "lh:audit:redirects", + "name": "lh:computed:CriticalRequestChains", "duration": 1, "entryType": "measure" }, { "startTime": 105, - "name": "lh:audit:installable-manifest", + "name": "lh:audit:redirects", "duration": 1, "entryType": "measure" }, { "startTime": 106, - "name": "lh:audit:splash-screen", + "name": "lh:audit:installable-manifest", "duration": 1, "entryType": "measure" }, { "startTime": 107, - "name": "lh:computed:ManifestValues", + "name": "lh:audit:splash-screen", "duration": 1, "entryType": "measure" }, { "startTime": 108, - "name": "lh:audit:themed-omnibox", + "name": "lh:computed:ManifestValues", "duration": 1, "entryType": "measure" }, { "startTime": 109, - "name": "lh:audit:maskable-icon", + "name": "lh:audit:themed-omnibox", "duration": 1, "entryType": "measure" }, { "startTime": 110, - "name": "lh:audit:content-width", + "name": "lh:audit:maskable-icon", "duration": 1, "entryType": "measure" }, { "startTime": 111, - "name": "lh:audit:image-aspect-ratio", + "name": "lh:audit:content-width", "duration": 1, "entryType": "measure" }, { "startTime": 112, - "name": "lh:audit:image-size-responsive", + "name": "lh:audit:image-aspect-ratio", "duration": 1, "entryType": "measure" }, { "startTime": 113, - "name": "lh:audit:deprecations", + "name": "lh:audit:image-size-responsive", "duration": 1, "entryType": "measure" }, { "startTime": 114, - "name": "lh:audit:third-party-cookies", + "name": "lh:audit:deprecations", "duration": 1, "entryType": "measure" }, { "startTime": 115, - "name": "lh:audit:mainthread-work-breakdown", + "name": "lh:audit:third-party-cookies", "duration": 1, "entryType": "measure" }, { "startTime": 116, - "name": "lh:computed:MainThreadTasks", + "name": "lh:audit:mainthread-work-breakdown", "duration": 1, "entryType": "measure" }, { "startTime": 117, - "name": "lh:audit:bootup-time", + "name": "lh:computed:MainThreadTasks", "duration": 1, "entryType": "measure" }, { "startTime": 118, - "name": "lh:computed:TBTImpactTasks", + "name": "lh:audit:bootup-time", "duration": 1, "entryType": "measure" }, { "startTime": 119, - "name": "lh:audit:uses-rel-preconnect", + "name": "lh:computed:TBTImpactTasks", "duration": 1, "entryType": "measure" }, { "startTime": 120, - "name": "lh:audit:font-display", + "name": "lh:audit:uses-rel-preconnect", "duration": 1, "entryType": "measure" }, { "startTime": 121, - "name": "lh:audit:diagnostics", + "name": "lh:audit:font-display", "duration": 1, "entryType": "measure" }, { "startTime": 122, - "name": "lh:audit:network-requests", + "name": "lh:audit:diagnostics", "duration": 1, "entryType": "measure" }, { "startTime": 123, - "name": "lh:computed:EntityClassification", + "name": "lh:audit:network-requests", "duration": 1, "entryType": "measure" }, { "startTime": 124, - "name": "lh:audit:network-rtt", + "name": "lh:computed:EntityClassification", "duration": 1, "entryType": "measure" }, { "startTime": 125, - "name": "lh:audit:network-server-latency", + "name": "lh:audit:network-rtt", "duration": 1, "entryType": "measure" }, { "startTime": 126, - "name": "lh:audit:main-thread-tasks", + "name": "lh:audit:network-server-latency", "duration": 1, "entryType": "measure" }, { "startTime": 127, - "name": "lh:audit:metrics", + "name": "lh:audit:main-thread-tasks", "duration": 1, "entryType": "measure" }, { "startTime": 128, - "name": "lh:computed:TimingSummary", + "name": "lh:audit:metrics", "duration": 1, "entryType": "measure" }, { "startTime": 129, - "name": "lh:computed:FirstContentfulPaintAllFrames", + "name": "lh:computed:TimingSummary", "duration": 1, "entryType": "measure" }, { "startTime": 130, - "name": "lh:computed:LargestContentfulPaintAllFrames", + "name": "lh:computed:FirstContentfulPaintAllFrames", "duration": 1, "entryType": "measure" }, { "startTime": 131, - "name": "lh:computed:LCPBreakdown", + "name": "lh:computed:LargestContentfulPaintAllFrames", "duration": 1, "entryType": "measure" }, { "startTime": 132, - "name": "lh:computed:TimeToFirstByte", + "name": "lh:computed:LCPBreakdown", "duration": 1, "entryType": "measure" }, { "startTime": 133, - "name": "lh:computed:LCPImageRecord", + "name": "lh:computed:TimeToFirstByte", "duration": 1, "entryType": "measure" }, { "startTime": 134, - "name": "lh:audit:performance-budget", + "name": "lh:computed:LCPImageRecord", "duration": 1, "entryType": "measure" }, { "startTime": 135, - "name": "lh:computed:ResourceSummary", + "name": "lh:audit:performance-budget", "duration": 1, "entryType": "measure" }, { "startTime": 136, - "name": "lh:audit:timing-budget", + "name": "lh:computed:ResourceSummary", "duration": 1, "entryType": "measure" }, { "startTime": 137, - "name": "lh:audit:resource-summary", + "name": "lh:audit:timing-budget", "duration": 1, "entryType": "measure" }, { "startTime": 138, - "name": "lh:audit:third-party-summary", + "name": "lh:audit:resource-summary", "duration": 1, "entryType": "measure" }, { "startTime": 139, - "name": "lh:audit:third-party-facades", + "name": "lh:audit:third-party-summary", "duration": 1, "entryType": "measure" }, { "startTime": 140, - "name": "lh:audit:largest-contentful-paint-element", + "name": "lh:audit:third-party-facades", "duration": 1, "entryType": "measure" }, { "startTime": 141, - "name": "lh:audit:lcp-lazy-loaded", + "name": "lh:audit:largest-contentful-paint-element", "duration": 1, "entryType": "measure" }, { "startTime": 142, - "name": "lh:audit:layout-shifts", + "name": "lh:audit:lcp-lazy-loaded", "duration": 1, "entryType": "measure" }, { "startTime": 143, - "name": "lh:computed:TraceEngineResult", + "name": "lh:audit:layout-shifts", "duration": 1, "entryType": "measure" }, { "startTime": 144, - "name": "lh:audit:long-tasks", + "name": "lh:computed:TraceEngineResult", "duration": 1, "entryType": "measure" }, { "startTime": 145, - "name": "lh:audit:non-composited-animations", + "name": "lh:audit:long-tasks", "duration": 1, "entryType": "measure" }, { "startTime": 146, - "name": "lh:audit:unsized-images", + "name": "lh:audit:non-composited-animations", "duration": 1, "entryType": "measure" }, { "startTime": 147, - "name": "lh:audit:valid-source-maps", + "name": "lh:audit:unsized-images", "duration": 1, "entryType": "measure" }, { "startTime": 148, - "name": "lh:audit:prioritize-lcp-image", + "name": "lh:audit:valid-source-maps", "duration": 1, "entryType": "measure" }, { "startTime": 149, - "name": "lh:audit:csp-xss", + "name": "lh:audit:prioritize-lcp-image", "duration": 1, "entryType": "measure" }, { "startTime": 150, - "name": "lh:audit:script-treemap-data", + "name": "lh:audit:csp-xss", "duration": 1, "entryType": "measure" }, { "startTime": 151, - "name": "lh:computed:ModuleDuplication", + "name": "lh:audit:script-treemap-data", "duration": 1, "entryType": "measure" }, { "startTime": 152, - "name": "lh:computed:UnusedJavascriptSummary", + "name": "lh:computed:ModuleDuplication", "duration": 1, "entryType": "measure" }, @@ -23755,684 +23791,690 @@ }, { "startTime": 165, - "name": "lh:audit:pwa-cross-browser", + "name": "lh:computed:UnusedJavascriptSummary", "duration": 1, "entryType": "measure" }, { "startTime": 166, - "name": "lh:audit:pwa-page-transitions", + "name": "lh:audit:pwa-cross-browser", "duration": 1, "entryType": "measure" }, { "startTime": 167, - "name": "lh:audit:pwa-each-page-has-url", + "name": "lh:audit:pwa-page-transitions", "duration": 1, "entryType": "measure" }, { "startTime": 168, - "name": "lh:audit:accesskeys", + "name": "lh:audit:pwa-each-page-has-url", "duration": 1, "entryType": "measure" }, { "startTime": 169, - "name": "lh:audit:aria-allowed-attr", + "name": "lh:audit:accesskeys", "duration": 1, "entryType": "measure" }, { "startTime": 170, - "name": "lh:audit:aria-allowed-role", + "name": "lh:audit:aria-allowed-attr", "duration": 1, "entryType": "measure" }, { "startTime": 171, - "name": "lh:audit:aria-command-name", + "name": "lh:audit:aria-allowed-role", "duration": 1, "entryType": "measure" }, { "startTime": 172, - "name": "lh:audit:aria-dialog-name", + "name": "lh:audit:aria-command-name", "duration": 1, "entryType": "measure" }, { "startTime": 173, - "name": "lh:audit:aria-hidden-body", + "name": "lh:audit:aria-dialog-name", "duration": 1, "entryType": "measure" }, { "startTime": 174, - "name": "lh:audit:aria-hidden-focus", + "name": "lh:audit:aria-hidden-body", "duration": 1, "entryType": "measure" }, { "startTime": 175, - "name": "lh:audit:aria-input-field-name", + "name": "lh:audit:aria-hidden-focus", "duration": 1, "entryType": "measure" }, { "startTime": 176, - "name": "lh:audit:aria-meter-name", + "name": "lh:audit:aria-input-field-name", "duration": 1, "entryType": "measure" }, { "startTime": 177, - "name": "lh:audit:aria-progressbar-name", + "name": "lh:audit:aria-meter-name", "duration": 1, "entryType": "measure" }, { "startTime": 178, - "name": "lh:audit:aria-required-attr", + "name": "lh:audit:aria-progressbar-name", "duration": 1, "entryType": "measure" }, { "startTime": 179, - "name": "lh:audit:aria-required-children", + "name": "lh:audit:aria-required-attr", "duration": 1, "entryType": "measure" }, { "startTime": 180, - "name": "lh:audit:aria-required-parent", + "name": "lh:audit:aria-required-children", "duration": 1, "entryType": "measure" }, { "startTime": 181, - "name": "lh:audit:aria-roles", + "name": "lh:audit:aria-required-parent", "duration": 1, "entryType": "measure" }, { "startTime": 182, - "name": "lh:audit:aria-text", + "name": "lh:audit:aria-roles", "duration": 1, "entryType": "measure" }, { "startTime": 183, - "name": "lh:audit:aria-toggle-field-name", + "name": "lh:audit:aria-text", "duration": 1, "entryType": "measure" }, { "startTime": 184, - "name": "lh:audit:aria-tooltip-name", + "name": "lh:audit:aria-toggle-field-name", "duration": 1, "entryType": "measure" }, { "startTime": 185, - "name": "lh:audit:aria-treeitem-name", + "name": "lh:audit:aria-tooltip-name", "duration": 1, "entryType": "measure" }, { "startTime": 186, - "name": "lh:audit:aria-valid-attr-value", + "name": "lh:audit:aria-treeitem-name", "duration": 1, "entryType": "measure" }, { "startTime": 187, - "name": "lh:audit:aria-valid-attr", + "name": "lh:audit:aria-valid-attr-value", "duration": 1, "entryType": "measure" }, { "startTime": 188, - "name": "lh:audit:button-name", + "name": "lh:audit:aria-valid-attr", "duration": 1, "entryType": "measure" }, { "startTime": 189, - "name": "lh:audit:bypass", + "name": "lh:audit:button-name", "duration": 1, "entryType": "measure" }, { "startTime": 190, - "name": "lh:audit:color-contrast", + "name": "lh:audit:bypass", "duration": 1, "entryType": "measure" }, { "startTime": 191, - "name": "lh:audit:definition-list", + "name": "lh:audit:color-contrast", "duration": 1, "entryType": "measure" }, { "startTime": 192, - "name": "lh:audit:dlitem", + "name": "lh:audit:definition-list", "duration": 1, "entryType": "measure" }, { "startTime": 193, - "name": "lh:audit:document-title", + "name": "lh:audit:dlitem", "duration": 1, "entryType": "measure" }, { "startTime": 194, - "name": "lh:audit:duplicate-id-aria", + "name": "lh:audit:document-title", "duration": 1, "entryType": "measure" }, { "startTime": 195, - "name": "lh:audit:empty-heading", + "name": "lh:audit:duplicate-id-aria", "duration": 1, "entryType": "measure" }, { "startTime": 196, - "name": "lh:audit:form-field-multiple-labels", + "name": "lh:audit:empty-heading", "duration": 1, "entryType": "measure" }, { "startTime": 197, - "name": "lh:audit:frame-title", + "name": "lh:audit:form-field-multiple-labels", "duration": 1, "entryType": "measure" }, { "startTime": 198, - "name": "lh:audit:heading-order", + "name": "lh:audit:frame-title", "duration": 1, "entryType": "measure" }, { "startTime": 199, - "name": "lh:audit:html-has-lang", + "name": "lh:audit:heading-order", "duration": 1, "entryType": "measure" }, { "startTime": 200, - "name": "lh:audit:html-lang-valid", + "name": "lh:audit:html-has-lang", "duration": 1, "entryType": "measure" }, { "startTime": 201, - "name": "lh:audit:html-xml-lang-mismatch", + "name": "lh:audit:html-lang-valid", "duration": 1, "entryType": "measure" }, { "startTime": 202, - "name": "lh:audit:identical-links-same-purpose", + "name": "lh:audit:html-xml-lang-mismatch", "duration": 1, "entryType": "measure" }, { "startTime": 203, - "name": "lh:audit:image-alt", + "name": "lh:audit:identical-links-same-purpose", "duration": 1, "entryType": "measure" }, { "startTime": 204, - "name": "lh:audit:image-redundant-alt", + "name": "lh:audit:image-alt", "duration": 1, "entryType": "measure" }, { "startTime": 205, - "name": "lh:audit:input-button-name", + "name": "lh:audit:image-redundant-alt", "duration": 1, "entryType": "measure" }, { "startTime": 206, - "name": "lh:audit:input-image-alt", + "name": "lh:audit:input-button-name", "duration": 1, "entryType": "measure" }, { "startTime": 207, - "name": "lh:audit:label-content-name-mismatch", + "name": "lh:audit:input-image-alt", "duration": 1, "entryType": "measure" }, { "startTime": 208, - "name": "lh:audit:label", + "name": "lh:audit:label-content-name-mismatch", "duration": 1, "entryType": "measure" }, { "startTime": 209, - "name": "lh:audit:landmark-one-main", + "name": "lh:audit:label", "duration": 1, "entryType": "measure" }, { "startTime": 210, - "name": "lh:audit:link-name", + "name": "lh:audit:landmark-one-main", "duration": 1, "entryType": "measure" }, { "startTime": 211, - "name": "lh:audit:link-in-text-block", + "name": "lh:audit:link-name", "duration": 1, "entryType": "measure" }, { "startTime": 212, - "name": "lh:audit:list", + "name": "lh:audit:link-in-text-block", "duration": 1, "entryType": "measure" }, { "startTime": 213, - "name": "lh:audit:listitem", + "name": "lh:audit:list", "duration": 1, "entryType": "measure" }, { "startTime": 214, - "name": "lh:audit:meta-refresh", + "name": "lh:audit:listitem", "duration": 1, "entryType": "measure" }, { "startTime": 215, - "name": "lh:audit:meta-viewport", + "name": "lh:audit:meta-refresh", "duration": 1, "entryType": "measure" }, { "startTime": 216, - "name": "lh:audit:object-alt", + "name": "lh:audit:meta-viewport", "duration": 1, "entryType": "measure" }, { "startTime": 217, - "name": "lh:audit:select-name", + "name": "lh:audit:object-alt", "duration": 1, "entryType": "measure" }, { "startTime": 218, - "name": "lh:audit:skip-link", + "name": "lh:audit:select-name", "duration": 1, "entryType": "measure" }, { "startTime": 219, - "name": "lh:audit:tabindex", + "name": "lh:audit:skip-link", "duration": 1, "entryType": "measure" }, { "startTime": 220, - "name": "lh:audit:table-duplicate-name", + "name": "lh:audit:tabindex", "duration": 1, "entryType": "measure" }, { "startTime": 221, - "name": "lh:audit:table-fake-caption", + "name": "lh:audit:table-duplicate-name", "duration": 1, "entryType": "measure" }, { "startTime": 222, - "name": "lh:audit:target-size", + "name": "lh:audit:table-fake-caption", "duration": 1, "entryType": "measure" }, { "startTime": 223, - "name": "lh:audit:td-has-header", + "name": "lh:audit:target-size", "duration": 1, "entryType": "measure" }, { "startTime": 224, - "name": "lh:audit:td-headers-attr", + "name": "lh:audit:td-has-header", "duration": 1, "entryType": "measure" }, { "startTime": 225, - "name": "lh:audit:th-has-data-cells", + "name": "lh:audit:td-headers-attr", "duration": 1, "entryType": "measure" }, { "startTime": 226, - "name": "lh:audit:valid-lang", + "name": "lh:audit:th-has-data-cells", "duration": 1, "entryType": "measure" }, { "startTime": 227, - "name": "lh:audit:video-caption", + "name": "lh:audit:valid-lang", "duration": 1, "entryType": "measure" }, { "startTime": 228, - "name": "lh:audit:custom-controls-labels", + "name": "lh:audit:video-caption", "duration": 1, "entryType": "measure" }, { "startTime": 229, - "name": "lh:audit:custom-controls-roles", + "name": "lh:audit:custom-controls-labels", "duration": 1, "entryType": "measure" }, { "startTime": 230, - "name": "lh:audit:focus-traps", + "name": "lh:audit:custom-controls-roles", "duration": 1, "entryType": "measure" }, { "startTime": 231, - "name": "lh:audit:focusable-controls", + "name": "lh:audit:focus-traps", "duration": 1, "entryType": "measure" }, { "startTime": 232, - "name": "lh:audit:interactive-element-affordance", + "name": "lh:audit:focusable-controls", "duration": 1, "entryType": "measure" }, { "startTime": 233, - "name": "lh:audit:logical-tab-order", + "name": "lh:audit:interactive-element-affordance", "duration": 1, "entryType": "measure" }, { "startTime": 234, - "name": "lh:audit:managed-focus", + "name": "lh:audit:logical-tab-order", "duration": 1, "entryType": "measure" }, { "startTime": 235, - "name": "lh:audit:offscreen-content-hidden", + "name": "lh:audit:managed-focus", "duration": 1, "entryType": "measure" }, { "startTime": 236, - "name": "lh:audit:use-landmarks", + "name": "lh:audit:offscreen-content-hidden", "duration": 1, "entryType": "measure" }, { "startTime": 237, - "name": "lh:audit:visual-order-follows-dom", + "name": "lh:audit:use-landmarks", "duration": 1, "entryType": "measure" }, { "startTime": 238, - "name": "lh:audit:uses-long-cache-ttl", + "name": "lh:audit:visual-order-follows-dom", "duration": 1, "entryType": "measure" }, { "startTime": 239, - "name": "lh:audit:total-byte-weight", + "name": "lh:audit:uses-long-cache-ttl", "duration": 1, "entryType": "measure" }, { "startTime": 240, - "name": "lh:audit:offscreen-images", + "name": "lh:audit:total-byte-weight", "duration": 1, "entryType": "measure" }, { "startTime": 241, - "name": "lh:audit:render-blocking-resources", + "name": "lh:audit:offscreen-images", "duration": 1, "entryType": "measure" }, { "startTime": 242, - "name": "lh:computed:UnusedCSS", + "name": "lh:audit:render-blocking-resources", "duration": 1, "entryType": "measure" }, { "startTime": 243, - "name": "lh:computed:FirstContentfulPaint", + "name": "lh:computed:UnusedCSS", "duration": 1, "entryType": "measure" }, { "startTime": 244, - "name": "lh:audit:unminified-css", + "name": "lh:computed:FirstContentfulPaint", "duration": 1, "entryType": "measure" }, { "startTime": 245, - "name": "lh:audit:unminified-javascript", + "name": "lh:audit:unminified-css", "duration": 1, "entryType": "measure" }, { "startTime": 246, - "name": "lh:audit:unused-css-rules", + "name": "lh:audit:unminified-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 247, - "name": "lh:audit:unused-javascript", + "name": "lh:audit:unused-css-rules", "duration": 1, "entryType": "measure" }, { "startTime": 248, - "name": "lh:audit:modern-image-formats", + "name": "lh:audit:unused-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 249, - "name": "lh:audit:uses-optimized-images", + "name": "lh:audit:modern-image-formats", "duration": 1, "entryType": "measure" }, { "startTime": 250, - "name": "lh:audit:uses-text-compression", + "name": "lh:audit:uses-optimized-images", "duration": 1, "entryType": "measure" }, { "startTime": 251, - "name": "lh:audit:uses-responsive-images", + "name": "lh:audit:uses-text-compression", "duration": 1, "entryType": "measure" }, { "startTime": 252, - "name": "lh:computed:ImageRecords", + "name": "lh:audit:uses-responsive-images", "duration": 1, "entryType": "measure" }, { "startTime": 253, - "name": "lh:audit:efficient-animated-content", + "name": "lh:computed:ImageRecords", "duration": 1, "entryType": "measure" }, { "startTime": 254, - "name": "lh:audit:duplicated-javascript", + "name": "lh:audit:efficient-animated-content", "duration": 1, "entryType": "measure" }, { "startTime": 255, - "name": "lh:audit:legacy-javascript", + "name": "lh:audit:duplicated-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 256, - "name": "lh:audit:doctype", + "name": "lh:audit:legacy-javascript", "duration": 1, "entryType": "measure" }, { "startTime": 257, - "name": "lh:audit:charset", + "name": "lh:audit:doctype", "duration": 1, "entryType": "measure" }, { "startTime": 258, - "name": "lh:audit:dom-size", + "name": "lh:audit:charset", "duration": 1, "entryType": "measure" }, { "startTime": 259, - "name": "lh:audit:geolocation-on-start", + "name": "lh:audit:dom-size", "duration": 1, "entryType": "measure" }, { "startTime": 260, - "name": "lh:audit:inspector-issues", + "name": "lh:audit:geolocation-on-start", "duration": 1, "entryType": "measure" }, { "startTime": 261, - "name": "lh:audit:no-document-write", + "name": "lh:audit:inspector-issues", "duration": 1, "entryType": "measure" }, { "startTime": 262, - "name": "lh:audit:js-libraries", + "name": "lh:audit:no-document-write", "duration": 1, "entryType": "measure" }, { "startTime": 263, - "name": "lh:audit:notification-on-start", + "name": "lh:audit:js-libraries", "duration": 1, "entryType": "measure" }, { "startTime": 264, - "name": "lh:audit:paste-preventing-inputs", + "name": "lh:audit:notification-on-start", "duration": 1, "entryType": "measure" }, { "startTime": 265, - "name": "lh:audit:uses-passive-event-listeners", + "name": "lh:audit:paste-preventing-inputs", "duration": 1, "entryType": "measure" }, { "startTime": 266, - "name": "lh:audit:meta-description", + "name": "lh:audit:uses-passive-event-listeners", "duration": 1, "entryType": "measure" }, { "startTime": 267, - "name": "lh:audit:http-status-code", + "name": "lh:audit:meta-description", "duration": 1, "entryType": "measure" }, { "startTime": 268, - "name": "lh:audit:font-size", + "name": "lh:audit:http-status-code", "duration": 1, "entryType": "measure" }, { "startTime": 269, - "name": "lh:audit:link-text", + "name": "lh:audit:font-size", "duration": 1, "entryType": "measure" }, { "startTime": 270, - "name": "lh:audit:crawlable-anchors", + "name": "lh:audit:link-text", "duration": 1, "entryType": "measure" }, { "startTime": 271, - "name": "lh:audit:is-crawlable", + "name": "lh:audit:crawlable-anchors", "duration": 1, "entryType": "measure" }, { "startTime": 272, - "name": "lh:audit:robots-txt", + "name": "lh:audit:is-crawlable", "duration": 1, "entryType": "measure" }, { "startTime": 273, - "name": "lh:audit:hreflang", + "name": "lh:audit:robots-txt", "duration": 1, "entryType": "measure" }, { "startTime": 274, - "name": "lh:audit:canonical", + "name": "lh:audit:hreflang", "duration": 1, "entryType": "measure" }, { "startTime": 275, - "name": "lh:audit:structured-data", + "name": "lh:audit:canonical", "duration": 1, "entryType": "measure" }, { "startTime": 276, - "name": "lh:audit:bf-cache", + "name": "lh:audit:structured-data", "duration": 1, "entryType": "measure" }, { "startTime": 277, + "name": "lh:audit:bf-cache", + "duration": 1, + "entryType": "measure" + }, + { + "startTime": 278, "name": "lh:runner:generate", "duration": 1, "entryType": "measure" } ], - "total": 278 + "total": 279 }, "i18n": { "rendererFormattedStrings": { @@ -24503,6 +24545,12 @@ "core/audits/is-on-https.js | description": [ "audits[is-on-https].description" ], + "core/audits/redirects-http.js | title": [ + "audits[redirects-http].title" + ], + "core/audits/redirects-http.js | description": [ + "audits[redirects-http].description" + ], "core/audits/viewport.js | title": [ "audits.viewport.title" ], diff --git a/core/test/results/sample_v2.json b/core/test/results/sample_v2.json index 240876d23b8d..6e8d0dc30d96 100644 --- a/core/test/results/sample_v2.json +++ b/core/test/results/sample_v2.json @@ -46,6 +46,13 @@ ] } }, + "redirects-http": { + "id": "redirects-http", + "title": "Redirects HTTP traffic to HTTPS", + "description": "Make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/).", + "score": null, + "scoreDisplayMode": "notApplicable" + }, "viewport": { "id": "viewport", "title": "Has a `` tag with `width` or `initial-scale`", @@ -6513,6 +6520,11 @@ "weight": 5, "group": "best-practices-trust-safety" }, + { + "id": "redirects-http", + "weight": 0, + "group": "best-practices-trust-safety" + }, { "id": "geolocation-on-start", "weight": 1, @@ -7861,6 +7873,12 @@ "duration": 100, "entryType": "measure" }, + { + "startTime": 0, + "name": "lh:audit:redirects-http", + "duration": 100, + "entryType": "measure" + }, { "startTime": 0, "name": "lh:audit:viewport", @@ -9264,6 +9282,12 @@ "core/audits/is-on-https.js | allowed": [ "audits[is-on-https].details.items[0].resolution" ], + "core/audits/redirects-http.js | title": [ + "audits[redirects-http].title" + ], + "core/audits/redirects-http.js | description": [ + "audits[redirects-http].description" + ], "core/audits/viewport.js | title": [ "audits.viewport.title" ], diff --git a/core/test/scenarios/__snapshots__/api-test-pptr.js.snap b/core/test/scenarios/__snapshots__/api-test-pptr.js.snap index c6d5ee1940fe..92a41db24960 100644 --- a/core/test/scenarios/__snapshots__/api-test-pptr.js.snap +++ b/core/test/scenarios/__snapshots__/api-test-pptr.js.snap @@ -119,6 +119,7 @@ Array [ "pwa-each-page-has-url", "pwa-page-transitions", "redirects", + "redirects-http", "render-blocking-resources", "resource-summary", "robots-txt", @@ -285,6 +286,7 @@ Array [ "pwa-each-page-has-url", "pwa-page-transitions", "redirects", + "redirects-http", "render-blocking-resources", "resource-summary", "robots-txt", diff --git a/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap new file mode 100644 index 000000000000..7fe986fffe7d --- /dev/null +++ b/lighthouse-cli/test/cli/__snapshots__/index-test.js.snap @@ -0,0 +1,1709 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CLI Tests print-config should print the default config and exit immediately after 1`] = ` +Object { + "audits": Array [ + Object { + "path": "is-on-https", + }, + Object { + "path": "redirects-http", + }, + Object { + "path": "service-worker", + }, + Object { + "path": "viewport", + }, + Object { + "path": "metrics/first-contentful-paint", + }, + Object { + "path": "metrics/largest-contentful-paint", + }, + Object { + "path": "metrics/first-meaningful-paint", + }, + Object { + "path": "metrics/speed-index", + }, + Object { + "path": "screenshot-thumbnails", + }, + Object { + "path": "final-screenshot", + }, + Object { + "path": "metrics/total-blocking-time", + }, + Object { + "path": "metrics/max-potential-fid", + }, + Object { + "path": "metrics/cumulative-layout-shift", + }, + Object { + "path": "errors-in-console", + }, + Object { + "path": "server-response-time", + }, + Object { + "path": "metrics/interactive", + }, + Object { + "path": "user-timings", + }, + Object { + "path": "critical-request-chains", + }, + Object { + "path": "redirects", + }, + Object { + "path": "installable-manifest", + }, + Object { + "path": "apple-touch-icon", + }, + Object { + "path": "splash-screen", + }, + Object { + "path": "themed-omnibox", + }, + Object { + "path": "maskable-icon", + }, + Object { + "path": "content-width", + }, + Object { + "path": "image-aspect-ratio", + }, + Object { + "path": "image-size-responsive", + }, + Object { + "path": "preload-fonts", + }, + Object { + "path": "deprecations", + }, + Object { + "path": "mainthread-work-breakdown", + }, + Object { + "path": "bootup-time", + }, + Object { + "path": "uses-rel-preload", + }, + Object { + "path": "uses-rel-preconnect", + }, + Object { + "path": "font-display", + }, + Object { + "path": "diagnostics", + }, + Object { + "path": "network-requests", + }, + Object { + "path": "network-rtt", + }, + Object { + "path": "network-server-latency", + }, + Object { + "path": "main-thread-tasks", + }, + Object { + "path": "metrics", + }, + Object { + "path": "performance-budget", + }, + Object { + "path": "timing-budget", + }, + Object { + "path": "resource-summary", + }, + Object { + "path": "third-party-summary", + }, + Object { + "path": "third-party-facades", + }, + Object { + "path": "largest-contentful-paint-element", + }, + Object { + "path": "lcp-lazy-loaded", + }, + Object { + "path": "layout-shift-elements", + }, + Object { + "path": "long-tasks", + }, + Object { + "path": "no-unload-listeners", + }, + Object { + "path": "non-composited-animations", + }, + Object { + "path": "unsized-images", + }, + Object { + "path": "valid-source-maps", + }, + Object { + "path": "preload-lcp-image", + }, + Object { + "path": "csp-xss", + }, + Object { + "path": "full-page-screenshot", + }, + Object { + "path": "script-treemap-data", + }, + Object { + "path": "manual/pwa-cross-browser", + }, + Object { + "path": "manual/pwa-page-transitions", + }, + Object { + "path": "manual/pwa-each-page-has-url", + }, + Object { + "path": "accessibility/accesskeys", + }, + Object { + "path": "accessibility/aria-allowed-attr", + }, + Object { + "path": "accessibility/aria-command-name", + }, + Object { + "path": "accessibility/aria-hidden-body", + }, + Object { + "path": "accessibility/aria-hidden-focus", + }, + Object { + "path": "accessibility/aria-input-field-name", + }, + Object { + "path": "accessibility/aria-meter-name", + }, + Object { + "path": "accessibility/aria-progressbar-name", + }, + Object { + "path": "accessibility/aria-required-attr", + }, + Object { + "path": "accessibility/aria-required-children", + }, + Object { + "path": "accessibility/aria-required-parent", + }, + Object { + "path": "accessibility/aria-roles", + }, + Object { + "path": "accessibility/aria-toggle-field-name", + }, + Object { + "path": "accessibility/aria-tooltip-name", + }, + Object { + "path": "accessibility/aria-treeitem-name", + }, + Object { + "path": "accessibility/aria-valid-attr-value", + }, + Object { + "path": "accessibility/aria-valid-attr", + }, + Object { + "path": "accessibility/button-name", + }, + Object { + "path": "accessibility/bypass", + }, + Object { + "path": "accessibility/color-contrast", + }, + Object { + "path": "accessibility/definition-list", + }, + Object { + "path": "accessibility/dlitem", + }, + Object { + "path": "accessibility/document-title", + }, + Object { + "path": "accessibility/duplicate-id-active", + }, + Object { + "path": "accessibility/duplicate-id-aria", + }, + Object { + "path": "accessibility/form-field-multiple-labels", + }, + Object { + "path": "accessibility/frame-title", + }, + Object { + "path": "accessibility/heading-order", + }, + Object { + "path": "accessibility/html-has-lang", + }, + Object { + "path": "accessibility/html-lang-valid", + }, + Object { + "path": "accessibility/image-alt", + }, + Object { + "path": "accessibility/input-image-alt", + }, + Object { + "path": "accessibility/label", + }, + Object { + "path": "accessibility/link-name", + }, + Object { + "path": "accessibility/list", + }, + Object { + "path": "accessibility/listitem", + }, + Object { + "path": "accessibility/meta-refresh", + }, + Object { + "path": "accessibility/meta-viewport", + }, + Object { + "path": "accessibility/object-alt", + }, + Object { + "path": "accessibility/tabindex", + }, + Object { + "path": "accessibility/td-headers-attr", + }, + Object { + "path": "accessibility/th-has-data-cells", + }, + Object { + "path": "accessibility/valid-lang", + }, + Object { + "path": "accessibility/video-caption", + }, + Object { + "path": "accessibility/manual/custom-controls-labels", + }, + Object { + "path": "accessibility/manual/custom-controls-roles", + }, + Object { + "path": "accessibility/manual/focus-traps", + }, + Object { + "path": "accessibility/manual/focusable-controls", + }, + Object { + "path": "accessibility/manual/interactive-element-affordance", + }, + Object { + "path": "accessibility/manual/logical-tab-order", + }, + Object { + "path": "accessibility/manual/managed-focus", + }, + Object { + "path": "accessibility/manual/offscreen-content-hidden", + }, + Object { + "path": "accessibility/manual/use-landmarks", + }, + Object { + "path": "accessibility/manual/visual-order-follows-dom", + }, + Object { + "path": "byte-efficiency/uses-long-cache-ttl", + }, + Object { + "path": "byte-efficiency/total-byte-weight", + }, + Object { + "path": "byte-efficiency/offscreen-images", + }, + Object { + "path": "byte-efficiency/render-blocking-resources", + }, + Object { + "path": "byte-efficiency/unminified-css", + }, + Object { + "path": "byte-efficiency/unminified-javascript", + }, + Object { + "path": "byte-efficiency/unused-css-rules", + }, + Object { + "path": "byte-efficiency/unused-javascript", + }, + Object { + "path": "byte-efficiency/modern-image-formats", + }, + Object { + "path": "byte-efficiency/uses-optimized-images", + }, + Object { + "path": "byte-efficiency/uses-text-compression", + }, + Object { + "path": "byte-efficiency/uses-responsive-images", + }, + Object { + "path": "byte-efficiency/efficient-animated-content", + }, + Object { + "path": "byte-efficiency/duplicated-javascript", + }, + Object { + "path": "byte-efficiency/legacy-javascript", + }, + Object { + "path": "dobetterweb/doctype", + }, + Object { + "path": "dobetterweb/charset", + }, + Object { + "path": "dobetterweb/dom-size", + }, + Object { + "path": "dobetterweb/geolocation-on-start", + }, + Object { + "path": "dobetterweb/inspector-issues", + }, + Object { + "path": "dobetterweb/no-document-write", + }, + Object { + "path": "dobetterweb/no-vulnerable-libraries", + }, + Object { + "path": "dobetterweb/js-libraries", + }, + Object { + "path": "dobetterweb/notification-on-start", + }, + Object { + "path": "dobetterweb/password-inputs-can-be-pasted-into", + }, + Object { + "path": "dobetterweb/uses-http2", + }, + Object { + "path": "dobetterweb/uses-passive-event-listeners", + }, + Object { + "path": "seo/meta-description", + }, + Object { + "path": "seo/http-status-code", + }, + Object { + "path": "seo/font-size", + }, + Object { + "path": "seo/link-text", + }, + Object { + "path": "seo/crawlable-anchors", + }, + Object { + "path": "seo/is-crawlable", + }, + Object { + "path": "seo/robots-txt", + }, + Object { + "path": "seo/tap-targets", + }, + Object { + "path": "seo/hreflang", + }, + Object { + "path": "seo/plugins", + }, + Object { + "path": "seo/canonical", + }, + Object { + "path": "seo/manual/structured-data", + }, + ], + "categories": Object { + "accessibility": Object { + "auditRefs": Array [ + Object { + "group": "a11y-navigation", + "id": "accesskeys", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-allowed-attr", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-command-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-hidden-body", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-hidden-focus", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-input-field-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-meter-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-progressbar-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-required-attr", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-required-children", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-required-parent", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-roles", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-toggle-field-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-tooltip-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-treeitem-name", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "aria-valid-attr-value", + "weight": 10, + }, + Object { + "group": "a11y-aria", + "id": "aria-valid-attr", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "button-name", + "weight": 10, + }, + Object { + "group": "a11y-navigation", + "id": "bypass", + "weight": 3, + }, + Object { + "group": "a11y-color-contrast", + "id": "color-contrast", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "definition-list", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "dlitem", + "weight": 3, + }, + Object { + "group": "a11y-names-labels", + "id": "document-title", + "weight": 3, + }, + Object { + "group": "a11y-navigation", + "id": "duplicate-id-active", + "weight": 3, + }, + Object { + "group": "a11y-aria", + "id": "duplicate-id-aria", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "form-field-multiple-labels", + "weight": 2, + }, + Object { + "group": "a11y-names-labels", + "id": "frame-title", + "weight": 3, + }, + Object { + "group": "a11y-navigation", + "id": "heading-order", + "weight": 2, + }, + Object { + "group": "a11y-language", + "id": "html-has-lang", + "weight": 3, + }, + Object { + "group": "a11y-language", + "id": "html-lang-valid", + "weight": 3, + }, + Object { + "group": "a11y-names-labels", + "id": "image-alt", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "input-image-alt", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "label", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "link-name", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "list", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "listitem", + "weight": 3, + }, + Object { + "group": "a11y-best-practices", + "id": "meta-refresh", + "weight": 10, + }, + Object { + "group": "a11y-best-practices", + "id": "meta-viewport", + "weight": 10, + }, + Object { + "group": "a11y-names-labels", + "id": "object-alt", + "weight": 3, + }, + Object { + "group": "a11y-navigation", + "id": "tabindex", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "td-headers-attr", + "weight": 3, + }, + Object { + "group": "a11y-tables-lists", + "id": "th-has-data-cells", + "weight": 3, + }, + Object { + "group": "a11y-language", + "id": "valid-lang", + "weight": 3, + }, + Object { + "group": "a11y-audio-video", + "id": "video-caption", + "weight": 10, + }, + Object { + "id": "logical-tab-order", + "weight": 0, + }, + Object { + "id": "focusable-controls", + "weight": 0, + }, + Object { + "id": "interactive-element-affordance", + "weight": 0, + }, + Object { + "id": "managed-focus", + "weight": 0, + }, + Object { + "id": "focus-traps", + "weight": 0, + }, + Object { + "id": "custom-controls-labels", + "weight": 0, + }, + Object { + "id": "custom-controls-roles", + "weight": 0, + }, + Object { + "id": "visual-order-follows-dom", + "weight": 0, + }, + Object { + "id": "offscreen-content-hidden", + "weight": 0, + }, + Object { + "id": "use-landmarks", + "weight": 0, + }, + ], + "description": "These checks highlight opportunities to [improve the accessibility of your web app](https://developers.google.com/web/fundamentals/accessibility). Only a subset of accessibility issues can be automatically detected so manual testing is also encouraged.", + "manualDescription": "These items address areas which an automated testing tool cannot cover. Learn more in our guide on [conducting an accessibility review](https://developers.google.com/web/fundamentals/accessibility/how-to-review).", + "supportedModes": Array [ + "navigation", + "snapshot", + ], + "title": "Accessibility", + }, + "best-practices": Object { + "auditRefs": Array [ + Object { + "group": "best-practices-trust-safety", + "id": "is-on-https", + "weight": 1, + }, + Object { + "group": "best-practices-trust-safety", + "id": "redirects-http", + "weight": 1, + }, + Object { + "group": "best-practices-trust-safety", + "id": "geolocation-on-start", + "weight": 1, + }, + Object { + "group": "best-practices-trust-safety", + "id": "notification-on-start", + "weight": 1, + }, + Object { + "group": "best-practices-trust-safety", + "id": "no-vulnerable-libraries", + "weight": 1, + }, + Object { + "group": "best-practices-trust-safety", + "id": "csp-xss", + "weight": 0, + }, + Object { + "group": "best-practices-ux", + "id": "password-inputs-can-be-pasted-into", + "weight": 1, + }, + Object { + "group": "best-practices-ux", + "id": "image-aspect-ratio", + "weight": 1, + }, + Object { + "group": "best-practices-ux", + "id": "image-size-responsive", + "weight": 1, + }, + Object { + "group": "best-practices-ux", + "id": "preload-fonts", + "weight": 1, + }, + Object { + "group": "best-practices-browser-compat", + "id": "doctype", + "weight": 1, + }, + Object { + "group": "best-practices-browser-compat", + "id": "charset", + "weight": 1, + }, + Object { + "group": "best-practices-general", + "id": "js-libraries", + "weight": 0, + }, + Object { + "group": "best-practices-general", + "id": "deprecations", + "weight": 1, + }, + Object { + "group": "best-practices-general", + "id": "errors-in-console", + "weight": 1, + }, + Object { + "group": "best-practices-general", + "id": "valid-source-maps", + "weight": 0, + }, + Object { + "group": "best-practices-general", + "id": "inspector-issues", + "weight": 1, + }, + ], + "supportedModes": Array [ + "navigation", + "timespan", + "snapshot", + ], + "title": "Best Practices", + }, + "performance": Object { + "auditRefs": Array [ + Object { + "acronym": "FCP", + "group": "metrics", + "id": "first-contentful-paint", + "relevantAudits": Array [ + "server-response-time", + "render-blocking-resources", + "redirects", + "critical-request-chains", + "uses-text-compression", + "uses-rel-preconnect", + "uses-rel-preload", + "font-display", + "unminified-javascript", + "unminified-css", + "unused-css-rules", + ], + "weight": 10, + }, + Object { + "acronym": "TTI", + "group": "metrics", + "id": "interactive", + "weight": 10, + }, + Object { + "acronym": "SI", + "group": "metrics", + "id": "speed-index", + "weight": 10, + }, + Object { + "acronym": "TBT", + "group": "metrics", + "id": "total-blocking-time", + "relevantAudits": Array [ + "long-tasks", + "third-party-summary", + "third-party-facades", + "bootup-time", + "mainthread-work-breakdown", + "dom-size", + "duplicated-javascript", + "legacy-javascript", + "viewport", + ], + "weight": 30, + }, + Object { + "acronym": "LCP", + "group": "metrics", + "id": "largest-contentful-paint", + "relevantAudits": Array [ + "server-response-time", + "render-blocking-resources", + "redirects", + "critical-request-chains", + "uses-text-compression", + "uses-rel-preconnect", + "uses-rel-preload", + "font-display", + "unminified-javascript", + "unminified-css", + "unused-css-rules", + "largest-contentful-paint-element", + "preload-lcp-image", + "unused-javascript", + "efficient-animated-content", + "total-byte-weight", + ], + "weight": 25, + }, + Object { + "acronym": "CLS", + "group": "metrics", + "id": "cumulative-layout-shift", + "relevantAudits": Array [ + "layout-shift-elements", + "non-composited-animations", + "unsized-images", + ], + "weight": 15, + }, + Object { + "group": "hidden", + "id": "max-potential-fid", + "weight": 0, + }, + Object { + "acronym": "FMP", + "group": "hidden", + "id": "first-meaningful-paint", + "weight": 0, + }, + Object { + "id": "render-blocking-resources", + "weight": 0, + }, + Object { + "id": "uses-responsive-images", + "weight": 0, + }, + Object { + "id": "offscreen-images", + "weight": 0, + }, + Object { + "id": "unminified-css", + "weight": 0, + }, + Object { + "id": "unminified-javascript", + "weight": 0, + }, + Object { + "id": "unused-css-rules", + "weight": 0, + }, + Object { + "id": "unused-javascript", + "weight": 0, + }, + Object { + "id": "uses-optimized-images", + "weight": 0, + }, + Object { + "id": "modern-image-formats", + "weight": 0, + }, + Object { + "id": "uses-text-compression", + "weight": 0, + }, + Object { + "id": "uses-rel-preconnect", + "weight": 0, + }, + Object { + "id": "server-response-time", + "weight": 0, + }, + Object { + "id": "redirects", + "weight": 0, + }, + Object { + "id": "uses-rel-preload", + "weight": 0, + }, + Object { + "id": "uses-http2", + "weight": 0, + }, + Object { + "id": "efficient-animated-content", + "weight": 0, + }, + Object { + "id": "duplicated-javascript", + "weight": 0, + }, + Object { + "id": "legacy-javascript", + "weight": 0, + }, + Object { + "id": "preload-lcp-image", + "weight": 0, + }, + Object { + "id": "total-byte-weight", + "weight": 0, + }, + Object { + "id": "uses-long-cache-ttl", + "weight": 0, + }, + Object { + "id": "dom-size", + "weight": 0, + }, + Object { + "id": "critical-request-chains", + "weight": 0, + }, + Object { + "id": "user-timings", + "weight": 0, + }, + Object { + "id": "bootup-time", + "weight": 0, + }, + Object { + "id": "mainthread-work-breakdown", + "weight": 0, + }, + Object { + "id": "font-display", + "weight": 0, + }, + Object { + "id": "resource-summary", + "weight": 0, + }, + Object { + "id": "third-party-summary", + "weight": 0, + }, + Object { + "id": "third-party-facades", + "weight": 0, + }, + Object { + "id": "largest-contentful-paint-element", + "weight": 0, + }, + Object { + "id": "lcp-lazy-loaded", + "weight": 0, + }, + Object { + "id": "layout-shift-elements", + "weight": 0, + }, + Object { + "id": "uses-passive-event-listeners", + "weight": 0, + }, + Object { + "id": "no-document-write", + "weight": 0, + }, + Object { + "id": "long-tasks", + "weight": 0, + }, + Object { + "id": "non-composited-animations", + "weight": 0, + }, + Object { + "id": "unsized-images", + "weight": 0, + }, + Object { + "id": "viewport", + "weight": 0, + }, + Object { + "id": "no-unload-listeners", + "weight": 0, + }, + Object { + "group": "budgets", + "id": "performance-budget", + "weight": 0, + }, + Object { + "group": "budgets", + "id": "timing-budget", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "network-requests", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "network-rtt", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "network-server-latency", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "main-thread-tasks", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "diagnostics", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "metrics", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "screenshot-thumbnails", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "final-screenshot", + "weight": 0, + }, + Object { + "group": "hidden", + "id": "script-treemap-data", + "weight": 0, + }, + ], + "supportedModes": Array [ + "navigation", + "timespan", + "snapshot", + ], + "title": "Performance", + }, + "pwa": Object { + "auditRefs": Array [ + Object { + "group": "pwa-installable", + "id": "installable-manifest", + "weight": 2, + }, + Object { + "group": "pwa-optimized", + "id": "service-worker", + "weight": 1, + }, + Object { + "group": "pwa-optimized", + "id": "redirects-http", + "weight": 2, + }, + Object { + "group": "pwa-optimized", + "id": "splash-screen", + "weight": 1, + }, + Object { + "group": "pwa-optimized", + "id": "themed-omnibox", + "weight": 1, + }, + Object { + "group": "pwa-optimized", + "id": "content-width", + "weight": 1, + }, + Object { + "group": "pwa-optimized", + "id": "viewport", + "weight": 2, + }, + Object { + "group": "pwa-optimized", + "id": "apple-touch-icon", + "weight": 1, + }, + Object { + "group": "pwa-optimized", + "id": "maskable-icon", + "weight": 1, + }, + Object { + "id": "pwa-cross-browser", + "weight": 0, + }, + Object { + "id": "pwa-page-transitions", + "weight": 0, + }, + Object { + "id": "pwa-each-page-has-url", + "weight": 0, + }, + ], + "description": "These checks validate the aspects of a Progressive Web App. [Learn more](https://developers.google.com/web/progressive-web-apps/checklist).", + "manualDescription": "These checks are required by the baseline [PWA Checklist](https://developers.google.com/web/progressive-web-apps/checklist) but are not automatically checked by Lighthouse. They do not affect your score but it's important that you verify them manually.", + "supportedModes": Array [ + "navigation", + ], + "title": "PWA", + }, + "seo": Object { + "auditRefs": Array [ + Object { + "group": "seo-mobile", + "id": "viewport", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "document-title", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "meta-description", + "weight": 1, + }, + Object { + "group": "seo-crawl", + "id": "http-status-code", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "link-text", + "weight": 1, + }, + Object { + "group": "seo-crawl", + "id": "crawlable-anchors", + "weight": 1, + }, + Object { + "group": "seo-crawl", + "id": "is-crawlable", + "weight": 1, + }, + Object { + "group": "seo-crawl", + "id": "robots-txt", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "image-alt", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "hreflang", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "canonical", + "weight": 1, + }, + Object { + "group": "seo-mobile", + "id": "font-size", + "weight": 1, + }, + Object { + "group": "seo-content", + "id": "plugins", + "weight": 1, + }, + Object { + "group": "seo-mobile", + "id": "tap-targets", + "weight": 1, + }, + Object { + "id": "structured-data", + "weight": 0, + }, + ], + "description": "These checks ensure that your page is following basic search engine optimization advice. There are many additional factors Lighthouse does not score here that may affect your search ranking, including performance on [Core Web Vitals](https://web.dev/learn-web-vitals/). [Learn more](https://support.google.com/webmasters/answer/35769).", + "manualDescription": "Run these additional validators on your site to check additional SEO best practices.", + "supportedModes": Array [ + "navigation", + "snapshot", + ], + "title": "SEO", + }, + }, + "groups": Object { + "a11y-aria": Object { + "description": "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader.", + "title": "ARIA", + }, + "a11y-audio-video": Object { + "description": "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments.", + "title": "Audio and video", + }, + "a11y-best-practices": Object { + "description": "These items highlight common accessibility best practices.", + "title": "Best practices", + }, + "a11y-color-contrast": Object { + "description": "These are opportunities to improve the legibility of your content.", + "title": "Contrast", + }, + "a11y-language": Object { + "description": "These are opportunities to improve the interpretation of your content by users in different locales.", + "title": "Internationalization and localization", + }, + "a11y-names-labels": Object { + "description": "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader.", + "title": "Names and labels", + }, + "a11y-navigation": Object { + "description": "These are opportunities to improve keyboard navigation in your application.", + "title": "Navigation", + }, + "a11y-tables-lists": Object { + "description": "These are opportunities to improve the experience of reading tabular or list data using assistive technology, like a screen reader.", + "title": "Tables and lists", + }, + "best-practices-browser-compat": Object { + "title": "Browser Compatibility", + }, + "best-practices-general": Object { + "title": "General", + }, + "best-practices-trust-safety": Object { + "title": "Trust and Safety", + }, + "best-practices-ux": Object { + "title": "User Experience", + }, + "budgets": Object { + "description": "Performance budgets set standards for the performance of your site.", + "title": "Budgets", + }, + "diagnostics": Object { + "description": "More information about the performance of your application. These numbers don't [directly affect](https://web.dev/performance-scoring/) the Performance score.", + "title": "Diagnostics", + }, + "hidden": Object { + "title": "", + }, + "load-opportunities": Object { + "description": "These suggestions can help your page load faster. They don't [directly affect](https://web.dev/performance-scoring/) the Performance score.", + "title": "Opportunities", + }, + "metrics": Object { + "title": "Metrics", + }, + "pwa-installable": Object { + "title": "Installable", + }, + "pwa-optimized": Object { + "title": "PWA Optimized", + }, + "seo-content": Object { + "description": "Format your HTML in a way that enables crawlers to better understand your app’s content.", + "title": "Content Best Practices", + }, + "seo-crawl": Object { + "description": "To appear in search results, crawlers need access to your app.", + "title": "Crawling and Indexing", + }, + "seo-mobile": Object { + "description": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn more](https://developers.google.com/search/mobile-sites/).", + "title": "Mobile Friendly", + }, + }, + "passes": Array [ + Object { + "blankPage": "about:blank", + "blockedUrlPatterns": Array [], + "cpuQuietThresholdMs": 1000, + "gatherers": Array [ + Object { + "path": "css-usage", + }, + Object { + "path": "js-usage", + }, + Object { + "path": "viewport-dimensions", + }, + Object { + "path": "console-messages", + }, + Object { + "path": "anchor-elements", + }, + Object { + "path": "image-elements", + }, + Object { + "path": "link-elements", + }, + Object { + "path": "meta-elements", + }, + Object { + "path": "script-elements", + }, + Object { + "path": "iframe-elements", + }, + Object { + "path": "form-elements", + }, + Object { + "path": "main-document-content", + }, + Object { + "path": "global-listeners", + }, + Object { + "path": "dobetterweb/doctype", + }, + Object { + "path": "dobetterweb/domstats", + }, + Object { + "path": "dobetterweb/optimized-images", + }, + Object { + "path": "dobetterweb/password-inputs-with-prevented-paste", + }, + Object { + "path": "dobetterweb/response-compression", + }, + Object { + "path": "dobetterweb/tags-blocking-first-paint", + }, + Object { + "path": "seo/font-size", + }, + Object { + "path": "seo/embedded-content", + }, + Object { + "path": "seo/robots-txt", + }, + Object { + "path": "seo/tap-targets", + }, + Object { + "path": "accessibility", + }, + Object { + "path": "trace-elements", + }, + Object { + "path": "inspector-issues", + }, + Object { + "path": "source-maps", + }, + Object { + "path": "full-page-screenshot", + }, + ], + "loadFailureMode": "fatal", + "networkQuietThresholdMs": 1000, + "passName": "defaultPass", + "pauseAfterFcpMs": 1000, + "pauseAfterLoadMs": 1000, + "recordTrace": true, + "useThrottling": true, + }, + Object { + "blankPage": "about:blank", + "blockedUrlPatterns": Array [], + "cpuQuietThresholdMs": 0, + "gatherers": Array [ + Object { + "path": "service-worker", + }, + ], + "loadFailureMode": "ignore", + "networkQuietThresholdMs": 0, + "passName": "offlinePass", + "pauseAfterFcpMs": 0, + "pauseAfterLoadMs": 0, + "recordTrace": false, + "useThrottling": false, + }, + ], + "settings": Object { + "additionalTraceCategories": null, + "auditMode": false, + "blockedUrlPatterns": null, + "budgets": null, + "channel": "cli", + "debugNavigation": false, + "disableStorageReset": false, + "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4695.0 Mobile Safari/537.36 Chrome-Lighthouse", + "extraHeaders": null, + "formFactor": "mobile", + "gatherMode": false, + "locale": "en-US", + "maxWaitForFcp": 30000, + "maxWaitForLoad": 45000, + "onlyAudits": null, + "onlyCategories": null, + "output": Array [ + "html", + ], + "precomputedLanternData": null, + "screenEmulation": Object { + "deviceScaleFactor": 2.625, + "disabled": false, + "height": 640, + "mobile": true, + "width": 360, + }, + "skipAudits": null, + "throttling": Object { + "cpuSlowdownMultiplier": 4, + "downloadThroughputKbps": 1474.5600000000002, + "requestLatencyMs": 562.5, + "rttMs": 150, + "throughputKbps": 1638.4, + "uploadThroughputKbps": 675, + }, + "throttlingMethod": "simulate", + }, +} +`; + +exports[`CLI Tests print-config should print the overridden config and exit immediately after 1`] = ` +Object { + "audits": Array [ + Object { + "path": "metrics", + }, + ], + "categories": Object { + "performance": Object { + "auditRefs": Array [ + Object { + "group": "hidden", + "id": "metrics", + "weight": 0, + }, + ], + "supportedModes": Array [ + "navigation", + "timespan", + "snapshot", + ], + "title": "Performance", + }, + }, + "groups": Object { + "a11y-aria": Object { + "description": "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader.", + "title": "ARIA", + }, + "a11y-audio-video": Object { + "description": "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments.", + "title": "Audio and video", + }, + "a11y-best-practices": Object { + "description": "These items highlight common accessibility best practices.", + "title": "Best practices", + }, + "a11y-color-contrast": Object { + "description": "These are opportunities to improve the legibility of your content.", + "title": "Contrast", + }, + "a11y-language": Object { + "description": "These are opportunities to improve the interpretation of your content by users in different locales.", + "title": "Internationalization and localization", + }, + "a11y-names-labels": Object { + "description": "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader.", + "title": "Names and labels", + }, + "a11y-navigation": Object { + "description": "These are opportunities to improve keyboard navigation in your application.", + "title": "Navigation", + }, + "a11y-tables-lists": Object { + "description": "These are opportunities to improve the experience of reading tabular or list data using assistive technology, like a screen reader.", + "title": "Tables and lists", + }, + "best-practices-browser-compat": Object { + "title": "Browser Compatibility", + }, + "best-practices-general": Object { + "title": "General", + }, + "best-practices-trust-safety": Object { + "title": "Trust and Safety", + }, + "best-practices-ux": Object { + "title": "User Experience", + }, + "budgets": Object { + "description": "Performance budgets set standards for the performance of your site.", + "title": "Budgets", + }, + "diagnostics": Object { + "description": "More information about the performance of your application. These numbers don't [directly affect](https://web.dev/performance-scoring/) the Performance score.", + "title": "Diagnostics", + }, + "hidden": Object { + "title": "", + }, + "load-opportunities": Object { + "description": "These suggestions can help your page load faster. They don't [directly affect](https://web.dev/performance-scoring/) the Performance score.", + "title": "Opportunities", + }, + "metrics": Object { + "title": "Metrics", + }, + "pwa-installable": Object { + "title": "Installable", + }, + "pwa-optimized": Object { + "title": "PWA Optimized", + }, + "seo-content": Object { + "description": "Format your HTML in a way that enables crawlers to better understand your app’s content.", + "title": "Content Best Practices", + }, + "seo-crawl": Object { + "description": "To appear in search results, crawlers need access to your app.", + "title": "Crawling and Indexing", + }, + "seo-mobile": Object { + "description": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn more](https://developers.google.com/search/mobile-sites/).", + "title": "Mobile Friendly", + }, + }, + "passes": Array [ + Object { + "blankPage": "about:blank", + "blockedUrlPatterns": Array [], + "cpuQuietThresholdMs": 1000, + "gatherers": Array [], + "loadFailureMode": "fatal", + "networkQuietThresholdMs": 1000, + "passName": "defaultPass", + "pauseAfterFcpMs": 1000, + "pauseAfterLoadMs": 1000, + "recordTrace": true, + "useThrottling": true, + }, + ], + "settings": Object { + "additionalTraceCategories": null, + "auditMode": true, + "blockedUrlPatterns": null, + "budgets": null, + "channel": "cli", + "debugNavigation": false, + "disableStorageReset": false, + "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4695.0 Mobile Safari/537.36 Chrome-Lighthouse", + "extraHeaders": null, + "formFactor": "mobile", + "gatherMode": false, + "locale": "en-US", + "maxWaitForFcp": 30000, + "maxWaitForLoad": 45000, + "onlyAudits": Array [ + "metrics", + ], + "onlyCategories": null, + "output": Array [ + "json", + ], + "precomputedLanternData": null, + "screenEmulation": Object { + "deviceScaleFactor": 2.625, + "disabled": false, + "height": 640, + "mobile": true, + "width": 360, + }, + "skipAudits": null, + "throttling": Object { + "cpuSlowdownMultiplier": 4, + "downloadThroughputKbps": 1474.5600000000002, + "requestLatencyMs": 562.5, + "rttMs": 150, + "throughputKbps": 1638.4, + "uploadThroughputKbps": 675, + }, + "throttlingMethod": "simulate", + }, +} +`; diff --git a/report/test/renderer/report-renderer-test.js b/report/test/renderer/report-renderer-test.js index 03a4e85e504e..e12141ee73ae 100644 --- a/report/test/renderer/report-renderer-test.js +++ b/report/test/renderer/report-renderer-test.js @@ -302,6 +302,7 @@ describe('ReportRenderer', () => { // The performance-budget audit is omitted from the DOM when it is not applicable if (audit.scoreDisplayMode === 'notApplicable' && audit.id !== 'performance-budget') { notApplicableCount++; + // Switch to old-style `not_applicable` to test fallback behavior. audit.scoreDisplayMode = 'not_applicable'; } }); @@ -310,8 +311,11 @@ describe('ReportRenderer', () => { const container = renderer._dom.document().body; const reportElement = renderer.renderReport(sampleResults, container); - const notApplicableElementCount = reportElement - .querySelectorAll('.lh-audit--notapplicable').length; + const notApplicableElements = [...reportElement.querySelectorAll('.lh-audit--notapplicable')]; + // Audits can be included multiple times in the report, so dedupe by id. + const uniqueNotApplicableElements = new Set(notApplicableElements.map(el => el.id)); + const notApplicableElementCount = uniqueNotApplicableElements.size; + assert.strictEqual(notApplicableCount, notApplicableElementCount); }); }); diff --git a/shared/localization/locales/en-US.json b/shared/localization/locales/en-US.json index 736871d92aee..0a7ff0f2b1ed 100644 --- a/shared/localization/locales/en-US.json +++ b/shared/localization/locales/en-US.json @@ -1322,6 +1322,15 @@ "core/audits/prioritize-lcp-image.js | title": { "message": "Preload Largest Contentful Paint image" }, + "core/audits/redirects-http.js | description": { + "message": "Make sure that you redirect all HTTP traffic to HTTPS in order to enable secure web features for all your users. [Learn more](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/)." + }, + "core/audits/redirects-http.js | failureTitle": { + "message": "Does not redirect HTTP traffic to HTTPS" + }, + "core/audits/redirects-http.js | title": { + "message": "Redirects HTTP traffic to HTTPS" + }, "core/audits/redirects.js | description": { "message": "Redirects introduce additional delays before the page can be loaded. [Learn how to avoid page redirects](https://developer.chrome.com/docs/lighthouse/performance/redirects/)." }, diff --git a/shared/localization/locales/en-XL.json b/shared/localization/locales/en-XL.json index 6b082df0ebd9..1a5bebaf937e 100644 --- a/shared/localization/locales/en-XL.json +++ b/shared/localization/locales/en-XL.json @@ -1322,6 +1322,15 @@ "core/audits/prioritize-lcp-image.js | title": { "message": "P̂ŕêĺôád̂ Ĺâŕĝéŝt́ Ĉón̂t́êńt̂f́ûĺ P̂áîńt̂ ím̂áĝé" }, + "core/audits/redirects-http.js | description": { + "message": "M̂ák̂é ŝúr̂é t̂h́ât́ ŷóû ŕêd́îŕêćt̂ ál̂ĺ ĤT́T̂Ṕ t̂ŕâf́f̂íĉ t́ô H́T̂T́P̂Ś îń ôŕd̂ér̂ t́ô én̂áb̂ĺê śêćûŕê ẃêb́ f̂éât́ûŕêś f̂ór̂ ál̂ĺ ŷóûŕ ûśêŕŝ. [Ĺêár̂ń m̂ór̂é](https://developer.chrome.com/docs/lighthouse/pwa/redirects-http/)." + }, + "core/audits/redirects-http.js | failureTitle": { + "message": "D̂óêś n̂ót̂ ŕêd́îŕêćt̂ H́T̂T́P̂ t́r̂áf̂f́îć t̂ó ĤT́T̂ṔŜ" + }, + "core/audits/redirects-http.js | title": { + "message": "R̂éd̂ír̂éĉt́ŝ H́T̂T́P̂ t́r̂áf̂f́îć t̂ó ĤT́T̂ṔŜ" + }, "core/audits/redirects.js | description": { "message": "R̂éd̂ír̂éĉt́ŝ ín̂t́r̂ód̂úĉé âd́d̂ít̂íôńâĺ d̂él̂áŷś b̂éf̂ór̂é t̂h́ê ṕâǵê ćâń b̂é l̂óâd́êd́. [L̂éâŕn̂ h́ôẃ t̂ó âv́ôíd̂ ṕâǵê ŕêd́îŕêćt̂ś](https://developer.chrome.com/docs/lighthouse/performance/redirects/)." }, diff --git a/third-party/devtools-tests/e2e/lighthouse/navigation_test.ts b/third-party/devtools-tests/e2e/lighthouse/navigation_test.ts index 29f958986a03..248bb90e47a9 100644 --- a/third-party/devtools-tests/e2e/lighthouse/navigation_test.ts +++ b/third-party/devtools-tests/e2e/lighthouse/navigation_test.ts @@ -122,7 +122,7 @@ describe('Navigation', function() { }); const {auditResults, erroredAudits, failedAudits} = getAuditsBreakdown(lhr, ['max-potential-fid']); - assert.strictEqual(auditResults.length, 161); + assert.strictEqual(auditResults.length, 162); assert.deepStrictEqual(erroredAudits, []); assert.deepStrictEqual(failedAudits.map(audit => audit.id), [ 'installable-manifest', @@ -204,7 +204,7 @@ describe('Navigation', function() { ]; const {auditResults, erroredAudits, failedAudits} = getAuditsBreakdown(lhr, flakyAudits); - assert.strictEqual(auditResults.length, 161); + assert.strictEqual(auditResults.length, 162); assert.deepStrictEqual(erroredAudits, []); assert.deepStrictEqual(failedAudits.map(audit => audit.id), [ 'installable-manifest',