lighthouse 9.5.0-dev.20220509 → 9.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +70 -0
- package/dist/report/bundle.esm.js +400 -808
- package/dist/report/flow.js +22 -27
- package/dist/report/standalone.js +18 -23
- package/flow-report/src/summary/category.tsx +1 -1
- package/jest.config.js +1 -1
- package/lighthouse-cli/.eslintrc.cjs +4 -3
- package/lighthouse-cli/bin.js +1 -0
- package/lighthouse-cli/cli-flags.js +4 -3
- package/lighthouse-cli/commands/commands.js +1 -0
- package/lighthouse-cli/commands/list-audits.js +1 -0
- package/lighthouse-cli/commands/list-locales.js +1 -0
- package/lighthouse-cli/commands/list-trace-categories.js +1 -0
- package/lighthouse-cli/index.js +1 -0
- package/lighthouse-cli/printer.js +1 -0
- package/lighthouse-cli/run.js +24 -9
- package/lighthouse-cli/sentry-prompt.js +1 -0
- package/lighthouse-cli/test/smokehouse/core-tests.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/lib.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -0
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -0
- package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -0
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +23 -109
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +3 -2
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +19 -28
- package/lighthouse-cli/test/smokehouse/report-assert.js +4 -3
- package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
- package/lighthouse-cli/test/smokehouse/version-check-test.js +3 -0
- package/lighthouse-cli/test/smokehouse/version-check.js +1 -0
- package/lighthouse-core/audits/accessibility/accesskeys.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-allowed-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-body.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-hidden-focus.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-input-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-children.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-required-parent.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-roles.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-toggle-field-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr-value.js +1 -1
- package/lighthouse-core/audits/accessibility/aria-valid-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/button-name.js +1 -1
- package/lighthouse-core/audits/accessibility/bypass.js +1 -1
- package/lighthouse-core/audits/accessibility/color-contrast.js +1 -1
- package/lighthouse-core/audits/accessibility/definition-list.js +1 -1
- package/lighthouse-core/audits/accessibility/dlitem.js +1 -1
- package/lighthouse-core/audits/accessibility/document-title.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-active.js +1 -1
- package/lighthouse-core/audits/accessibility/duplicate-id-aria.js +1 -1
- package/lighthouse-core/audits/accessibility/form-field-multiple-labels.js +1 -1
- package/lighthouse-core/audits/accessibility/frame-title.js +1 -1
- package/lighthouse-core/audits/accessibility/heading-order.js +1 -1
- package/lighthouse-core/audits/accessibility/html-has-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/html-lang-valid.js +1 -1
- package/lighthouse-core/audits/accessibility/image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/input-image-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/label.js +1 -1
- package/lighthouse-core/audits/accessibility/link-name.js +1 -1
- package/lighthouse-core/audits/accessibility/list.js +1 -1
- package/lighthouse-core/audits/accessibility/listitem.js +5 -5
- package/lighthouse-core/audits/accessibility/meta-refresh.js +1 -1
- package/lighthouse-core/audits/accessibility/meta-viewport.js +1 -1
- package/lighthouse-core/audits/accessibility/object-alt.js +1 -1
- package/lighthouse-core/audits/accessibility/tabindex.js +1 -1
- package/lighthouse-core/audits/accessibility/td-headers-attr.js +1 -1
- package/lighthouse-core/audits/accessibility/th-has-data-cells.js +1 -1
- package/lighthouse-core/audits/accessibility/valid-lang.js +1 -1
- package/lighthouse-core/audits/accessibility/video-caption.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
- package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +12 -11
- package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +24 -22
- package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +2 -3
- package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +3 -2
- package/lighthouse-core/audits/byte-efficiency/unminified-css.js +5 -3
- package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +11 -10
- package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -0
- package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +8 -11
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
- package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
- package/lighthouse-core/audits/deprecations.js +598 -8
- package/lighthouse-core/audits/diagnostics.js +3 -4
- package/lighthouse-core/audits/dobetterweb/doctype.js +9 -20
- package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/no-document-write.js +1 -1
- package/lighthouse-core/audits/dobetterweb/notification-on-start.js +1 -1
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -2
- package/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +1 -1
- package/lighthouse-core/audits/errors-in-console.js +2 -2
- package/lighthouse-core/audits/long-tasks.js +2 -3
- package/lighthouse-core/audits/metrics/experimental-interaction-to-next-paint.js +3 -1
- package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
- package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/interactive.js +2 -3
- package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -3
- package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -3
- package/lighthouse-core/audits/metrics/speed-index.js +2 -3
- package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -3
- package/lighthouse-core/audits/metrics.js +2 -3
- package/lighthouse-core/audits/no-unload-listeners.js +15 -7
- package/lighthouse-core/audits/predictive-perf.js +1 -2
- package/lighthouse-core/audits/preload-lcp-image.js +3 -3
- package/lighthouse-core/audits/redirects.js +1 -1
- package/lighthouse-core/audits/script-treemap-data.js +45 -45
- package/lighthouse-core/audits/seo/http-status-code.js +4 -2
- package/lighthouse-core/audits/seo/link-text.js +0 -2
- package/lighthouse-core/audits/server-response-time.js +17 -2
- package/lighthouse-core/audits/service-worker.js +2 -7
- package/lighthouse-core/audits/timing-budget.js +2 -3
- package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
- package/lighthouse-core/audits/uses-rel-preload.js +1 -1
- package/lighthouse-core/audits/valid-source-maps.js +14 -12
- package/lighthouse-core/audits/violation-audit.js +1 -1
- package/lighthouse-core/audits/work-during-interaction.js +280 -0
- package/lighthouse-core/computed/critical-request-chains.js +9 -5
- package/lighthouse-core/computed/js-bundles.js +11 -11
- package/lighthouse-core/computed/main-resource.js +2 -3
- package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-metric.js +5 -3
- package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
- package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
- package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
- package/lighthouse-core/computed/metrics/metric.js +0 -1
- package/lighthouse-core/computed/metrics/responsiveness.js +12 -9
- package/lighthouse-core/computed/metrics/speed-index.js +1 -1
- package/lighthouse-core/computed/metrics/timing-summary.js +6 -13
- package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
- package/lighthouse-core/computed/module-duplication.js +5 -6
- package/lighthouse-core/computed/page-dependency-graph.js +28 -55
- package/lighthouse-core/computed/resource-summary.js +5 -5
- package/lighthouse-core/computed/unused-css.js +7 -6
- package/lighthouse-core/computed/unused-javascript-summary.js +36 -16
- package/lighthouse-core/config/budget.js +2 -2
- package/lighthouse-core/config/default-config.js +1 -2
- package/lighthouse-core/config/metrics-to-audits.js +5 -0
- package/lighthouse-core/fraggle-rock/api.js +1 -1
- package/lighthouse-core/fraggle-rock/config/default-config.js +8 -5
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +3 -6
- package/lighthouse-core/fraggle-rock/gather/driver.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +26 -51
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
- package/lighthouse-core/fraggle-rock/gather/session.js +2 -2
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -5
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +6 -6
- package/lighthouse-core/gather/connections/cri.js +0 -1
- package/lighthouse-core/gather/driver/execution-context.js +2 -4
- package/lighthouse-core/gather/driver/navigation.js +9 -9
- package/lighthouse-core/gather/driver/network-monitor.js +3 -16
- package/lighthouse-core/gather/driver.js +1 -6
- package/lighthouse-core/gather/fetcher.js +210 -34
- package/lighthouse-core/gather/gather-runner.js +17 -13
- package/lighthouse-core/gather/gatherers/accessibility.js +4 -16
- package/lighthouse-core/gather/gatherers/console-messages.js +2 -4
- package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +2 -4
- package/lighthouse-core/gather/gatherers/full-page-screenshot.js +2 -3
- package/lighthouse-core/gather/gatherers/js-usage.js +87 -12
- package/lighthouse-core/gather/gatherers/link-elements.js +14 -12
- package/lighthouse-core/gather/gatherers/main-document-content.js +8 -8
- package/lighthouse-core/gather/gatherers/script-elements.js +56 -7
- package/lighthouse-core/gather/gatherers/seo/robots-txt.js +30 -2
- package/lighthouse-core/gather/gatherers/source-maps.js +1 -3
- package/lighthouse-core/gather/gatherers/trace-elements.js +21 -2
- package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
- package/lighthouse-core/index.js +2 -26
- package/lighthouse-core/lib/cdt/generated/SourceMap.js +1 -1
- package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +29 -8
- package/lighthouse-core/lib/navigation-error.js +4 -13
- package/lighthouse-core/lib/script-helpers.js +6 -11
- package/lighthouse-core/lib/url-shim.js +2 -2
- package/lighthouse-core/runner.js +5 -0
- package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -0
- package/lighthouse-core/util-commonjs.js +24 -28
- package/package.json +12 -12
- package/readme.md +1 -1
- package/report/.eslintrc.cjs +1 -3
- package/report/assets/styles.css +10 -12
- package/report/assets/templates.html +9 -10
- package/report/clients/bundle.js +1 -0
- package/report/clients/standalone.js +1 -0
- package/report/generator/report-generator.js +21 -46
- package/report/renderer/api.js +1 -0
- package/report/renderer/category-renderer.js +1 -0
- package/report/renderer/components.js +304 -303
- package/report/renderer/crc-details-renderer.js +1 -0
- package/report/renderer/details-renderer.js +10 -10
- package/report/renderer/dom.js +1 -0
- package/report/renderer/drop-down-menu.js +1 -0
- package/report/renderer/element-screenshot-renderer.js +4 -0
- package/report/renderer/features-util.js +1 -0
- package/report/renderer/i18n.js +62 -118
- package/report/renderer/logger.js +1 -0
- package/report/renderer/open-tab.js +3 -1
- package/report/renderer/performance-category-renderer.js +1 -0
- package/report/renderer/pwa-category-renderer.js +1 -0
- package/report/renderer/report-renderer.js +1 -0
- package/report/renderer/report-ui-features.js +1 -0
- package/report/renderer/snippet-renderer.js +1 -0
- package/report/renderer/swap-locale-feature.js +1 -0
- package/report/renderer/text-encoding.js +1 -0
- package/report/renderer/topbar-features.js +1 -0
- package/report/renderer/util.js +24 -27
- package/report/test/clients/bundle-test.js +4 -0
- package/report/test/generator/file-namer-test.js +1 -0
- package/report/test/generator/report-generator-test.js +20 -25
- package/report/test/renderer/category-renderer-test.js +3 -0
- package/report/test/renderer/components-test.js +3 -0
- package/report/test/renderer/crc-details-renderer-test.js +3 -0
- package/report/test/renderer/details-renderer-test.js +12 -58
- package/report/test/renderer/dom-test.js +3 -0
- package/report/test/renderer/element-screenshot-renderer-test.js +6 -3
- package/report/test/renderer/i18n-test.js +25 -70
- package/report/test/renderer/performance-category-renderer-test.js +4 -11
- package/report/test/renderer/pwa-category-renderer-test.js +3 -0
- package/report/test/renderer/report-renderer-axe-test.js +3 -0
- package/report/test/renderer/report-renderer-test.js +3 -0
- package/report/test/renderer/report-ui-features-test.js +3 -0
- package/report/test/renderer/snippet-renderer-test.js +3 -0
- package/report/test/renderer/text-encoding-test.js +3 -0
- package/report/test/renderer/util-test.js +5 -2
- package/report/test-assets/faux-psi.js +1 -2
- package/shared/localization/locales/en-US.json +260 -53
- package/shared/localization/locales/en-XL.json +260 -53
- package/shared/test/localization/format-test.js +2 -0
- package/shared/test/localization/locales-test.js +2 -0
- package/shared/test/localization/swap-locale-test.js +2 -0
- package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -0
- package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
- package/tsconfig.json +0 -1
- package/types/artifacts.d.ts +9 -48
- package/types/config.d.ts +0 -2
- package/types/externs.d.ts +2 -2
- package/types/gatherer.d.ts +2 -1
- package/types/global-lh.d.ts +0 -3
- package/types/lhr/audit-details.d.ts +3 -1
- package/types/lhr/lhr.d.ts +2 -2
- package/types/lhr/treemap.d.ts +1 -0
- package/lighthouse-core/audits/script-elements-test-audit.js +0 -30
- package/lighthouse-core/gather/gatherers/scripts.js +0 -154
- package/report/test/.eslintrc.cjs +0 -11
- package/shared/test/localization/.eslintrc.cjs +0 -11
|
@@ -35,10 +35,7 @@ async function getBaseArtifacts(config, driver, context) {
|
|
|
35
35
|
HostFormFactor: userAgent.includes('Android') || userAgent.includes('Mobile') ?
|
|
36
36
|
'mobile' : 'desktop',
|
|
37
37
|
// Contextual artifacts whose collection changes based on gather mode.
|
|
38
|
-
URL: {
|
|
39
|
-
initialUrl: '',
|
|
40
|
-
finalUrl: '',
|
|
41
|
-
},
|
|
38
|
+
URL: {requestedUrl: '', finalUrl: ''},
|
|
42
39
|
PageLoadError: null,
|
|
43
40
|
GatherContext: context,
|
|
44
41
|
// Artifacts that have been replaced by regular gatherers in Fraggle Rock.
|
|
@@ -86,11 +83,11 @@ function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
|
|
|
86
83
|
artifacts.LighthouseRunWarnings = deduplicateWarnings(warnings);
|
|
87
84
|
|
|
88
85
|
if (artifacts.PageLoadError && !artifacts.URL.finalUrl) {
|
|
89
|
-
artifacts.URL.finalUrl = artifacts.URL.requestedUrl
|
|
86
|
+
artifacts.URL.finalUrl = artifacts.URL.requestedUrl;
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
// Check that the runner remembered to mutate the special-case URL artifact.
|
|
93
|
-
if (!artifacts.URL.
|
|
90
|
+
if (!artifacts.URL.requestedUrl) throw new Error('Runner did not set requestedUrl');
|
|
94
91
|
if (!artifacts.URL.finalUrl) throw new Error('Runner did not set finalUrl');
|
|
95
92
|
|
|
96
93
|
return artifacts;
|
|
@@ -35,7 +35,7 @@ const defaultSession = {
|
|
|
35
35
|
/** @implements {LH.Gatherer.FRTransitionalDriver} */
|
|
36
36
|
class Driver {
|
|
37
37
|
/**
|
|
38
|
-
* @param {
|
|
38
|
+
* @param {import('puppeteer').Page} page
|
|
39
39
|
*/
|
|
40
40
|
constructor(page) {
|
|
41
41
|
this._page = page;
|
|
@@ -74,7 +74,7 @@ class Driver {
|
|
|
74
74
|
const session = await this._page.target().createCDPSession();
|
|
75
75
|
this._session = this.defaultSession = new ProtocolSession(session);
|
|
76
76
|
this._executionContext = new ExecutionContext(this._session);
|
|
77
|
-
this._fetcher = new Fetcher(this._session);
|
|
77
|
+
this._fetcher = new Fetcher(this._session, this._executionContext);
|
|
78
78
|
log.timeEnd(status);
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const puppeteer = require('puppeteer-core');
|
|
9
8
|
const log = require('lighthouse-logger');
|
|
10
9
|
const Driver = require('./driver.js');
|
|
11
10
|
const Runner = require('../../runner.js');
|
|
@@ -44,20 +43,18 @@ const NetworkRecords = require('../../computed/network-records.js');
|
|
|
44
43
|
|
|
45
44
|
/** @typedef {Omit<Parameters<typeof collectPhaseArtifacts>[0], 'phase'>} PhaseState */
|
|
46
45
|
|
|
47
|
-
const DEFAULT_HOSTNAME = '127.0.0.1';
|
|
48
|
-
const DEFAULT_PORT = 9222;
|
|
49
|
-
|
|
50
46
|
/**
|
|
51
|
-
* @param {{driver: Driver, config: LH.Config.FRConfig, options?: InternalOptions}} args
|
|
47
|
+
* @param {{driver: Driver, config: LH.Config.FRConfig, requestor: LH.NavigationRequestor, options?: InternalOptions}} args
|
|
52
48
|
* @return {Promise<{baseArtifacts: LH.FRBaseArtifacts}>}
|
|
53
49
|
*/
|
|
54
|
-
async function _setup({driver, config, options}) {
|
|
50
|
+
async function _setup({driver, config, requestor, options}) {
|
|
55
51
|
await driver.connect();
|
|
56
52
|
if (!options?.skipAboutBlank) {
|
|
57
53
|
await gotoURL(driver, defaultNavigationConfig.blankPage, {waitUntil: ['navigated']});
|
|
58
54
|
}
|
|
59
55
|
|
|
60
56
|
const baseArtifacts = await getBaseArtifacts(config, driver, {gatherMode: 'navigation'});
|
|
57
|
+
if (typeof requestor === 'string') baseArtifacts.URL.requestedUrl = requestor;
|
|
61
58
|
|
|
62
59
|
await prepare.prepareTargetForNavigationMode(driver, config.settings);
|
|
63
60
|
|
|
@@ -93,32 +90,25 @@ async function _cleanupNavigation({driver}) {
|
|
|
93
90
|
|
|
94
91
|
/**
|
|
95
92
|
* @param {NavigationContext} navigationContext
|
|
96
|
-
* @return {Promise<{requestedUrl: string,
|
|
93
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, navigationError: LH.LighthouseError | undefined, warnings: Array<LH.IcuMessage>}>}
|
|
97
94
|
*/
|
|
98
95
|
async function _navigate(navigationContext) {
|
|
99
96
|
const {driver, config, requestor} = navigationContext;
|
|
100
97
|
|
|
101
98
|
try {
|
|
102
|
-
const {requestedUrl,
|
|
99
|
+
const {requestedUrl, finalUrl, warnings} = await gotoURL(driver, requestor, {
|
|
103
100
|
...navigationContext.navigation,
|
|
104
101
|
debugNavigation: config.settings.debugNavigation,
|
|
105
102
|
maxWaitForFcp: config.settings.maxWaitForFcp,
|
|
106
103
|
maxWaitForLoad: config.settings.maxWaitForLoad,
|
|
107
104
|
waitUntil: navigationContext.navigation.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
108
105
|
});
|
|
109
|
-
return {requestedUrl,
|
|
106
|
+
return {requestedUrl, finalUrl, navigationError: undefined, warnings};
|
|
110
107
|
} catch (err) {
|
|
111
108
|
if (!(err instanceof LighthouseError)) throw err;
|
|
112
109
|
if (err.code !== 'NO_FCP' && err.code !== 'PAGE_HUNG') throw err;
|
|
113
110
|
if (typeof requestor !== 'string') throw err;
|
|
114
|
-
|
|
115
|
-
// TODO: Make the urls optional here so we don't need to throw an error with a callback requestor.
|
|
116
|
-
return {
|
|
117
|
-
requestedUrl: requestor,
|
|
118
|
-
mainDocumentUrl: requestor,
|
|
119
|
-
navigationError: err,
|
|
120
|
-
warnings: [],
|
|
121
|
-
};
|
|
111
|
+
return {requestedUrl: requestor, finalUrl: requestor, navigationError: err, warnings: []};
|
|
122
112
|
}
|
|
123
113
|
}
|
|
124
114
|
|
|
@@ -162,7 +152,7 @@ async function _collectDebugData(navigationContext, phaseState) {
|
|
|
162
152
|
* @param {PhaseState} phaseState
|
|
163
153
|
* @param {Awaited<ReturnType<typeof _setupNavigation>>} setupResult
|
|
164
154
|
* @param {Awaited<ReturnType<typeof _navigate>>} navigateResult
|
|
165
|
-
* @return {Promise<{artifacts: Partial<LH.GathererArtifacts>, warnings: Array<LH.IcuMessage>, pageLoadError: LH.LighthouseError | undefined}>}
|
|
155
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, artifacts: Partial<LH.GathererArtifacts>, warnings: Array<LH.IcuMessage>, pageLoadError: LH.LighthouseError | undefined}>}
|
|
166
156
|
*/
|
|
167
157
|
async function _computeNavigationResult(
|
|
168
158
|
navigationContext,
|
|
@@ -170,12 +160,12 @@ async function _computeNavigationResult(
|
|
|
170
160
|
setupResult,
|
|
171
161
|
navigateResult
|
|
172
162
|
) {
|
|
173
|
-
const {navigationError,
|
|
163
|
+
const {navigationError, finalUrl} = navigateResult;
|
|
174
164
|
const warnings = [...setupResult.warnings, ...navigateResult.warnings];
|
|
175
165
|
const debugData = await _collectDebugData(navigationContext, phaseState);
|
|
176
166
|
const pageLoadError = debugData.records
|
|
177
167
|
? getPageLoadError(navigationError, {
|
|
178
|
-
url:
|
|
168
|
+
url: finalUrl,
|
|
179
169
|
loadFailureMode: navigationContext.navigation.loadFailureMode,
|
|
180
170
|
networkRecords: debugData.records,
|
|
181
171
|
})
|
|
@@ -193,6 +183,8 @@ async function _computeNavigationResult(
|
|
|
193
183
|
if (debugData.trace) artifacts.traces = {[pageLoadErrorId]: debugData.trace};
|
|
194
184
|
|
|
195
185
|
return {
|
|
186
|
+
requestedUrl: navigateResult.requestedUrl,
|
|
187
|
+
finalUrl,
|
|
196
188
|
pageLoadError,
|
|
197
189
|
artifacts,
|
|
198
190
|
warnings: [...warnings, pageLoadError.friendlyMessage],
|
|
@@ -202,6 +194,8 @@ async function _computeNavigationResult(
|
|
|
202
194
|
|
|
203
195
|
const artifacts = await awaitArtifacts(phaseState.artifactState);
|
|
204
196
|
return {
|
|
197
|
+
requestedUrl: navigateResult.requestedUrl,
|
|
198
|
+
finalUrl,
|
|
205
199
|
artifacts,
|
|
206
200
|
warnings,
|
|
207
201
|
pageLoadError: undefined,
|
|
@@ -215,9 +209,8 @@ async function _computeNavigationResult(
|
|
|
215
209
|
*/
|
|
216
210
|
async function _navigation(navigationContext) {
|
|
217
211
|
const artifactState = getEmptyArtifactState();
|
|
218
|
-
const initialUrl = await navigationContext.driver.url();
|
|
219
212
|
const phaseState = {
|
|
220
|
-
url:
|
|
213
|
+
url: await navigationContext.driver.url(),
|
|
221
214
|
gatherMode: /** @type {const} */ ('navigation'),
|
|
222
215
|
driver: navigationContext.driver,
|
|
223
216
|
computedCache: navigationContext.computedCache,
|
|
@@ -231,19 +224,7 @@ async function _navigation(navigationContext) {
|
|
|
231
224
|
await collectPhaseArtifacts({phase: 'startInstrumentation', ...phaseState});
|
|
232
225
|
await collectPhaseArtifacts({phase: 'startSensitiveInstrumentation', ...phaseState});
|
|
233
226
|
const navigateResult = await _navigate(navigationContext);
|
|
234
|
-
|
|
235
|
-
// Every required url is initialized to an empty string in `getBaseArtifacts`.
|
|
236
|
-
// If we haven't set all the required urls yet, set them here.
|
|
237
|
-
if (!Object.values(phaseState.baseArtifacts).every(Boolean)) {
|
|
238
|
-
phaseState.baseArtifacts.URL = {
|
|
239
|
-
initialUrl,
|
|
240
|
-
requestedUrl: navigateResult.requestedUrl,
|
|
241
|
-
mainDocumentUrl: navigateResult.mainDocumentUrl,
|
|
242
|
-
finalUrl: navigateResult.mainDocumentUrl,
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
phaseState.url = navigateResult.mainDocumentUrl;
|
|
246
|
-
|
|
227
|
+
phaseState.url = navigateResult.finalUrl;
|
|
247
228
|
await collectPhaseArtifacts({phase: 'stopSensitiveInstrumentation', ...phaseState});
|
|
248
229
|
await collectPhaseArtifacts({phase: 'stopInstrumentation', ...phaseState});
|
|
249
230
|
await _cleanupNavigation(navigationContext);
|
|
@@ -281,6 +262,11 @@ async function _navigations({driver, config, requestor, baseArtifacts, computedC
|
|
|
281
262
|
artifacts.PageLoadError = navigationResult.pageLoadError;
|
|
282
263
|
shouldHaltNavigations = true;
|
|
283
264
|
}
|
|
265
|
+
|
|
266
|
+
artifacts.URL = {
|
|
267
|
+
requestedUrl: navigationResult.requestedUrl,
|
|
268
|
+
finalUrl: navigationResult.finalUrl,
|
|
269
|
+
};
|
|
284
270
|
}
|
|
285
271
|
|
|
286
272
|
LighthouseRunWarnings.push(...navigationResult.warnings);
|
|
@@ -302,12 +288,12 @@ async function _cleanup({requestedUrl, driver, config}) {
|
|
|
302
288
|
}
|
|
303
289
|
|
|
304
290
|
/**
|
|
305
|
-
* @param {LH.NavigationRequestor
|
|
306
|
-
* @param {{page
|
|
291
|
+
* @param {LH.NavigationRequestor} requestor
|
|
292
|
+
* @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
|
|
307
293
|
* @return {Promise<LH.Gatherer.FRGatherResult>}
|
|
308
294
|
*/
|
|
309
295
|
async function navigationGather(requestor, options) {
|
|
310
|
-
const {configContext = {}} = options;
|
|
296
|
+
const {page, configContext = {}} = options;
|
|
311
297
|
log.setLevel(configContext.logLevel || 'error');
|
|
312
298
|
|
|
313
299
|
const {config} = initializeConfig(options.config, {...configContext, gatherMode: 'navigation'});
|
|
@@ -317,29 +303,18 @@ async function navigationGather(requestor, options) {
|
|
|
317
303
|
};
|
|
318
304
|
|
|
319
305
|
// We can't trigger the navigation through user interaction if we reset the page before starting.
|
|
320
|
-
|
|
321
|
-
if (isCallback) {
|
|
306
|
+
if (typeof requestor !== 'string') {
|
|
322
307
|
internalOptions.skipAboutBlank = true;
|
|
323
308
|
}
|
|
324
309
|
|
|
325
310
|
const runnerOptions = {config, computedCache};
|
|
326
311
|
const artifacts = await Runner.gather(
|
|
327
312
|
async () => {
|
|
328
|
-
let {page} = options;
|
|
329
|
-
|
|
330
|
-
// For navigation mode, we shouldn't connect to a browser in audit mode,
|
|
331
|
-
// therefore we connect to the browser in the gatherFn callback.
|
|
332
|
-
if (!page) {
|
|
333
|
-
const {hostname = DEFAULT_HOSTNAME, port = DEFAULT_PORT} = configContext;
|
|
334
|
-
const browser = await puppeteer.connect({browserURL: `http://${hostname}:${port}`});
|
|
335
|
-
page = await browser.newPage();
|
|
336
|
-
}
|
|
337
|
-
|
|
338
313
|
const driver = new Driver(page);
|
|
339
314
|
const context = {
|
|
340
315
|
driver,
|
|
341
316
|
config,
|
|
342
|
-
requestor:
|
|
317
|
+
requestor: typeof requestor === 'string' ? URL.normalizeUrl(requestor) : requestor,
|
|
343
318
|
options: internalOptions,
|
|
344
319
|
};
|
|
345
320
|
const {baseArtifacts} = await _setup(context);
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @property {LH.Gatherer.GatherMode} gatherMode
|
|
16
16
|
* @property {Map<string, LH.ArbitraryEqualityMap>} computedCache
|
|
17
17
|
* @property {LH.Config.Settings} settings
|
|
18
|
+
* @property {string} url
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
/** @typedef {Record<string, Promise<any>>} IntermediateArtifacts */
|
|
@@ -74,6 +75,7 @@ async function collectPhaseArtifacts(options) {
|
|
|
74
75
|
gatherMode,
|
|
75
76
|
computedCache,
|
|
76
77
|
settings,
|
|
78
|
+
url,
|
|
77
79
|
} = options;
|
|
78
80
|
const priorPhase = phaseToPriorPhase[phase];
|
|
79
81
|
const priorPhaseArtifacts = (priorPhase && artifactState[priorPhase]) || {};
|
|
@@ -90,6 +92,7 @@ async function collectPhaseArtifacts(options) {
|
|
|
90
92
|
: /** @type {Dependencies} */ ({});
|
|
91
93
|
|
|
92
94
|
return gatherer[phase]({
|
|
95
|
+
url,
|
|
93
96
|
gatherMode,
|
|
94
97
|
driver,
|
|
95
98
|
baseArtifacts,
|
|
@@ -14,7 +14,7 @@ const DEFAULT_PROTOCOL_TIMEOUT = 30000;
|
|
|
14
14
|
/** @implements {LH.Gatherer.FRProtocolSession} */
|
|
15
15
|
class ProtocolSession {
|
|
16
16
|
/**
|
|
17
|
-
* @param {
|
|
17
|
+
* @param {import('puppeteer').CDPSession} session
|
|
18
18
|
*/
|
|
19
19
|
constructor(session) {
|
|
20
20
|
this._session = session;
|
|
@@ -93,7 +93,7 @@ class ProtocolSession {
|
|
|
93
93
|
* @param {(session: ProtocolSession) => void} callback
|
|
94
94
|
*/
|
|
95
95
|
addSessionAttachedListener(callback) {
|
|
96
|
-
/** @param {
|
|
96
|
+
/** @param {import('puppeteer').CDPSession} session */
|
|
97
97
|
const listener = session => callback(new ProtocolSession(session));
|
|
98
98
|
this._callbackMap.set(callback, listener);
|
|
99
99
|
this._getConnection().on('sessionattached', listener);
|
|
@@ -17,7 +17,7 @@ const {initializeConfig} = require('../config/config.js');
|
|
|
17
17
|
const {getBaseArtifacts, finalizeArtifacts} = require('./base-artifacts.js');
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @param {{page:
|
|
20
|
+
* @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
|
|
21
21
|
* @return {Promise<LH.Gatherer.FRGatherResult>}
|
|
22
22
|
*/
|
|
23
23
|
async function snapshotGather(options) {
|
|
@@ -36,14 +36,13 @@ async function snapshotGather(options) {
|
|
|
36
36
|
const artifacts = await Runner.gather(
|
|
37
37
|
async () => {
|
|
38
38
|
const baseArtifacts = await getBaseArtifacts(config, driver, {gatherMode: 'snapshot'});
|
|
39
|
-
baseArtifacts.URL =
|
|
40
|
-
|
|
41
|
-
finalUrl: url,
|
|
42
|
-
};
|
|
39
|
+
baseArtifacts.URL.requestedUrl = url;
|
|
40
|
+
baseArtifacts.URL.finalUrl = url;
|
|
43
41
|
|
|
44
42
|
const artifactDefinitions = config.artifacts || [];
|
|
45
43
|
const artifactState = getEmptyArtifactState();
|
|
46
44
|
await collectPhaseArtifacts({
|
|
45
|
+
url,
|
|
47
46
|
phase: 'getArtifact',
|
|
48
47
|
gatherMode: 'snapshot',
|
|
49
48
|
driver,
|
|
@@ -18,7 +18,7 @@ const {initializeConfig} = require('../config/config.js');
|
|
|
18
18
|
const {getBaseArtifacts, finalizeArtifacts} = require('./base-artifacts.js');
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* @param {{page:
|
|
21
|
+
* @param {{page: import('puppeteer').Page, config?: LH.Config.Json, configContext?: LH.Config.FRContext}} options
|
|
22
22
|
* @return {Promise<{endTimespanGather(): Promise<LH.Gatherer.FRGatherResult>}>}
|
|
23
23
|
*/
|
|
24
24
|
async function startTimespanGather(options) {
|
|
@@ -32,11 +32,12 @@ async function startTimespanGather(options) {
|
|
|
32
32
|
/** @type {Map<string, LH.ArbitraryEqualityMap>} */
|
|
33
33
|
const computedCache = new Map();
|
|
34
34
|
const artifactDefinitions = config.artifacts || [];
|
|
35
|
-
const
|
|
35
|
+
const requestedUrl = await driver.url();
|
|
36
36
|
const baseArtifacts = await getBaseArtifacts(config, driver, {gatherMode: 'timespan'});
|
|
37
37
|
const artifactState = getEmptyArtifactState();
|
|
38
38
|
/** @type {Omit<import('./runner-helpers.js').CollectPhaseArtifactOptions, 'phase'>} */
|
|
39
39
|
const phaseOptions = {
|
|
40
|
+
url: requestedUrl,
|
|
40
41
|
driver,
|
|
41
42
|
artifactDefinitions,
|
|
42
43
|
artifactState,
|
|
@@ -53,14 +54,13 @@ async function startTimespanGather(options) {
|
|
|
53
54
|
return {
|
|
54
55
|
async endTimespanGather() {
|
|
55
56
|
const finalUrl = await driver.url();
|
|
57
|
+
phaseOptions.url = finalUrl;
|
|
56
58
|
|
|
57
59
|
const runnerOptions = {config, computedCache};
|
|
58
60
|
const artifacts = await Runner.gather(
|
|
59
61
|
async () => {
|
|
60
|
-
baseArtifacts.URL =
|
|
61
|
-
|
|
62
|
-
finalUrl,
|
|
63
|
-
};
|
|
62
|
+
baseArtifacts.URL.requestedUrl = requestedUrl;
|
|
63
|
+
baseArtifacts.URL.finalUrl = finalUrl;
|
|
64
64
|
|
|
65
65
|
await collectPhaseArtifacts({phase: 'stopSensitiveInstrumentation', ...phaseOptions});
|
|
66
66
|
await collectPhaseArtifacts({phase: 'stopInstrumentation', ...phaseOptions});
|
|
@@ -97,8 +97,7 @@ class ExecutionContext {
|
|
|
97
97
|
.catch(${pageFunctions.wrapRuntimeEvalErrorInBrowserString})
|
|
98
98
|
.then(resolve);
|
|
99
99
|
});
|
|
100
|
-
}())
|
|
101
|
-
//# sourceURL=_lighthouse-eval.js`,
|
|
100
|
+
}())`,
|
|
102
101
|
includeCommandLineAPI: true,
|
|
103
102
|
awaitPromise: true,
|
|
104
103
|
returnByValue: true,
|
|
@@ -196,8 +195,7 @@ class ExecutionContext {
|
|
|
196
195
|
${ExecutionContext._cachedNativesPreamble};
|
|
197
196
|
${depsSerialized};
|
|
198
197
|
(${mainFn})(${argsSerialized});
|
|
199
|
-
})()
|
|
200
|
-
//# sourceURL=_lighthouse-eval.js`;
|
|
198
|
+
})()`;
|
|
201
199
|
|
|
202
200
|
await this._session.sendCommand('Page.addScriptToEvaluateOnNewDocument', {source: expression});
|
|
203
201
|
}
|
|
@@ -80,7 +80,7 @@ function resolveWaitForFullyLoadedOptions(options) {
|
|
|
80
80
|
* @param {LH.Gatherer.FRTransitionalDriver} driver
|
|
81
81
|
* @param {LH.NavigationRequestor} requestor
|
|
82
82
|
* @param {NavigationOptions} options
|
|
83
|
-
* @return {Promise<{requestedUrl: string,
|
|
83
|
+
* @return {Promise<{requestedUrl: string, finalUrl: string, warnings: Array<LH.IcuMessage>}>}
|
|
84
84
|
*/
|
|
85
85
|
async function gotoURL(driver, requestor, options) {
|
|
86
86
|
const status = typeof requestor === 'string' ?
|
|
@@ -130,14 +130,14 @@ async function gotoURL(driver, requestor, options) {
|
|
|
130
130
|
|
|
131
131
|
let requestedUrl = navigationUrls.requestedUrl;
|
|
132
132
|
if (typeof requestor === 'string') {
|
|
133
|
-
if (
|
|
133
|
+
if (requestor !== requestedUrl) {
|
|
134
134
|
log.error('Navigation', 'Provided URL did not match initial navigation URL');
|
|
135
135
|
}
|
|
136
136
|
requestedUrl = requestor;
|
|
137
137
|
}
|
|
138
138
|
if (!requestedUrl) throw Error('No navigations detected when running user defined requestor.');
|
|
139
139
|
|
|
140
|
-
const
|
|
140
|
+
const finalUrl = navigationUrls.finalUrl || requestedUrl;
|
|
141
141
|
|
|
142
142
|
// Bring `Page.navigate` errors back into the promise chain. See https://github.com/GoogleChrome/lighthouse/pull/6739.
|
|
143
143
|
await waitForNavigationTriggered;
|
|
@@ -150,26 +150,26 @@ async function gotoURL(driver, requestor, options) {
|
|
|
150
150
|
log.timeEnd(status);
|
|
151
151
|
return {
|
|
152
152
|
requestedUrl,
|
|
153
|
-
|
|
154
|
-
warnings: getNavigationWarnings({timedOut,
|
|
153
|
+
finalUrl,
|
|
154
|
+
warnings: getNavigationWarnings({timedOut, finalUrl, requestedUrl}),
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
|
-
* @param {{timedOut: boolean, requestedUrl: string,
|
|
159
|
+
* @param {{timedOut: boolean, requestedUrl: string, finalUrl: string; }} navigation
|
|
160
160
|
* @return {Array<LH.IcuMessage>}
|
|
161
161
|
*/
|
|
162
162
|
function getNavigationWarnings(navigation) {
|
|
163
|
-
const {requestedUrl,
|
|
163
|
+
const {requestedUrl, finalUrl} = navigation;
|
|
164
164
|
/** @type {Array<LH.IcuMessage>} */
|
|
165
165
|
const warnings = [];
|
|
166
166
|
|
|
167
167
|
if (navigation.timedOut) warnings.push(str_(UIStrings.warningTimeout));
|
|
168
168
|
|
|
169
|
-
if (!URL.equalWithExcludedFragments(requestedUrl,
|
|
169
|
+
if (!URL.equalWithExcludedFragments(requestedUrl, finalUrl)) {
|
|
170
170
|
warnings.push(str_(UIStrings.warningRedirected, {
|
|
171
171
|
requested: requestedUrl,
|
|
172
|
-
final:
|
|
172
|
+
final: finalUrl,
|
|
173
173
|
}));
|
|
174
174
|
}
|
|
175
175
|
|
|
@@ -133,7 +133,7 @@ class NetworkMonitor {
|
|
|
133
133
|
this._sessions = new Map();
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
/** @return {Promise<{requestedUrl?: string,
|
|
136
|
+
/** @return {Promise<{requestedUrl?: string, finalUrl?: string}>} */
|
|
137
137
|
async getNavigationUrls() {
|
|
138
138
|
const frameNavigations = this._frameNavigations;
|
|
139
139
|
if (!frameNavigations.length) return {};
|
|
@@ -143,22 +143,9 @@ class NetworkMonitor {
|
|
|
143
143
|
const mainFrameNavigations = frameNavigations.filter(frame => frame.id === mainFrameId);
|
|
144
144
|
if (!mainFrameNavigations.length) log.warn('NetworkMonitor', 'No detected navigations');
|
|
145
145
|
|
|
146
|
-
// The requested URL is the initiator request for the first frame navigation.
|
|
147
|
-
/** @type {string|undefined} */
|
|
148
|
-
let requestedUrl = mainFrameNavigations[0]?.url;
|
|
149
|
-
if (this._networkRecorder) {
|
|
150
|
-
const records = this._networkRecorder.getRawRecords();
|
|
151
|
-
|
|
152
|
-
let initialUrlRequest = records.find(record => record.url === requestedUrl);
|
|
153
|
-
while (initialUrlRequest?.redirectSource) {
|
|
154
|
-
initialUrlRequest = initialUrlRequest.redirectSource;
|
|
155
|
-
requestedUrl = initialUrlRequest.url;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
146
|
return {
|
|
160
|
-
requestedUrl,
|
|
161
|
-
|
|
147
|
+
requestedUrl: mainFrameNavigations[0]?.url,
|
|
148
|
+
finalUrl: mainFrameNavigations[mainFrameNavigations.length - 1]?.url,
|
|
162
149
|
};
|
|
163
150
|
}
|
|
164
151
|
|
|
@@ -64,7 +64,7 @@ class Driver {
|
|
|
64
64
|
defaultSession = this;
|
|
65
65
|
|
|
66
66
|
// eslint-disable-next-line no-invalid-this
|
|
67
|
-
fetcher = new Fetcher(this.defaultSession);
|
|
67
|
+
fetcher = new Fetcher(this.defaultSession, this.executionContext);
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* @param {Connection} connection
|
|
@@ -470,11 +470,6 @@ class Driver {
|
|
|
470
470
|
this._devtoolsLog.endRecording();
|
|
471
471
|
return this._devtoolsLog.messages;
|
|
472
472
|
}
|
|
473
|
-
|
|
474
|
-
async url() {
|
|
475
|
-
const {frameTree} = await this.sendCommand('Page.getFrameTree');
|
|
476
|
-
return `${frameTree.frame.url}${frameTree.frame.urlFragment || ''}`;
|
|
477
|
-
}
|
|
478
473
|
}
|
|
479
474
|
|
|
480
475
|
module.exports = Driver;
|