lighthouse 10.4.0 → 11.0.0
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/CONTRIBUTING.md +1 -1
- package/cli/cli-flags.d.ts +1 -6
- package/cli/cli-flags.js +0 -5
- package/cli/run.js +3 -10
- package/cli/sentry-prompt.js +4 -2
- package/cli/test/smokehouse/core-tests.js +0 -2
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +24 -14
- package/cli/test/smokehouse/lighthouse-runners/bundle.d.ts +1 -2
- package/cli/test/smokehouse/lighthouse-runners/bundle.js +12 -21
- package/cli/test/smokehouse/lighthouse-runners/cli.d.ts +1 -3
- package/cli/test/smokehouse/lighthouse-runners/cli.js +3 -7
- package/cli/test/smokehouse/lighthouse-runners/devtools.d.ts +1 -5
- package/cli/test/smokehouse/lighthouse-runners/devtools.js +1 -12
- package/cli/test/smokehouse/readme.md +0 -2
- package/cli/test/smokehouse/report-assert.d.ts +1 -3
- package/cli/test/smokehouse/report-assert.js +2 -19
- package/cli/test/smokehouse/smokehouse.js +3 -32
- package/core/audits/accessibility/aria-allowed-role.d.ts +10 -0
- package/core/audits/accessibility/aria-allowed-role.js +46 -0
- package/core/audits/accessibility/image-redundant-alt.d.ts +10 -0
- package/core/audits/accessibility/image-redundant-alt.js +45 -0
- package/core/audits/accessibility/label-content-name-mismatch.d.ts +10 -0
- package/core/audits/accessibility/label-content-name-mismatch.js +44 -0
- package/core/audits/accessibility/skip-link.d.ts +10 -0
- package/core/audits/accessibility/skip-link.js +43 -0
- package/core/audits/accessibility/table-duplicate-name.d.ts +10 -0
- package/core/audits/accessibility/table-duplicate-name.js +44 -0
- package/core/audits/accessibility/target-size.js +1 -1
- package/core/audits/byte-efficiency/duplicated-javascript.js +2 -2
- package/core/audits/byte-efficiency/render-blocking-resources.js +1 -0
- package/core/audits/dobetterweb/uses-http2.d.ts +18 -1
- package/core/audits/dobetterweb/uses-http2.js +62 -16
- package/core/audits/installable-manifest.d.ts +1 -5
- package/core/audits/installable-manifest.js +2 -7
- package/core/audits/largest-contentful-paint-element.d.ts +0 -6
- package/core/audits/largest-contentful-paint-element.js +13 -15
- package/core/audits/metrics/{experimental-interaction-to-next-paint.d.ts → interaction-to-next-paint.d.ts} +3 -3
- package/core/audits/metrics/{experimental-interaction-to-next-paint.js → interaction-to-next-paint.js} +3 -3
- package/core/audits/uses-rel-preconnect.js +23 -8
- package/core/audits/work-during-interaction.js +2 -2
- package/core/computed/processed-navigation.d.ts +1 -1
- package/core/config/config-helpers.d.ts +3 -3
- package/core/config/config-helpers.js +5 -12
- package/core/config/config.js +1 -7
- package/core/config/constants.d.ts +0 -2
- package/core/config/constants.js +2 -18
- package/core/config/default-config.js +59 -53
- package/core/config/filters.js +1 -1
- package/core/config/validation.d.ts +7 -12
- package/core/config/validation.js +16 -26
- package/core/gather/base-artifacts.d.ts +4 -4
- package/core/gather/base-artifacts.js +2 -6
- package/core/gather/base-gatherer.d.ts +12 -37
- package/core/gather/base-gatherer.js +7 -54
- package/core/gather/driver/dom.d.ts +4 -4
- package/core/gather/driver/dom.js +2 -2
- package/core/gather/driver/environment.d.ts +4 -4
- package/core/gather/driver/environment.js +2 -2
- package/core/gather/driver/execution-context.d.ts +12 -3
- package/core/gather/driver/execution-context.js +34 -3
- package/core/gather/driver/navigation.d.ts +2 -2
- package/core/gather/driver/navigation.js +2 -5
- package/core/gather/driver/network-monitor.d.ts +7 -6
- package/core/gather/driver/network-monitor.js +4 -4
- package/core/gather/driver/network.d.ts +2 -2
- package/core/gather/driver/network.js +1 -1
- package/core/gather/driver/prepare.d.ts +10 -10
- package/core/gather/driver/prepare.js +10 -10
- package/core/gather/driver/service-workers.d.ts +4 -4
- package/core/gather/driver/service-workers.js +2 -2
- package/core/gather/driver/storage.d.ts +6 -6
- package/core/gather/driver/storage.js +3 -3
- package/core/gather/driver/target-manager.d.ts +6 -5
- package/core/gather/driver/target-manager.js +3 -3
- package/core/gather/driver/wait-for-condition.d.ts +14 -14
- package/core/gather/driver/wait-for-condition.js +8 -8
- package/core/gather/driver.d.ts +9 -6
- package/core/gather/driver.js +14 -4
- package/core/gather/fetcher.d.ts +3 -3
- package/core/gather/fetcher.js +1 -1
- package/core/gather/gatherers/accessibility.d.ts +4 -4
- package/core/gather/gatherers/accessibility.js +8 -3
- package/core/gather/gatherers/anchor-elements.d.ts +4 -4
- package/core/gather/gatherers/anchor-elements.js +4 -4
- package/core/gather/gatherers/bf-cache-failures.d.ts +8 -14
- package/core/gather/gatherers/bf-cache-failures.js +5 -14
- package/core/gather/gatherers/cache-contents.d.ts +4 -4
- package/core/gather/gatherers/cache-contents.js +3 -3
- package/core/gather/gatherers/console-messages.d.ts +6 -6
- package/core/gather/gatherers/console-messages.js +4 -4
- package/core/gather/gatherers/css-usage.d.ts +14 -14
- package/core/gather/gatherers/css-usage.js +9 -9
- package/core/gather/gatherers/devtools-log-compat.d.ts +5 -5
- package/core/gather/gatherers/devtools-log-compat.js +4 -4
- package/core/gather/gatherers/devtools-log.d.ts +6 -6
- package/core/gather/gatherers/devtools-log.js +4 -4
- package/core/gather/gatherers/dobetterweb/doctype.d.ts +4 -4
- package/core/gather/gatherers/dobetterweb/doctype.js +3 -3
- package/core/gather/gatherers/dobetterweb/domstats.d.ts +4 -4
- package/core/gather/gatherers/dobetterweb/domstats.js +3 -3
- package/core/gather/gatherers/dobetterweb/optimized-images.d.ts +10 -22
- package/core/gather/gatherers/dobetterweb/optimized-images.js +10 -27
- package/core/gather/gatherers/dobetterweb/response-compression.d.ts +6 -12
- package/core/gather/gatherers/dobetterweb/response-compression.js +14 -21
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.d.ts +8 -14
- package/core/gather/gatherers/dobetterweb/tags-blocking-first-paint.js +5 -14
- package/core/gather/gatherers/full-page-screenshot.d.ts +10 -10
- package/core/gather/gatherers/full-page-screenshot.js +7 -10
- package/core/gather/gatherers/global-listeners.d.ts +4 -4
- package/core/gather/gatherers/global-listeners.js +3 -3
- package/core/gather/gatherers/iframe-elements.d.ts +4 -4
- package/core/gather/gatherers/iframe-elements.js +3 -3
- package/core/gather/gatherers/image-elements.d.ts +10 -10
- package/core/gather/gatherers/image-elements.js +6 -6
- package/core/gather/gatherers/inputs.d.ts +4 -4
- package/core/gather/gatherers/inputs.js +3 -3
- package/core/gather/gatherers/inspector-issues.d.ts +8 -19
- package/core/gather/gatherers/inspector-issues.js +9 -26
- package/core/gather/gatherers/installability-errors.d.ts +6 -6
- package/core/gather/gatherers/installability-errors.js +4 -4
- package/core/gather/gatherers/js-usage.d.ts +6 -6
- package/core/gather/gatherers/js-usage.js +4 -4
- package/core/gather/gatherers/link-elements.d.ts +8 -20
- package/core/gather/gatherers/link-elements.js +7 -24
- package/core/gather/gatherers/main-document-content.d.ts +4 -16
- package/core/gather/gatherers/main-document-content.js +5 -23
- package/core/gather/gatherers/meta-elements.d.ts +4 -4
- package/core/gather/gatherers/meta-elements.js +3 -3
- package/core/gather/gatherers/network-user-agent.d.ts +5 -5
- package/core/gather/gatherers/network-user-agent.js +4 -4
- package/core/gather/gatherers/script-elements.d.ts +6 -11
- package/core/gather/gatherers/script-elements.js +4 -13
- package/core/gather/gatherers/scripts.d.ts +7 -6
- package/core/gather/gatherers/scripts.js +7 -9
- package/core/gather/gatherers/seo/embedded-content.d.ts +4 -4
- package/core/gather/gatherers/seo/embedded-content.js +3 -3
- package/core/gather/gatherers/seo/font-size.d.ts +6 -6
- package/core/gather/gatherers/seo/font-size.js +5 -5
- package/core/gather/gatherers/seo/robots-txt.d.ts +4 -4
- package/core/gather/gatherers/seo/robots-txt.js +3 -3
- package/core/gather/gatherers/seo/tap-targets.d.ts +8 -8
- package/core/gather/gatherers/seo/tap-targets.js +5 -5
- package/core/gather/gatherers/service-worker.d.ts +4 -10
- package/core/gather/gatherers/service-worker.js +3 -15
- package/core/gather/gatherers/source-maps.d.ts +11 -23
- package/core/gather/gatherers/source-maps.js +22 -53
- package/core/gather/gatherers/stacks.d.ts +7 -7
- package/core/gather/gatherers/stacks.js +6 -6
- package/core/gather/gatherers/trace-compat.d.ts +5 -5
- package/core/gather/gatherers/trace-compat.js +4 -4
- package/core/gather/gatherers/trace-elements.d.ts +13 -25
- package/core/gather/gatherers/trace-elements.js +19 -32
- package/core/gather/gatherers/trace.d.ts +8 -8
- package/core/gather/gatherers/trace.js +5 -5
- package/core/gather/gatherers/viewport-dimensions.d.ts +4 -4
- package/core/gather/gatherers/viewport-dimensions.js +3 -3
- package/core/gather/gatherers/web-app-manifest.d.ts +8 -8
- package/core/gather/gatherers/web-app-manifest.js +5 -5
- package/core/gather/navigation-runner.d.ts +9 -9
- package/core/gather/navigation-runner.js +14 -8
- package/core/gather/runner-helpers.d.ts +3 -3
- package/core/gather/runner-helpers.js +12 -4
- package/core/gather/session.d.ts +2 -2
- package/core/gather/session.js +1 -1
- package/core/gather/snapshot-runner.d.ts +2 -2
- package/core/gather/snapshot-runner.js +1 -1
- package/core/gather/timespan-runner.d.ts +2 -2
- package/core/gather/timespan-runner.js +1 -1
- package/core/index.cjs +0 -7
- package/core/index.d.ts +0 -15
- package/core/index.js +2 -40
- package/core/lib/asset-saver.js +14 -4
- package/core/lib/axe.js +1 -1
- package/core/lib/dependency-graph/simulator/network-analyzer.d.ts +28 -12
- package/core/lib/dependency-graph/simulator/network-analyzer.js +128 -100
- package/core/lib/emulation.d.ts +14 -14
- package/core/lib/emulation.js +7 -7
- package/core/lib/navigation-error.js +5 -0
- package/core/lib/network-recorder.d.ts +2 -1
- package/core/lib/network-recorder.js +1 -0
- package/core/lib/network-request.js +12 -3
- package/core/lib/page-functions.d.ts +10 -2
- package/core/lib/page-functions.js +85 -8
- package/core/lib/sentry.js +9 -2
- package/core/lib/stack-packs.js +4 -0
- package/core/runner.d.ts +8 -30
- package/core/runner.js +8 -39
- package/core/user-flow.d.ts +4 -4
- package/core/user-flow.js +2 -2
- package/dist/report/bundle.esm.js +2221 -5832
- package/dist/report/flow.js +2631 -235
- package/dist/report/standalone.js +2586 -234
- package/flow-report/src/i18n/i18n.d.ts +2 -2
- package/package.json +17 -24
- package/readme.md +3 -1
- package/report/assets/templates.html +3 -1
- package/report/renderer/category-renderer.d.ts +3 -2
- package/report/renderer/category-renderer.js +8 -4
- package/report/renderer/components.js +11 -5
- package/report/renderer/pwa-category-renderer.js +1 -1
- package/report/renderer/report-ui-features.js +9 -6
- package/report/renderer/report-utils.d.ts +1 -1
- package/report/renderer/report-utils.js +2 -2
- package/report/renderer/topbar-features.js +3 -0
- package/shared/localization/locales/ar-XB.json +185 -44
- package/shared/localization/locales/ar.json +185 -44
- package/shared/localization/locales/bg.json +185 -44
- package/shared/localization/locales/ca.json +190 -49
- package/shared/localization/locales/cs.json +185 -44
- package/shared/localization/locales/da.json +185 -44
- package/shared/localization/locales/de.json +185 -44
- package/shared/localization/locales/el.json +185 -44
- package/shared/localization/locales/en-GB.json +185 -44
- package/shared/localization/locales/en-US.json +99 -45
- package/shared/localization/locales/en-XA.json +185 -44
- package/shared/localization/locales/en-XL.json +99 -45
- package/shared/localization/locales/es-419.json +185 -44
- package/shared/localization/locales/es.json +185 -44
- package/shared/localization/locales/fi.json +185 -44
- package/shared/localization/locales/fil.json +185 -44
- package/shared/localization/locales/fr.json +185 -44
- package/shared/localization/locales/he.json +186 -45
- package/shared/localization/locales/hi.json +185 -44
- package/shared/localization/locales/hr.json +185 -44
- package/shared/localization/locales/hu.json +185 -44
- package/shared/localization/locales/id.json +185 -44
- package/shared/localization/locales/it.json +185 -44
- package/shared/localization/locales/ja.json +185 -44
- package/shared/localization/locales/ko.json +185 -44
- package/shared/localization/locales/lt.json +185 -44
- package/shared/localization/locales/lv.json +185 -44
- package/shared/localization/locales/nl.json +185 -44
- package/shared/localization/locales/no.json +185 -44
- package/shared/localization/locales/pl.json +185 -44
- package/shared/localization/locales/pt-PT.json +185 -44
- package/shared/localization/locales/pt.json +190 -49
- package/shared/localization/locales/ro.json +185 -44
- package/shared/localization/locales/ru.json +185 -44
- package/shared/localization/locales/sk.json +185 -44
- package/shared/localization/locales/sl.json +185 -44
- package/shared/localization/locales/sr-Latn.json +185 -44
- package/shared/localization/locales/sr.json +185 -44
- package/shared/localization/locales/sv.json +185 -44
- package/shared/localization/locales/ta.json +185 -44
- package/shared/localization/locales/te.json +185 -44
- package/shared/localization/locales/th.json +185 -44
- package/shared/localization/locales/tr.json +185 -44
- package/shared/localization/locales/uk.json +185 -44
- package/shared/localization/locales/vi.json +185 -44
- package/shared/localization/locales/zh-HK.json +185 -44
- package/shared/localization/locales/zh-TW.json +185 -44
- package/shared/localization/locales/zh.json +185 -44
- package/third-party/esbuild-plugins-polyfills/LICENSE +3 -0
- package/third-party/esbuild-plugins-polyfills/README.md +7 -0
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.d.ts +9 -0
- package/third-party/esbuild-plugins-polyfills/esbuild-polyfills.js +129 -0
- package/tsconfig.json +2 -1
- package/types/artifacts.d.ts +16 -45
- package/types/config.d.ts +10 -52
- package/types/externs.d.ts +0 -2
- package/types/gatherer.d.ts +24 -47
- package/types/internal/rxjs.d.ts +26 -0
- package/types/internal/smokehouse.d.ts +1 -3
- package/types/lh.d.ts +0 -2
- package/types/lhr/settings.d.ts +1 -1
- package/core/audits/metrics/first-contentful-paint-3g.d.ts +0 -15
- package/core/audits/metrics/first-contentful-paint-3g.js +0 -69
- package/core/audits/resource-summary.d.ts +0 -16
- package/core/audits/resource-summary.js +0 -104
- package/core/audits/service-worker.d.ts +0 -46
- package/core/audits/service-worker.js +0 -182
- package/core/gather/gatherers/gatherer.d.ts +0 -46
- package/core/gather/gatherers/gatherer.js +0 -58
- package/core/legacy/config/config.d.ts +0 -107
- package/core/legacy/config/config.js +0 -566
- package/core/legacy/config/legacy-default-config.d.ts +0 -4
- package/core/legacy/config/legacy-default-config.js +0 -87
- package/core/legacy/gather/connections/connection.d.ts +0 -77
- package/core/legacy/gather/connections/connection.js +0 -196
- package/core/legacy/gather/connections/cri.d.ts +0 -27
- package/core/legacy/gather/connections/cri.js +0 -162
- package/core/legacy/gather/connections/raw.d.ts +0 -20
- package/core/legacy/gather/connections/raw.js +0 -57
- package/core/legacy/gather/driver.d.ts +0 -216
- package/core/legacy/gather/driver.js +0 -480
- package/core/legacy/gather/gather-runner.d.ts +0 -166
- package/core/legacy/gather/gather-runner.js +0 -590
- package/types/internal/lighthouse-logger.d.ts +0 -34
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
export type CrdpEventEmitter = LH.Protocol.StrictEventEmitter<LH.CrdpEvents>;
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {LH.Protocol.StrictEventEmitter<LH.CrdpEvents>} CrdpEventEmitter
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* @implements {LH.Gatherer.FRTransitionalDriver}
|
|
7
|
-
*/
|
|
8
|
-
export class Driver implements LH.Gatherer.FRTransitionalDriver {
|
|
9
|
-
/** @deprecated - Not available on Fraggle Rock driver. */
|
|
10
|
-
static get traceCategories(): string[];
|
|
11
|
-
/**
|
|
12
|
-
* @param {import('./connections/connection.js').Connection} connection
|
|
13
|
-
*/
|
|
14
|
-
constructor(connection: import('./connections/connection.js').Connection);
|
|
15
|
-
/**
|
|
16
|
-
* @pri_vate (This should be private, but that makes our tests harder).
|
|
17
|
-
* An event emitter that enforces mapping between Crdp event names and payload types.
|
|
18
|
-
*/
|
|
19
|
-
_eventEmitter: CrdpEventEmitter;
|
|
20
|
-
/**
|
|
21
|
-
* @private
|
|
22
|
-
* Used to save network and lifecycle protocol traffic. Just Page and Network are needed.
|
|
23
|
-
*/
|
|
24
|
-
private _devtoolsLog;
|
|
25
|
-
/**
|
|
26
|
-
* @private
|
|
27
|
-
* @type {Map<string, number>}
|
|
28
|
-
*/
|
|
29
|
-
private _domainEnabledCounts;
|
|
30
|
-
/**
|
|
31
|
-
* @type {number}
|
|
32
|
-
* @private
|
|
33
|
-
*/
|
|
34
|
-
private _nextProtocolTimeout;
|
|
35
|
-
online: boolean;
|
|
36
|
-
executionContext: ExecutionContext;
|
|
37
|
-
defaultSession: Driver;
|
|
38
|
-
fetcher: Fetcher;
|
|
39
|
-
_connection: import("./connections/connection.js").Connection;
|
|
40
|
-
/** @private @deprecated Only available for plugin backcompat. */
|
|
41
|
-
private evaluate;
|
|
42
|
-
/** @private @deprecated Only available for plugin backcompat. */
|
|
43
|
-
private evaluateAsync;
|
|
44
|
-
targetManager: {
|
|
45
|
-
rootSession: () => Driver;
|
|
46
|
-
mainFrameExecutionContexts: () => LH.Crdp.Runtime.ExecutionContextDescription[];
|
|
47
|
-
/**
|
|
48
|
-
* Bind to *any* protocol event.
|
|
49
|
-
* @param {'protocolevent'} event
|
|
50
|
-
* @param {(payload: LH.Protocol.RawEventMessage) => void} callback
|
|
51
|
-
*/
|
|
52
|
-
on: (event: 'protocolevent', callback: (payload: LH.Protocol.RawEventMessage) => void) => void;
|
|
53
|
-
/**
|
|
54
|
-
* Unbind to *any* protocol event.
|
|
55
|
-
* @param {'protocolevent'} event
|
|
56
|
-
* @param {(payload: LH.Protocol.RawEventMessage) => void} callback
|
|
57
|
-
*/
|
|
58
|
-
off: (event: 'protocolevent', callback: (payload: LH.Protocol.RawEventMessage) => void) => void;
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* @return {Promise<LH.Crdp.Browser.GetVersionResponse & {milestone: number}>}
|
|
62
|
-
*/
|
|
63
|
-
getBrowserVersion(): Promise<LH.Crdp.Browser.GetVersionResponse & {
|
|
64
|
-
milestone: number;
|
|
65
|
-
}>;
|
|
66
|
-
/**
|
|
67
|
-
* @return {Promise<void>}
|
|
68
|
-
*/
|
|
69
|
-
connect(): Promise<void>;
|
|
70
|
-
/**
|
|
71
|
-
* @return {Promise<void>}
|
|
72
|
-
*/
|
|
73
|
-
disconnect(): Promise<void>;
|
|
74
|
-
/** @return {Promise<void>} */
|
|
75
|
-
dispose(): Promise<void>;
|
|
76
|
-
/**
|
|
77
|
-
* Get the browser WebSocket endpoint for devtools protocol clients like Puppeteer.
|
|
78
|
-
* Only works with WebSocket connection, not extension or devtools.
|
|
79
|
-
* @return {Promise<string>}
|
|
80
|
-
*/
|
|
81
|
-
wsEndpoint(): Promise<string>;
|
|
82
|
-
/**
|
|
83
|
-
* Bind listeners for protocol events.
|
|
84
|
-
* @template {keyof LH.CrdpEvents} E
|
|
85
|
-
* @param {E} eventName
|
|
86
|
-
* @param {(...args: LH.CrdpEvents[E]) => void} cb
|
|
87
|
-
*/
|
|
88
|
-
on<E extends keyof LH.CrdpEvents>(eventName: E, cb: (...args: LH.CrdpEvents[E]) => void): void;
|
|
89
|
-
/**
|
|
90
|
-
* Bind a one-time listener for protocol events. Listener is removed once it
|
|
91
|
-
* has been called.
|
|
92
|
-
* @template {keyof LH.CrdpEvents} E
|
|
93
|
-
* @param {E} eventName
|
|
94
|
-
* @param {(...args: LH.CrdpEvents[E]) => void} cb
|
|
95
|
-
*/
|
|
96
|
-
once<E_1 extends keyof LH.CrdpEvents>(eventName: E_1, cb: (...args: LH.CrdpEvents[E_1]) => void): void;
|
|
97
|
-
/**
|
|
98
|
-
* Unbind event listener.
|
|
99
|
-
* @template {keyof LH.CrdpEvents} E
|
|
100
|
-
* @param {E} eventName
|
|
101
|
-
* @param {Function} cb
|
|
102
|
-
*/
|
|
103
|
-
off<E_2 extends keyof LH.CrdpEvents>(eventName: E_2, cb: Function): void;
|
|
104
|
-
/** @param {LH.Crdp.Target.TargetInfo} targetInfo */
|
|
105
|
-
setTargetInfo(targetInfo: LH.Crdp.Target.TargetInfo): void;
|
|
106
|
-
/**
|
|
107
|
-
* Debounce enabling or disabling domains to prevent driver users from
|
|
108
|
-
* stomping on each other. Maintains an internal count of the times a domain
|
|
109
|
-
* has been enabled. Returns false if the command would have no effect (domain
|
|
110
|
-
* is already enabled or disabled), or if command would interfere with another
|
|
111
|
-
* user of that domain (e.g. two gatherers have enabled a domain, both need to
|
|
112
|
-
* disable it for it to be disabled). Returns true otherwise.
|
|
113
|
-
* @param {string} domain
|
|
114
|
-
* @param {string|undefined} sessionId
|
|
115
|
-
* @param {boolean} enable
|
|
116
|
-
* @return {boolean}
|
|
117
|
-
* @private
|
|
118
|
-
*/
|
|
119
|
-
private _shouldToggleDomain;
|
|
120
|
-
/**
|
|
121
|
-
* @return {boolean}
|
|
122
|
-
*/
|
|
123
|
-
hasNextProtocolTimeout(): boolean;
|
|
124
|
-
/**
|
|
125
|
-
* @return {number}
|
|
126
|
-
*/
|
|
127
|
-
getNextProtocolTimeout(): number;
|
|
128
|
-
/**
|
|
129
|
-
* timeout is used for the next call to 'sendCommand'.
|
|
130
|
-
* NOTE: This can eventually be replaced when TypeScript
|
|
131
|
-
* resolves https://github.com/Microsoft/TypeScript/issues/5453.
|
|
132
|
-
* @param {number} timeout
|
|
133
|
-
*/
|
|
134
|
-
setNextProtocolTimeout(timeout: number): void;
|
|
135
|
-
/**
|
|
136
|
-
* @param {LH.Protocol.RawEventMessage} event
|
|
137
|
-
*/
|
|
138
|
-
_handleProtocolEvent(event: LH.Protocol.RawEventMessage): void;
|
|
139
|
-
/**
|
|
140
|
-
* @param {Error} error
|
|
141
|
-
*/
|
|
142
|
-
_handleEventError(error: Error): void;
|
|
143
|
-
/**
|
|
144
|
-
* @param {LH.Crdp.Target.AttachedToTargetEvent} event
|
|
145
|
-
*/
|
|
146
|
-
_handleTargetAttached(event: LH.Crdp.Target.AttachedToTargetEvent): Promise<void>;
|
|
147
|
-
/**
|
|
148
|
-
* Call protocol methods, with a timeout.
|
|
149
|
-
* To configure the timeout for the next call, use 'setNextProtocolTimeout'.
|
|
150
|
-
* If 'sessionId' is undefined, the message is sent to the main session.
|
|
151
|
-
* @template {keyof LH.CrdpCommands} C
|
|
152
|
-
* @param {C} method
|
|
153
|
-
* @param {string|undefined} sessionId
|
|
154
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
155
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
156
|
-
*/
|
|
157
|
-
sendCommandToSession<C extends keyof LH.CrdpCommands>(method: C, sessionId: string | undefined, ...params: LH.CrdpCommands[C]["paramsType"]): Promise<LH.CrdpCommands[C]["returnType"]>;
|
|
158
|
-
/**
|
|
159
|
-
* Alias for 'sendCommandToSession(method, undefined, ...params)'
|
|
160
|
-
* @template {keyof LH.CrdpCommands} C
|
|
161
|
-
* @param {C} method
|
|
162
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
163
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
164
|
-
*/
|
|
165
|
-
sendCommand<C_1 extends keyof LH.CrdpCommands>(method: C_1, ...params: LH.CrdpCommands[C_1]["paramsType"]): Promise<LH.CrdpCommands[C_1]["returnType"]>;
|
|
166
|
-
/**
|
|
167
|
-
* Call protocol methods.
|
|
168
|
-
* @private
|
|
169
|
-
* @template {keyof LH.CrdpCommands} C
|
|
170
|
-
* @param {C} method
|
|
171
|
-
* @param {string|undefined} sessionId
|
|
172
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
173
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
174
|
-
*/
|
|
175
|
-
private _innerSendCommand;
|
|
176
|
-
/**
|
|
177
|
-
* Returns whether a domain is currently enabled.
|
|
178
|
-
* @param {string} domain
|
|
179
|
-
* @return {boolean}
|
|
180
|
-
*/
|
|
181
|
-
isDomainEnabled(domain: string): boolean;
|
|
182
|
-
/**
|
|
183
|
-
* Return the body of the response with the given ID. Rejects if getting the
|
|
184
|
-
* body times out.
|
|
185
|
-
* @param {string} requestId
|
|
186
|
-
* @param {number} [timeout]
|
|
187
|
-
* @return {Promise<string>}
|
|
188
|
-
*/
|
|
189
|
-
getRequestContent(requestId: string, timeout?: number | undefined): Promise<string>;
|
|
190
|
-
/**
|
|
191
|
-
* @param {{additionalTraceCategories?: string|null}=} settings
|
|
192
|
-
* @return {Promise<void>}
|
|
193
|
-
*/
|
|
194
|
-
beginTrace(settings?: {
|
|
195
|
-
additionalTraceCategories?: string | null;
|
|
196
|
-
} | undefined): Promise<void>;
|
|
197
|
-
/**
|
|
198
|
-
* @return {Promise<LH.Trace>}
|
|
199
|
-
*/
|
|
200
|
-
endTrace(): Promise<LH.Trace>;
|
|
201
|
-
/**
|
|
202
|
-
* Begin recording devtools protocol messages.
|
|
203
|
-
*/
|
|
204
|
-
beginDevtoolsLog(): Promise<void>;
|
|
205
|
-
_disableAsyncStacks: (() => Promise<void>) | undefined;
|
|
206
|
-
/**
|
|
207
|
-
* Stop recording to devtoolsLog and return log contents.
|
|
208
|
-
* @return {Promise<LH.DevtoolsLog>}
|
|
209
|
-
*/
|
|
210
|
-
endDevtoolsLog(): Promise<LH.DevtoolsLog>;
|
|
211
|
-
url(): Promise<string>;
|
|
212
|
-
}
|
|
213
|
-
import * as LH from '../../../types/lh.js';
|
|
214
|
-
import { ExecutionContext } from '../../gather/driver/execution-context.js';
|
|
215
|
-
import { Fetcher } from '../../gather/fetcher.js';
|
|
216
|
-
//# sourceMappingURL=driver.d.ts.map
|
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license Copyright 2016 The Lighthouse Authors. All Rights Reserved.
|
|
3
|
-
* 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
|
|
4
|
-
* 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.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {EventEmitter} from 'events';
|
|
8
|
-
|
|
9
|
-
import log from 'lighthouse-logger';
|
|
10
|
-
|
|
11
|
-
import * as LH from '../../../types/lh.js';
|
|
12
|
-
import {Fetcher} from '../../gather/fetcher.js';
|
|
13
|
-
import {ExecutionContext} from '../../gather/driver/execution-context.js';
|
|
14
|
-
import {LighthouseError} from '../../lib/lh-error.js';
|
|
15
|
-
import {fetchResponseBodyFromCache} from '../../gather/driver/network.js';
|
|
16
|
-
import {DevtoolsMessageLog} from '../../gather/gatherers/devtools-log.js';
|
|
17
|
-
import TraceGatherer from '../../gather/gatherers/trace.js';
|
|
18
|
-
import {getBrowserVersion} from '../../gather/driver/environment.js';
|
|
19
|
-
import {enableAsyncStacks} from '../../gather/driver/prepare.js';
|
|
20
|
-
|
|
21
|
-
// Controls how long to wait for a response after sending a DevTools protocol command.
|
|
22
|
-
const DEFAULT_PROTOCOL_TIMEOUT = 30000;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @typedef {LH.Protocol.StrictEventEmitter<LH.CrdpEvents>} CrdpEventEmitter
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @implements {LH.Gatherer.FRTransitionalDriver}
|
|
30
|
-
*/
|
|
31
|
-
class Driver {
|
|
32
|
-
/**
|
|
33
|
-
* @pri_vate (This should be private, but that makes our tests harder).
|
|
34
|
-
* An event emitter that enforces mapping between Crdp event names and payload types.
|
|
35
|
-
*/
|
|
36
|
-
_eventEmitter = /** @type {CrdpEventEmitter} */ (new EventEmitter());
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @private
|
|
40
|
-
* Used to save network and lifecycle protocol traffic. Just Page and Network are needed.
|
|
41
|
-
*/
|
|
42
|
-
_devtoolsLog = new DevtoolsMessageLog(/^(Page|Network|Target|Runtime)\./);
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @private
|
|
46
|
-
* @type {Map<string, number>}
|
|
47
|
-
*/
|
|
48
|
-
_domainEnabledCounts = new Map();
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @type {number}
|
|
52
|
-
* @private
|
|
53
|
-
*/
|
|
54
|
-
_nextProtocolTimeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
55
|
-
|
|
56
|
-
online = true;
|
|
57
|
-
|
|
58
|
-
// eslint-disable-next-line no-invalid-this
|
|
59
|
-
executionContext = new ExecutionContext(this);
|
|
60
|
-
|
|
61
|
-
// eslint-disable-next-line no-invalid-this
|
|
62
|
-
defaultSession = this;
|
|
63
|
-
|
|
64
|
-
// eslint-disable-next-line no-invalid-this
|
|
65
|
-
fetcher = new Fetcher(this.defaultSession);
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* @param {import('./connections/connection.js').Connection} connection
|
|
69
|
-
*/
|
|
70
|
-
constructor(connection) {
|
|
71
|
-
this._connection = connection;
|
|
72
|
-
|
|
73
|
-
this.on('Target.attachedToTarget', event => {
|
|
74
|
-
this._handleTargetAttached(event).catch(this._handleEventError);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
this.on('Page.frameNavigated', event => {
|
|
78
|
-
// We're only interested in setting autoattach on the root via this method.
|
|
79
|
-
// `_handleTargetAttached` takes care of the recursive piece.
|
|
80
|
-
if (event.frame.parentId) return;
|
|
81
|
-
|
|
82
|
-
// Enable auto-attaching to subtargets so we receive iframe information.
|
|
83
|
-
this.sendCommand('Target.setAutoAttach', {
|
|
84
|
-
flatten: true,
|
|
85
|
-
autoAttach: true,
|
|
86
|
-
// Pause targets on startup so we don't miss anything
|
|
87
|
-
waitForDebuggerOnStart: true,
|
|
88
|
-
}).catch(this._handleEventError);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
connection.on('protocolevent', this._handleProtocolEvent.bind(this));
|
|
92
|
-
|
|
93
|
-
/** @private @deprecated Only available for plugin backcompat. */
|
|
94
|
-
this.evaluate = this.executionContext.evaluate.bind(this.executionContext);
|
|
95
|
-
/** @private @deprecated Only available for plugin backcompat. */
|
|
96
|
-
this.evaluateAsync = this.executionContext.evaluateAsync.bind(this.executionContext);
|
|
97
|
-
|
|
98
|
-
// A shim for sufficient coverage of targetManager functionality. Exposes the target
|
|
99
|
-
// management that legacy driver already handles (see this._handleTargetAttached).
|
|
100
|
-
this.targetManager = {
|
|
101
|
-
rootSession: () => {
|
|
102
|
-
return this.defaultSession;
|
|
103
|
-
},
|
|
104
|
-
// For legacy driver, only bother supporting access to the default execution context.
|
|
105
|
-
mainFrameExecutionContexts: () => {
|
|
106
|
-
// @ts-expect-error - undefined ids are OK for purposes of calling protocol commands like Runtime.evaluate.
|
|
107
|
-
return [/** @type {LH.Crdp.Runtime.ExecutionContextDescription} */({
|
|
108
|
-
id: undefined,
|
|
109
|
-
uniqueId: undefined,
|
|
110
|
-
origin: '',
|
|
111
|
-
name: '',
|
|
112
|
-
auxData: {isDefault: true, type: 'default', frameId: ''},
|
|
113
|
-
})];
|
|
114
|
-
},
|
|
115
|
-
/**
|
|
116
|
-
* Bind to *any* protocol event.
|
|
117
|
-
* @param {'protocolevent'} event
|
|
118
|
-
* @param {(payload: LH.Protocol.RawEventMessage) => void} callback
|
|
119
|
-
*/
|
|
120
|
-
on: (event, callback) => {
|
|
121
|
-
this._connection.on('protocolevent', callback);
|
|
122
|
-
},
|
|
123
|
-
/**
|
|
124
|
-
* Unbind to *any* protocol event.
|
|
125
|
-
* @param {'protocolevent'} event
|
|
126
|
-
* @param {(payload: LH.Protocol.RawEventMessage) => void} callback
|
|
127
|
-
*/
|
|
128
|
-
off: (event, callback) => {
|
|
129
|
-
this._connection.off('protocolevent', callback);
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** @deprecated - Not available on Fraggle Rock driver. */
|
|
135
|
-
static get traceCategories() {
|
|
136
|
-
return TraceGatherer.getDefaultTraceCategories();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* @return {Promise<LH.Crdp.Browser.GetVersionResponse & {milestone: number}>}
|
|
141
|
-
*/
|
|
142
|
-
async getBrowserVersion() {
|
|
143
|
-
return getBrowserVersion(this);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* @return {Promise<void>}
|
|
148
|
-
*/
|
|
149
|
-
async connect() {
|
|
150
|
-
const status = {msg: 'Connecting to browser', id: 'lh:init:connect'};
|
|
151
|
-
log.time(status);
|
|
152
|
-
await this._connection.connect();
|
|
153
|
-
log.timeEnd(status);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* @return {Promise<void>}
|
|
158
|
-
*/
|
|
159
|
-
disconnect() {
|
|
160
|
-
return this._connection.disconnect();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** @return {Promise<void>} */
|
|
164
|
-
dispose() {
|
|
165
|
-
return this.disconnect();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Get the browser WebSocket endpoint for devtools protocol clients like Puppeteer.
|
|
170
|
-
* Only works with WebSocket connection, not extension or devtools.
|
|
171
|
-
* @return {Promise<string>}
|
|
172
|
-
*/
|
|
173
|
-
wsEndpoint() {
|
|
174
|
-
return this._connection.wsEndpoint();
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Bind listeners for protocol events.
|
|
179
|
-
* @template {keyof LH.CrdpEvents} E
|
|
180
|
-
* @param {E} eventName
|
|
181
|
-
* @param {(...args: LH.CrdpEvents[E]) => void} cb
|
|
182
|
-
*/
|
|
183
|
-
on(eventName, cb) {
|
|
184
|
-
if (this._eventEmitter === null) {
|
|
185
|
-
throw new Error('connect() must be called before attempting to listen to events.');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// log event listeners being bound
|
|
189
|
-
log.formatProtocol('listen for event =>', {method: eventName}, 'verbose');
|
|
190
|
-
this._eventEmitter.on(eventName, cb);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Bind a one-time listener for protocol events. Listener is removed once it
|
|
195
|
-
* has been called.
|
|
196
|
-
* @template {keyof LH.CrdpEvents} E
|
|
197
|
-
* @param {E} eventName
|
|
198
|
-
* @param {(...args: LH.CrdpEvents[E]) => void} cb
|
|
199
|
-
*/
|
|
200
|
-
once(eventName, cb) {
|
|
201
|
-
if (this._eventEmitter === null) {
|
|
202
|
-
throw new Error('connect() must be called before attempting to listen to events.');
|
|
203
|
-
}
|
|
204
|
-
// log event listeners being bound
|
|
205
|
-
log.formatProtocol('listen once for event =>', {method: eventName}, 'verbose');
|
|
206
|
-
this._eventEmitter.once(eventName, cb);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Unbind event listener.
|
|
211
|
-
* @template {keyof LH.CrdpEvents} E
|
|
212
|
-
* @param {E} eventName
|
|
213
|
-
* @param {Function} cb
|
|
214
|
-
*/
|
|
215
|
-
off(eventName, cb) {
|
|
216
|
-
if (this._eventEmitter === null) {
|
|
217
|
-
throw new Error('connect() must be called before attempting to remove an event listener.');
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
this._eventEmitter.removeListener(eventName, cb);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** @param {LH.Crdp.Target.TargetInfo} targetInfo */
|
|
224
|
-
setTargetInfo(targetInfo) { // eslint-disable-line no-unused-vars
|
|
225
|
-
// OOPIF handling in legacy driver is implicit.
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Debounce enabling or disabling domains to prevent driver users from
|
|
230
|
-
* stomping on each other. Maintains an internal count of the times a domain
|
|
231
|
-
* has been enabled. Returns false if the command would have no effect (domain
|
|
232
|
-
* is already enabled or disabled), or if command would interfere with another
|
|
233
|
-
* user of that domain (e.g. two gatherers have enabled a domain, both need to
|
|
234
|
-
* disable it for it to be disabled). Returns true otherwise.
|
|
235
|
-
* @param {string} domain
|
|
236
|
-
* @param {string|undefined} sessionId
|
|
237
|
-
* @param {boolean} enable
|
|
238
|
-
* @return {boolean}
|
|
239
|
-
* @private
|
|
240
|
-
*/
|
|
241
|
-
_shouldToggleDomain(domain, sessionId, enable) {
|
|
242
|
-
const key = domain + (sessionId || '');
|
|
243
|
-
const enabledCount = this._domainEnabledCounts.get(key) || 0;
|
|
244
|
-
const newCount = enabledCount + (enable ? 1 : -1);
|
|
245
|
-
this._domainEnabledCounts.set(key, Math.max(0, newCount));
|
|
246
|
-
|
|
247
|
-
// Switching to enabled or disabled, respectively.
|
|
248
|
-
if ((enable && newCount === 1) || (!enable && newCount === 0)) {
|
|
249
|
-
log.verbose('Driver', `${domain}.${enable ? 'enable' : 'disable'}`);
|
|
250
|
-
return true;
|
|
251
|
-
} else {
|
|
252
|
-
if (newCount < 0) {
|
|
253
|
-
log.error('Driver', `Attempted to disable domain '${domain}' when already disabled.`);
|
|
254
|
-
}
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* @return {boolean}
|
|
261
|
-
*/
|
|
262
|
-
hasNextProtocolTimeout() {
|
|
263
|
-
return this._nextProtocolTimeout !== DEFAULT_PROTOCOL_TIMEOUT;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* @return {number}
|
|
268
|
-
*/
|
|
269
|
-
getNextProtocolTimeout() {
|
|
270
|
-
return this._nextProtocolTimeout;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* timeout is used for the next call to 'sendCommand'.
|
|
275
|
-
* NOTE: This can eventually be replaced when TypeScript
|
|
276
|
-
* resolves https://github.com/Microsoft/TypeScript/issues/5453.
|
|
277
|
-
* @param {number} timeout
|
|
278
|
-
*/
|
|
279
|
-
setNextProtocolTimeout(timeout) {
|
|
280
|
-
this._nextProtocolTimeout = timeout;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* @param {LH.Protocol.RawEventMessage} event
|
|
285
|
-
*/
|
|
286
|
-
_handleProtocolEvent(event) {
|
|
287
|
-
this._devtoolsLog.record(event);
|
|
288
|
-
|
|
289
|
-
// @ts-expect-error TODO(bckenny): tsc can't type event.params correctly yet,
|
|
290
|
-
// typing as property of union instead of narrowing from union of
|
|
291
|
-
// properties. See https://github.com/Microsoft/TypeScript/pull/22348.
|
|
292
|
-
this._eventEmitter.emit(event.method, event.params);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* @param {Error} error
|
|
297
|
-
*/
|
|
298
|
-
_handleEventError(error) {
|
|
299
|
-
log.error('Driver', 'Unhandled event error', error.message);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* @param {LH.Crdp.Target.AttachedToTargetEvent} event
|
|
304
|
-
*/
|
|
305
|
-
async _handleTargetAttached(event) {
|
|
306
|
-
// We're only interested in network requests from iframes for now as those are "part of the page".
|
|
307
|
-
// If it's not an iframe, just resume it and move on.
|
|
308
|
-
if (event.targetInfo.type !== 'iframe') {
|
|
309
|
-
// We suspended the target when we auto-attached, so make sure it goes back to being normal.
|
|
310
|
-
await this.sendCommandToSession('Runtime.runIfWaitingForDebugger', event.sessionId);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Note: This is only reached for _out of process_ iframes (OOPIFs).
|
|
315
|
-
// If the iframe is in the same process as its embedding document, that means they
|
|
316
|
-
// share the same target.
|
|
317
|
-
|
|
318
|
-
// A target won't acknowledge/respond to protocol methods (or, at least for Network.enable)
|
|
319
|
-
// until it is resumed. But also we're paranoid about sending Network.enable _slightly_ too late,
|
|
320
|
-
// so we issue that method first. Therefore, we don't await on this serially, but await all at once.
|
|
321
|
-
await Promise.all([
|
|
322
|
-
// Events from subtargets will be stringified and sent back on `Target.receivedMessageFromTarget`.
|
|
323
|
-
// We want to receive information about network requests from iframes, so enable the Network domain.
|
|
324
|
-
this.sendCommandToSession('Network.enable', event.sessionId),
|
|
325
|
-
// We also want to receive information about subtargets of subtargets, so make sure we autoattach recursively.
|
|
326
|
-
this.sendCommandToSession('Target.setAutoAttach', event.sessionId, {
|
|
327
|
-
autoAttach: true,
|
|
328
|
-
flatten: true,
|
|
329
|
-
// Pause targets on startup so we don't miss anything
|
|
330
|
-
waitForDebuggerOnStart: true,
|
|
331
|
-
}),
|
|
332
|
-
// We suspended the target when we auto-attached, so make sure it goes back to being normal.
|
|
333
|
-
this.sendCommandToSession('Runtime.runIfWaitingForDebugger', event.sessionId),
|
|
334
|
-
]);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Call protocol methods, with a timeout.
|
|
339
|
-
* To configure the timeout for the next call, use 'setNextProtocolTimeout'.
|
|
340
|
-
* If 'sessionId' is undefined, the message is sent to the main session.
|
|
341
|
-
* @template {keyof LH.CrdpCommands} C
|
|
342
|
-
* @param {C} method
|
|
343
|
-
* @param {string|undefined} sessionId
|
|
344
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
345
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
346
|
-
*/
|
|
347
|
-
sendCommandToSession(method, sessionId, ...params) {
|
|
348
|
-
const timeout = this._nextProtocolTimeout;
|
|
349
|
-
this._nextProtocolTimeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
350
|
-
|
|
351
|
-
/** @type {NodeJS.Timer|undefined} */
|
|
352
|
-
let asyncTimeout;
|
|
353
|
-
const timeoutPromise = new Promise((resolve, reject) => {
|
|
354
|
-
if (timeout === Infinity) return;
|
|
355
|
-
// eslint-disable-next-line max-len
|
|
356
|
-
asyncTimeout = setTimeout(reject, timeout, new LighthouseError(LighthouseError.errors.PROTOCOL_TIMEOUT, {
|
|
357
|
-
protocolMethod: method,
|
|
358
|
-
}));
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
return Promise.race([
|
|
362
|
-
this._innerSendCommand(method, sessionId, ...params),
|
|
363
|
-
timeoutPromise,
|
|
364
|
-
]).finally(() => {
|
|
365
|
-
asyncTimeout && clearTimeout(asyncTimeout);
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Alias for 'sendCommandToSession(method, undefined, ...params)'
|
|
371
|
-
* @template {keyof LH.CrdpCommands} C
|
|
372
|
-
* @param {C} method
|
|
373
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
374
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
375
|
-
*/
|
|
376
|
-
sendCommand(method, ...params) {
|
|
377
|
-
return this.sendCommandToSession(method, undefined, ...params);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Call protocol methods.
|
|
382
|
-
* @private
|
|
383
|
-
* @template {keyof LH.CrdpCommands} C
|
|
384
|
-
* @param {C} method
|
|
385
|
-
* @param {string|undefined} sessionId
|
|
386
|
-
* @param {LH.CrdpCommands[C]['paramsType']} params
|
|
387
|
-
* @return {Promise<LH.CrdpCommands[C]['returnType']>}
|
|
388
|
-
*/
|
|
389
|
-
_innerSendCommand(method, sessionId, ...params) {
|
|
390
|
-
const domainCommand = /^(\w+)\.(enable|disable)$/.exec(method);
|
|
391
|
-
if (domainCommand) {
|
|
392
|
-
const enable = domainCommand[2] === 'enable';
|
|
393
|
-
if (!this._shouldToggleDomain(domainCommand[1], sessionId, enable)) {
|
|
394
|
-
return Promise.resolve();
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
return this._connection.sendCommand(method, sessionId, ...params);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Returns whether a domain is currently enabled.
|
|
402
|
-
* @param {string} domain
|
|
403
|
-
* @return {boolean}
|
|
404
|
-
*/
|
|
405
|
-
isDomainEnabled(domain) {
|
|
406
|
-
// Defined, non-zero elements of the domains map are enabled.
|
|
407
|
-
return !!this._domainEnabledCounts.get(domain);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Return the body of the response with the given ID. Rejects if getting the
|
|
412
|
-
* body times out.
|
|
413
|
-
* @param {string} requestId
|
|
414
|
-
* @param {number} [timeout]
|
|
415
|
-
* @return {Promise<string>}
|
|
416
|
-
*/
|
|
417
|
-
async getRequestContent(requestId, timeout = 1000) {
|
|
418
|
-
return fetchResponseBodyFromCache(this.defaultSession, requestId, timeout);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* @param {{additionalTraceCategories?: string|null}=} settings
|
|
423
|
-
* @return {Promise<void>}
|
|
424
|
-
*/
|
|
425
|
-
async beginTrace(settings) {
|
|
426
|
-
const additionalCategories = (settings?.additionalTraceCategories &&
|
|
427
|
-
settings.additionalTraceCategories.split(',')) || [];
|
|
428
|
-
const traceCategories = TraceGatherer.getDefaultTraceCategories().concat(additionalCategories);
|
|
429
|
-
|
|
430
|
-
const uniqueCategories = Array.from(new Set(traceCategories));
|
|
431
|
-
|
|
432
|
-
// Check any domains that could interfere with or add overhead to the trace.
|
|
433
|
-
if (this.isDomainEnabled('CSS')) {
|
|
434
|
-
throw new Error('CSS domain enabled when starting trace');
|
|
435
|
-
}
|
|
436
|
-
if (this.isDomainEnabled('DOM')) {
|
|
437
|
-
throw new Error('DOM domain enabled when starting trace');
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Enable Page domain to wait for Page.loadEventFired
|
|
441
|
-
return this.sendCommand('Page.enable')
|
|
442
|
-
.then(_ => this.sendCommand('Tracing.start', {
|
|
443
|
-
categories: uniqueCategories.join(','),
|
|
444
|
-
options: 'sampling-frequency=10000', // 1000 is default and too slow.
|
|
445
|
-
}));
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* @return {Promise<LH.Trace>}
|
|
450
|
-
*/
|
|
451
|
-
endTrace() {
|
|
452
|
-
return TraceGatherer.endTraceAndCollectEvents(this.defaultSession);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Begin recording devtools protocol messages.
|
|
457
|
-
*/
|
|
458
|
-
async beginDevtoolsLog() {
|
|
459
|
-
this._disableAsyncStacks = await enableAsyncStacks(this);
|
|
460
|
-
this._devtoolsLog.reset();
|
|
461
|
-
this._devtoolsLog.beginRecording();
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Stop recording to devtoolsLog and return log contents.
|
|
466
|
-
* @return {Promise<LH.DevtoolsLog>}
|
|
467
|
-
*/
|
|
468
|
-
async endDevtoolsLog() {
|
|
469
|
-
this._devtoolsLog.endRecording();
|
|
470
|
-
await this._disableAsyncStacks?.();
|
|
471
|
-
return this._devtoolsLog.messages;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
async url() {
|
|
475
|
-
const {frameTree} = await this.sendCommand('Page.getFrameTree');
|
|
476
|
-
return `${frameTree.frame.url}${frameTree.frame.urlFragment || ''}`;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
export {Driver};
|