lighthouse 13.4.1-dev.20260916 → 13.5.0-dev.20260917
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/core/audits/baseline.d.ts +13 -5
- package/core/gather/driver/navigation.d.ts +1 -0
- package/core/gather/driver/navigation.js +35 -7
- package/core/gather/driver/wait-for-condition.d.ts +2 -1
- package/core/gather/driver/wait-for-condition.js +13 -1
- package/core/gather/navigation-runner.d.ts +3 -1
- package/core/gather/navigation-runner.js +6 -3
- package/core/lib/baseline/web-features-data.json +27 -16
- package/core/lib/baseline/web-features-metadata.json +1 -1
- package/core/user-flow.d.ts +3 -0
- package/core/user-flow.js +12 -0
- package/dist/report/bundle.esm.js +8 -1
- package/dist/report/flow.js +19 -12
- package/dist/report/standalone.js +10 -3
- package/package.json +4 -4
- package/report/assets/styles.css +7 -0
- package/report/renderer/components.js +1 -1
- package/report/renderer/report-renderer.js +24 -3
- package/third-party/ard/README.md +1 -1
|
@@ -35,6 +35,7 @@ declare class Baseline extends Audit {
|
|
|
35
35
|
"array-flat": string;
|
|
36
36
|
"array-from": string;
|
|
37
37
|
"array-fromasync": string;
|
|
38
|
+
"array-group": string;
|
|
38
39
|
"array-includes": string;
|
|
39
40
|
"array-isarray": string;
|
|
40
41
|
"array-iteration-methods": string;
|
|
@@ -101,6 +102,7 @@ declare class Baseline extends Audit {
|
|
|
101
102
|
"change-event": string;
|
|
102
103
|
"channel-messaging": string;
|
|
103
104
|
charset: string;
|
|
105
|
+
"check-visibility": string;
|
|
104
106
|
cite: string;
|
|
105
107
|
"class-syntax": string;
|
|
106
108
|
"clip-path": string;
|
|
@@ -450,6 +452,7 @@ declare class Baseline extends Audit {
|
|
|
450
452
|
"promise-allsettled": string;
|
|
451
453
|
"promise-any": string;
|
|
452
454
|
"promise-finally": string;
|
|
455
|
+
"promise-withresolvers": string;
|
|
453
456
|
"proxy-reflect": string;
|
|
454
457
|
push: string;
|
|
455
458
|
q: string;
|
|
@@ -574,6 +577,7 @@ declare class Baseline extends Audit {
|
|
|
574
577
|
title: string;
|
|
575
578
|
"title-attr": string;
|
|
576
579
|
"touch-action": string;
|
|
580
|
+
"transferable-arraybuffer": string;
|
|
577
581
|
transforms2d: string;
|
|
578
582
|
transforms3d: string;
|
|
579
583
|
transitions: string;
|
|
@@ -605,6 +609,7 @@ declare class Baseline extends Audit {
|
|
|
605
609
|
"wasm-bigint": string;
|
|
606
610
|
"wasm-bulk-memory": string;
|
|
607
611
|
"wasm-exception-handling": string;
|
|
612
|
+
"wasm-extended-constant-expressions": string;
|
|
608
613
|
"wasm-multi-value": string;
|
|
609
614
|
"wasm-mutable-globals": string;
|
|
610
615
|
"wasm-non-trapping-float-to-int": string;
|
|
@@ -659,15 +664,16 @@ declare class Baseline extends Audit {
|
|
|
659
664
|
"abs-sign": string;
|
|
660
665
|
"active-view-transition": string;
|
|
661
666
|
"align-content-block": string;
|
|
667
|
+
alpha: string;
|
|
662
668
|
"alt-text-generated-content": string;
|
|
663
|
-
"array-group": string;
|
|
664
669
|
"async-clipboard": string;
|
|
670
|
+
"async-iterable-streams": string;
|
|
665
671
|
"atomics-pause": string;
|
|
666
672
|
"atomics-wait-async": string;
|
|
673
|
+
autocorrect: string;
|
|
667
674
|
"backdrop-filter": string;
|
|
668
675
|
"baseline-shift": string;
|
|
669
676
|
"canvas-2d-willreadfrequently": string;
|
|
670
|
-
"check-visibility": string;
|
|
671
677
|
"clipboard-supports": string;
|
|
672
678
|
"composed-ranges": string;
|
|
673
679
|
"container-style-queries": string;
|
|
@@ -704,17 +710,19 @@ declare class Baseline extends Audit {
|
|
|
704
710
|
"json-raw": string;
|
|
705
711
|
"largest-contentful-paint": string;
|
|
706
712
|
"light-dark": string;
|
|
713
|
+
"light-dark-image": string;
|
|
707
714
|
"link-rel-dns-prefetch": string;
|
|
708
715
|
"math-sum-precise": string;
|
|
709
716
|
navigation: string;
|
|
710
717
|
"open-pseudo": string;
|
|
718
|
+
"overflow-anchor": string;
|
|
711
719
|
"page-setup": string;
|
|
712
720
|
"paint-order": string;
|
|
713
721
|
"parse-html-unsafe": string;
|
|
714
722
|
popover: string;
|
|
715
723
|
"print-color-adjust": string;
|
|
724
|
+
"progress-function": string;
|
|
716
725
|
"promise-try": string;
|
|
717
|
-
"promise-withresolvers": string;
|
|
718
726
|
rcap: string;
|
|
719
727
|
rch: string;
|
|
720
728
|
"readable-byte-streams": string;
|
|
@@ -752,7 +760,7 @@ declare class Baseline extends Audit {
|
|
|
752
760
|
"text-wrap": string;
|
|
753
761
|
"text-wrap-balance": string;
|
|
754
762
|
"toggleevent-source": string;
|
|
755
|
-
"
|
|
763
|
+
"top-level-await": string;
|
|
756
764
|
"transform-box": string;
|
|
757
765
|
"transition-behavior": string;
|
|
758
766
|
"trusted-types": string;
|
|
@@ -763,8 +771,8 @@ declare class Baseline extends Audit {
|
|
|
763
771
|
"view-transitions": string;
|
|
764
772
|
"wasm-branch-hinting": string;
|
|
765
773
|
"wasm-exnref-exceptions": string;
|
|
766
|
-
"wasm-extended-constant-expressions": string;
|
|
767
774
|
"wasm-garbage-collection": string;
|
|
775
|
+
"wasm-jspi": string;
|
|
768
776
|
"wasm-tail-call-optimization": string;
|
|
769
777
|
"wasm-typed-fun-refs": string;
|
|
770
778
|
"webgl-color-management": string;
|
|
@@ -39,7 +39,7 @@ const DEFAULT_NETWORK_QUIET_THRESHOLD = 5000;
|
|
|
39
39
|
// Controls how long to wait between longtasks before determining the CPU is idle, off by default
|
|
40
40
|
const DEFAULT_CPU_QUIET_THRESHOLD = 0;
|
|
41
41
|
|
|
42
|
-
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'
|
|
42
|
+
/** @typedef {{waitUntil: Array<'fcp'|'load'|'navigated'>, signal?: AbortSignal} & Partial<LH.Config.Settings>} NavigationOptions */
|
|
43
43
|
|
|
44
44
|
/** @param {NavigationOptions} options */
|
|
45
45
|
function resolveWaitForFullyLoadedOptions(options) {
|
|
@@ -107,23 +107,49 @@ async function gotoURL(driver, requestor, options) {
|
|
|
107
107
|
|
|
108
108
|
/** @type {Array<Promise<{timedOut: boolean}>>} */
|
|
109
109
|
const waitConditionPromises = [];
|
|
110
|
+
/** @type {Array<() => void>} */
|
|
111
|
+
const cleanups = [];
|
|
112
|
+
|
|
113
|
+
/** @type {(event: Event) => void} */
|
|
114
|
+
let onAbort = () => {};
|
|
115
|
+
/** @type {Promise<never>} */
|
|
116
|
+
const abortPromise = new Promise((_, reject) => {
|
|
117
|
+
if (!options.signal) return;
|
|
118
|
+
options.signal.throwIfAborted();
|
|
119
|
+
onAbort = () => reject(new Error('Navigation aborted by signal'));
|
|
120
|
+
options.signal.addEventListener('abort', onAbort, {once: true});
|
|
121
|
+
});
|
|
122
|
+
if (options.signal) cleanups.push(() => options.signal?.removeEventListener('abort', onAbort));
|
|
110
123
|
|
|
111
124
|
if (waitForNavigated) {
|
|
112
|
-
const
|
|
113
|
-
|
|
125
|
+
const {promise, cancel} = waitForFrameNavigated(session);
|
|
126
|
+
cleanups.push(() => cancel());
|
|
127
|
+
waitConditionPromises.push(promise
|
|
128
|
+
.then(() => ({timedOut: false}))
|
|
129
|
+
.catch(() => ({timedOut: false})));
|
|
114
130
|
}
|
|
115
131
|
|
|
116
132
|
if (waitForLoad) {
|
|
117
133
|
const waitOptions = resolveWaitForFullyLoadedOptions(options);
|
|
118
|
-
waitConditionPromises.push(
|
|
134
|
+
waitConditionPromises.push(
|
|
135
|
+
waitForFullyLoaded(session, networkMonitor, waitOptions, options.signal)
|
|
136
|
+
);
|
|
119
137
|
} else if (waitForFcp) {
|
|
120
138
|
throw new Error('Cannot wait for FCP without waiting for page load');
|
|
121
139
|
}
|
|
122
140
|
|
|
123
|
-
const
|
|
141
|
+
const waitConditionsRace = [
|
|
124
142
|
session.onCrashPromise(),
|
|
125
143
|
Promise.all(waitConditionPromises),
|
|
126
|
-
]
|
|
144
|
+
];
|
|
145
|
+
if (options.signal) waitConditionsRace.push(abortPromise);
|
|
146
|
+
|
|
147
|
+
let waitConditions;
|
|
148
|
+
try {
|
|
149
|
+
waitConditions = await Promise.race(waitConditionsRace);
|
|
150
|
+
} finally {
|
|
151
|
+
for (const cleanup of cleanups) cleanup();
|
|
152
|
+
}
|
|
127
153
|
const timedOut = waitConditions.some(condition => condition.timedOut);
|
|
128
154
|
const navigationUrls = await networkMonitor.getNavigationUrls();
|
|
129
155
|
|
|
@@ -142,7 +168,9 @@ async function gotoURL(driver, requestor, options) {
|
|
|
142
168
|
const mainDocumentUrl = navigationUrls.mainDocumentUrl || requestedUrl;
|
|
143
169
|
|
|
144
170
|
// Bring `Page.navigate` errors back into the promise chain. See https://github.com/GoogleChrome/lighthouse/pull/6739.
|
|
145
|
-
await
|
|
171
|
+
await Promise.race(options.signal ?
|
|
172
|
+
[waitForNavigationTriggered, abortPromise] :
|
|
173
|
+
[waitForNavigationTriggered]);
|
|
146
174
|
|
|
147
175
|
if (options.debugNavigation) {
|
|
148
176
|
await waitForUserToContinue(driver);
|
|
@@ -101,9 +101,10 @@ export function waitForCPUIdle(session: LH.Gatherer.ProtocolSession, waitForCPUQ
|
|
|
101
101
|
* @param {LH.Gatherer.ProtocolSession} session
|
|
102
102
|
* @param {NetworkMonitor} networkMonitor
|
|
103
103
|
* @param {WaitOptions} options
|
|
104
|
+
* @param {AbortSignal} [signal]
|
|
104
105
|
* @return {Promise<{timedOut: boolean}>}
|
|
105
106
|
*/
|
|
106
|
-
export function waitForFullyLoaded(session: LH.Gatherer.ProtocolSession, networkMonitor: NetworkMonitor, options: WaitOptions): Promise<{
|
|
107
|
+
export function waitForFullyLoaded(session: LH.Gatherer.ProtocolSession, networkMonitor: NetworkMonitor, options: WaitOptions, signal?: AbortSignal): Promise<{
|
|
107
108
|
timedOut: boolean;
|
|
108
109
|
}>;
|
|
109
110
|
/**
|
|
@@ -418,9 +418,10 @@ const DEFAULT_WAIT_FUNCTIONS = {waitForFcp, waitForLoadEvent, waitForCPUIdle, wa
|
|
|
418
418
|
* @param {LH.Gatherer.ProtocolSession} session
|
|
419
419
|
* @param {NetworkMonitor} networkMonitor
|
|
420
420
|
* @param {WaitOptions} options
|
|
421
|
+
* @param {AbortSignal} [signal]
|
|
421
422
|
* @return {Promise<{timedOut: boolean}>}
|
|
422
423
|
*/
|
|
423
|
-
async function waitForFullyLoaded(session, networkMonitor, options) {
|
|
424
|
+
async function waitForFullyLoaded(session, networkMonitor, options, signal) {
|
|
424
425
|
const {pauseAfterFcpMs, pauseAfterLoadMs, networkQuietThresholdMs,
|
|
425
426
|
cpuQuietThresholdMs, maxWaitForLoadedMs, maxWaitForFcpMs} = options;
|
|
426
427
|
const {waitForFcp, waitForLoadEvent, waitForNetworkIdle, waitForCPUIdle} =
|
|
@@ -524,12 +525,23 @@ async function waitForFullyLoaded(session, networkMonitor, options) {
|
|
|
524
525
|
};
|
|
525
526
|
});
|
|
526
527
|
|
|
528
|
+
/** @type {(event: Event) => void} */
|
|
529
|
+
let onAbort = () => {};
|
|
530
|
+
/** @type {Promise<() => Promise<{timedOut: boolean}>>} */
|
|
531
|
+
const abortPromise = new Promise((resolve) => {
|
|
532
|
+
signal?.throwIfAborted();
|
|
533
|
+
onAbort = () => resolve(async () => ({timedOut: false}));
|
|
534
|
+
signal?.addEventListener('abort', onAbort, {once: true});
|
|
535
|
+
});
|
|
536
|
+
|
|
527
537
|
// Wait for load or timeout and run the cleanup function the winner returns.
|
|
528
538
|
const cleanupFn = await Promise.race([
|
|
529
539
|
loadPromise,
|
|
530
540
|
maxTimeoutPromise,
|
|
541
|
+
abortPromise,
|
|
531
542
|
]);
|
|
532
543
|
|
|
544
|
+
signal?.removeEventListener('abort', onAbort);
|
|
533
545
|
maxTimeoutHandle && clearTimeout(maxTimeoutHandle);
|
|
534
546
|
resolveOnFcp.cancel();
|
|
535
547
|
resolveOnLoadEvent.cancel();
|
|
@@ -5,17 +5,19 @@ export type NavigationContext = {
|
|
|
5
5
|
requestor: LH.NavigationRequestor;
|
|
6
6
|
baseArtifacts: LH.BaseArtifacts;
|
|
7
7
|
computedCache: Map<string, LH.ArbitraryEqualityMap>;
|
|
8
|
+
signal?: AbortSignal | undefined;
|
|
8
9
|
};
|
|
9
10
|
export type PhaseState = Omit<Parameters<typeof collectPhaseArtifacts>[0], "phase">;
|
|
10
11
|
/**
|
|
11
12
|
* @param {LH.Puppeteer.Page|undefined} page
|
|
12
13
|
* @param {LH.NavigationRequestor|undefined} requestor
|
|
13
|
-
* @param {{config?: LH.Config, flags?: LH.Flags}} [options]
|
|
14
|
+
* @param {{config?: LH.Config, flags?: LH.Flags, signal?: AbortSignal }} [options]
|
|
14
15
|
* @return {Promise<LH.Gatherer.GatherResult>}
|
|
15
16
|
*/
|
|
16
17
|
export function navigationGather(page: LH.Puppeteer.Page | undefined, requestor: LH.NavigationRequestor | undefined, options?: {
|
|
17
18
|
config?: LH.Config;
|
|
18
19
|
flags?: LH.Flags;
|
|
20
|
+
signal?: AbortSignal;
|
|
19
21
|
}): Promise<LH.Gatherer.GatherResult>;
|
|
20
22
|
/**
|
|
21
23
|
* @param {{driver: Driver, resolvedConfig: LH.Config.ResolvedConfig, requestor: LH.NavigationRequestor}} args
|
|
@@ -32,6 +32,7 @@ import {NetworkRecords} from '../computed/network-records.js';
|
|
|
32
32
|
* @property {LH.NavigationRequestor} requestor
|
|
33
33
|
* @property {LH.BaseArtifacts} baseArtifacts
|
|
34
34
|
* @property {Map<string, LH.ArbitraryEqualityMap>} computedCache
|
|
35
|
+
* @property {AbortSignal} [signal]
|
|
35
36
|
*/
|
|
36
37
|
|
|
37
38
|
/** @typedef {Omit<Parameters<typeof collectPhaseArtifacts>[0], 'phase'>} PhaseState */
|
|
@@ -79,12 +80,13 @@ async function _cleanupNavigation({driver}) {
|
|
|
79
80
|
* @return {Promise<{requestedUrl: string, mainDocumentUrl: string, navigationError: LH.LighthouseError | undefined}>}
|
|
80
81
|
*/
|
|
81
82
|
async function _navigate(navigationContext) {
|
|
82
|
-
const {driver, resolvedConfig, requestor} = navigationContext;
|
|
83
|
+
const {driver, resolvedConfig, requestor, signal} = navigationContext;
|
|
83
84
|
|
|
84
85
|
try {
|
|
85
86
|
const {requestedUrl, mainDocumentUrl, warnings} = await gotoURL(driver, requestor, {
|
|
86
87
|
...resolvedConfig.settings,
|
|
87
88
|
waitUntil: resolvedConfig.settings.pauseAfterFcpMs ? ['fcp', 'load'] : ['load'],
|
|
89
|
+
signal,
|
|
88
90
|
});
|
|
89
91
|
|
|
90
92
|
navigationContext.baseArtifacts.LighthouseRunWarnings.push(...warnings);
|
|
@@ -251,11 +253,11 @@ async function _cleanup({requestedUrl, driver, resolvedConfig, lhBrowser, lhPage
|
|
|
251
253
|
/**
|
|
252
254
|
* @param {LH.Puppeteer.Page|undefined} page
|
|
253
255
|
* @param {LH.NavigationRequestor|undefined} requestor
|
|
254
|
-
* @param {{config?: LH.Config, flags?: LH.Flags}} [options]
|
|
256
|
+
* @param {{config?: LH.Config, flags?: LH.Flags, signal?: AbortSignal }} [options]
|
|
255
257
|
* @return {Promise<LH.Gatherer.GatherResult>}
|
|
256
258
|
*/
|
|
257
259
|
async function navigationGather(page, requestor, options = {}) {
|
|
258
|
-
const {flags = {}, config} = options;
|
|
260
|
+
const {flags = {}, config, signal} = options;
|
|
259
261
|
log.setLevel(flags.logLevel || 'error');
|
|
260
262
|
|
|
261
263
|
const {resolvedConfig} = await initializeConfig('navigation', config, flags);
|
|
@@ -291,6 +293,7 @@ async function navigationGather(page, requestor, options = {}) {
|
|
|
291
293
|
resolvedConfig,
|
|
292
294
|
requestor: normalizedRequestor,
|
|
293
295
|
computedCache,
|
|
296
|
+
signal,
|
|
294
297
|
};
|
|
295
298
|
const {baseArtifacts} = await _setup(context);
|
|
296
299
|
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"array-flat": "2020-01-15",
|
|
25
25
|
"array-from": "2016-09-20",
|
|
26
26
|
"array-fromasync": "2024-01-25",
|
|
27
|
+
"array-group": "2024-03-05",
|
|
27
28
|
"array-includes": "2016-09-20",
|
|
28
29
|
"array-isarray": "2015-07-29",
|
|
29
30
|
"array-iteration-methods": "2015-07-29",
|
|
@@ -90,6 +91,7 @@
|
|
|
90
91
|
"change-event": "2015-07-29",
|
|
91
92
|
"channel-messaging": "2015-09-22",
|
|
92
93
|
"charset": "2015-07-29",
|
|
94
|
+
"check-visibility": "2024-03-05",
|
|
93
95
|
"cite": "2015-07-29",
|
|
94
96
|
"class-syntax": "2016-03-08",
|
|
95
97
|
"clip-path": "2021-01-21",
|
|
@@ -278,7 +280,7 @@
|
|
|
278
280
|
"input": "2015-07-29",
|
|
279
281
|
"input-button": "2015-07-29",
|
|
280
282
|
"input-checkbox": "2015-07-29",
|
|
281
|
-
"input-date-time": "2021-
|
|
283
|
+
"input-date-time": "2021-10-05",
|
|
282
284
|
"input-email-tel-url": "2015-07-29",
|
|
283
285
|
"input-event": "2020-01-15",
|
|
284
286
|
"input-file": "2015-07-29",
|
|
@@ -439,6 +441,7 @@
|
|
|
439
441
|
"promise-allsettled": "2020-07-28",
|
|
440
442
|
"promise-any": "2020-09-16",
|
|
441
443
|
"promise-finally": "2018-10-02",
|
|
444
|
+
"promise-withresolvers": "2024-03-05",
|
|
442
445
|
"proxy-reflect": "2016-09-20",
|
|
443
446
|
"push": "2023-03-27",
|
|
444
447
|
"q": "2015-07-29",
|
|
@@ -563,6 +566,7 @@
|
|
|
563
566
|
"title": "2015-07-29",
|
|
564
567
|
"title-attr": "2015-07-29",
|
|
565
568
|
"touch-action": "2019-09-19",
|
|
569
|
+
"transferable-arraybuffer": "2024-03-05",
|
|
566
570
|
"transforms2d": "2015-09-30",
|
|
567
571
|
"transforms3d": "2022-03-14",
|
|
568
572
|
"transitions": "2015-09-30",
|
|
@@ -594,6 +598,7 @@
|
|
|
594
598
|
"wasm-bigint": "2021-04-26",
|
|
595
599
|
"wasm-bulk-memory": "2021-10-25",
|
|
596
600
|
"wasm-exception-handling": "2022-05-03",
|
|
601
|
+
"wasm-extended-constant-expressions": "2024-03-05",
|
|
597
602
|
"wasm-multi-value": "2020-10-20",
|
|
598
603
|
"wasm-mutable-globals": "2020-03-24",
|
|
599
604
|
"wasm-non-trapping-float-to-int": "2021-10-25",
|
|
@@ -607,7 +612,7 @@
|
|
|
607
612
|
"weakset": "2015-09-30",
|
|
608
613
|
"web-animations": "2020-09-16",
|
|
609
614
|
"web-audio": "2021-04-26",
|
|
610
|
-
"web-cryptography": "
|
|
615
|
+
"web-cryptography": "2017-09-19",
|
|
611
616
|
"web-locks": "2022-03-14",
|
|
612
617
|
"webauthn": "2021-09-07",
|
|
613
618
|
"webauthn-public-key-easy": "2023-10-24",
|
|
@@ -648,15 +653,16 @@
|
|
|
648
653
|
"abs-sign": "2025-06-26",
|
|
649
654
|
"active-view-transition": "2026-01-13",
|
|
650
655
|
"align-content-block": "2024-04-16",
|
|
656
|
+
"alpha": "2026-09-14",
|
|
651
657
|
"alt-text-generated-content": "2024-07-09",
|
|
652
|
-
"array-group": "2024-03-05",
|
|
653
658
|
"async-clipboard": "2024-06-11",
|
|
659
|
+
"async-iterable-streams": "2026-09-14",
|
|
654
660
|
"atomics-pause": "2025-04-01",
|
|
655
661
|
"atomics-wait-async": "2025-11-11",
|
|
662
|
+
"autocorrect": "2026-09-11",
|
|
656
663
|
"backdrop-filter": "2024-09-16",
|
|
657
664
|
"baseline-shift": "2026-03-24",
|
|
658
665
|
"canvas-2d-willreadfrequently": "2024-09-16",
|
|
659
|
-
"check-visibility": "2024-03-05",
|
|
660
666
|
"clipboard-supports": "2025-03-31",
|
|
661
667
|
"composed-ranges": "2025-08-19",
|
|
662
668
|
"container-style-queries": "2026-05-19",
|
|
@@ -693,17 +699,19 @@
|
|
|
693
699
|
"json-raw": "2025-03-31",
|
|
694
700
|
"largest-contentful-paint": "2025-12-12",
|
|
695
701
|
"light-dark": "2024-05-13",
|
|
702
|
+
"light-dark-image": "2026-09-14",
|
|
696
703
|
"link-rel-dns-prefetch": "2025-09-15",
|
|
697
704
|
"math-sum-precise": "2026-04-10",
|
|
698
705
|
"navigation": "2026-01-13",
|
|
699
706
|
"open-pseudo": "2026-05-11",
|
|
707
|
+
"overflow-anchor": "2026-09-14",
|
|
700
708
|
"page-setup": "2024-12-11",
|
|
701
709
|
"paint-order": "2024-03-22",
|
|
702
710
|
"parse-html-unsafe": "2025-09-15",
|
|
703
711
|
"popover": "2025-01-27",
|
|
704
712
|
"print-color-adjust": "2025-05-01",
|
|
713
|
+
"progress-function": "2026-09-01",
|
|
705
714
|
"promise-try": "2025-01-07",
|
|
706
|
-
"promise-withresolvers": "2024-03-05",
|
|
707
715
|
"rcap": "2026-01-13",
|
|
708
716
|
"rch": "2026-01-13",
|
|
709
717
|
"readable-byte-streams": "2026-03-24",
|
|
@@ -741,7 +749,7 @@
|
|
|
741
749
|
"text-wrap": "2024-10-17",
|
|
742
750
|
"text-wrap-balance": "2024-05-13",
|
|
743
751
|
"toggleevent-source": "2026-05-11",
|
|
744
|
-
"
|
|
752
|
+
"top-level-await": "2026-09-14",
|
|
745
753
|
"transform-box": "2024-04-16",
|
|
746
754
|
"transition-behavior": "2024-08-06",
|
|
747
755
|
"trusted-types": "2026-02-24",
|
|
@@ -752,8 +760,8 @@
|
|
|
752
760
|
"view-transitions": "2025-10-14",
|
|
753
761
|
"wasm-branch-hinting": "2026-02-24",
|
|
754
762
|
"wasm-exnref-exceptions": "2025-05-29",
|
|
755
|
-
"wasm-extended-constant-expressions": "2024-03-05",
|
|
756
763
|
"wasm-garbage-collection": "2024-12-11",
|
|
764
|
+
"wasm-jspi": "2026-09-14",
|
|
757
765
|
"wasm-tail-call-optimization": "2024-12-11",
|
|
758
766
|
"wasm-typed-fun-refs": "2024-09-16",
|
|
759
767
|
"webgl-color-management": "2024-10-29",
|
|
@@ -770,7 +778,6 @@
|
|
|
770
778
|
"accessor-methods",
|
|
771
779
|
"ad-selection",
|
|
772
780
|
"alignment-baseline",
|
|
773
|
-
"alpha",
|
|
774
781
|
"alternative-style-sheets",
|
|
775
782
|
"ambient-light",
|
|
776
783
|
"anchor-positioning",
|
|
@@ -785,7 +792,6 @@
|
|
|
785
792
|
"app-shortcuts",
|
|
786
793
|
"arguments-callee",
|
|
787
794
|
"arianotify",
|
|
788
|
-
"async-iterable-streams",
|
|
789
795
|
"attr",
|
|
790
796
|
"attribution-reporting",
|
|
791
797
|
"audio-session",
|
|
@@ -793,7 +799,6 @@
|
|
|
793
799
|
"audiolistener",
|
|
794
800
|
"audiolistener-setposition-setorientation",
|
|
795
801
|
"autocapitalize",
|
|
796
|
-
"autocorrect",
|
|
797
802
|
"autofill",
|
|
798
803
|
"background-attachment",
|
|
799
804
|
"background-clip-border-area",
|
|
@@ -839,10 +844,12 @@
|
|
|
839
844
|
"contact-picker",
|
|
840
845
|
"container-anchor-position-queries",
|
|
841
846
|
"container-scroll-state-queries",
|
|
847
|
+
"container-timing",
|
|
842
848
|
"content-index",
|
|
843
849
|
"context-fill-stroke",
|
|
844
850
|
"controls-list",
|
|
845
851
|
"cookie-store",
|
|
852
|
+
"cookie-store-get-metadata",
|
|
846
853
|
"corner-shape",
|
|
847
854
|
"counter-reset-reversed",
|
|
848
855
|
"cross-document-view-transitions",
|
|
@@ -922,10 +929,12 @@
|
|
|
922
929
|
"gamepad-vr",
|
|
923
930
|
"gap-decorations",
|
|
924
931
|
"geolocation-element",
|
|
932
|
+
"geolocation-element-initialpermissionstatus",
|
|
925
933
|
"getallrecords",
|
|
926
934
|
"getboxquads",
|
|
927
935
|
"glyph-orientation-vertical",
|
|
928
936
|
"gpc",
|
|
937
|
+
"grid-lanes",
|
|
929
938
|
"gyroscope",
|
|
930
939
|
"hanging-punctuation",
|
|
931
940
|
"has-slotted",
|
|
@@ -936,6 +945,8 @@
|
|
|
936
945
|
"host-context",
|
|
937
946
|
"html-media-capture",
|
|
938
947
|
"html-processing-instructions",
|
|
948
|
+
"html-setters",
|
|
949
|
+
"html-streaming-setters",
|
|
939
950
|
"html-wrapper-methods",
|
|
940
951
|
"hyphenate-limit-chars",
|
|
941
952
|
"idle-detection",
|
|
@@ -944,10 +955,14 @@
|
|
|
944
955
|
"image-function",
|
|
945
956
|
"ime-mode",
|
|
946
957
|
"import-assertions",
|
|
958
|
+
"import-defer",
|
|
959
|
+
"import-maps-multiple",
|
|
947
960
|
"initial-letter",
|
|
948
961
|
"ink",
|
|
949
962
|
"input-color",
|
|
950
963
|
"input-color-alpha",
|
|
964
|
+
"input-date-time-month",
|
|
965
|
+
"input-date-time-week",
|
|
951
966
|
"insertable-streams",
|
|
952
967
|
"install",
|
|
953
968
|
"interaction-contentful-paint",
|
|
@@ -966,8 +981,8 @@
|
|
|
966
981
|
"languagedetector",
|
|
967
982
|
"languagemodel",
|
|
968
983
|
"layout-instability",
|
|
969
|
-
"light-dark-image",
|
|
970
984
|
"line-clamp",
|
|
985
|
+
"link-parameters",
|
|
971
986
|
"link-rel-expect",
|
|
972
987
|
"link-rel-prefetch",
|
|
973
988
|
"loading-lazy-media",
|
|
@@ -982,7 +997,6 @@
|
|
|
982
997
|
"margin-trim",
|
|
983
998
|
"marker",
|
|
984
999
|
"mask-border",
|
|
985
|
-
"masonry",
|
|
986
1000
|
"mathml-full",
|
|
987
1001
|
"measure-memory",
|
|
988
1002
|
"media-pseudos",
|
|
@@ -1007,7 +1021,6 @@
|
|
|
1007
1021
|
"opaquerange",
|
|
1008
1022
|
"orientation-sensor",
|
|
1009
1023
|
"origin",
|
|
1010
|
-
"overflow-anchor",
|
|
1011
1024
|
"overflow-clip-margin",
|
|
1012
1025
|
"overflow-overlay",
|
|
1013
1026
|
"overlay",
|
|
@@ -1038,7 +1051,6 @@
|
|
|
1038
1051
|
"private-click-measurement",
|
|
1039
1052
|
"private-network-access",
|
|
1040
1053
|
"profiler",
|
|
1041
|
-
"progress-function",
|
|
1042
1054
|
"protected-audience",
|
|
1043
1055
|
"proto",
|
|
1044
1056
|
"random-function",
|
|
@@ -1086,6 +1098,7 @@
|
|
|
1086
1098
|
"share",
|
|
1087
1099
|
"shared-storage",
|
|
1088
1100
|
"shared-storage-locks",
|
|
1101
|
+
"shared-workers-extended-lifetime",
|
|
1089
1102
|
"show-picker-input",
|
|
1090
1103
|
"show-picker-select",
|
|
1091
1104
|
"signature-based-resource-integrity",
|
|
@@ -1120,7 +1133,6 @@
|
|
|
1120
1133
|
"text-spacing-trim",
|
|
1121
1134
|
"text-wrap-pretty",
|
|
1122
1135
|
"time-relative-selectors",
|
|
1123
|
-
"top-level-await",
|
|
1124
1136
|
"topics",
|
|
1125
1137
|
"touch-events",
|
|
1126
1138
|
"transferable-streams",
|
|
@@ -1139,7 +1151,6 @@
|
|
|
1139
1151
|
"virtual-keyboard",
|
|
1140
1152
|
"virtual-pressure-sources",
|
|
1141
1153
|
"virtual-sensors",
|
|
1142
|
-
"wasm-jspi",
|
|
1143
1154
|
"wasm-memory64",
|
|
1144
1155
|
"wasm-multi-memory",
|
|
1145
1156
|
"wasm-simd-relaxed",
|
package/core/user-flow.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export class UserFlow {
|
|
|
13
13
|
_gatherSteps: LH.UserFlow.GatherStep[];
|
|
14
14
|
/** @type {GatherStepRunnerOptions} */
|
|
15
15
|
_gatherStepRunnerOptions: GatherStepRunnerOptions;
|
|
16
|
+
/** @type {AbortController} */
|
|
17
|
+
_controller: AbortController;
|
|
18
|
+
dispose(): void;
|
|
16
19
|
/**
|
|
17
20
|
* @param {LH.UserFlow.StepFlags|undefined} flags
|
|
18
21
|
* @return {LH.UserFlow.StepFlags|undefined}
|
package/core/user-flow.js
CHANGED
|
@@ -66,6 +66,16 @@ class UserFlow {
|
|
|
66
66
|
this._gatherSteps = [];
|
|
67
67
|
/** @type {GatherStepRunnerOptions} */
|
|
68
68
|
this._gatherStepRunnerOptions = new WeakMap();
|
|
69
|
+
/** @type {AbortController} */
|
|
70
|
+
this._controller = new AbortController();
|
|
71
|
+
|
|
72
|
+
page.on('close', () => {
|
|
73
|
+
this.dispose();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
dispose() {
|
|
78
|
+
this._controller.abort();
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
/**
|
|
@@ -131,6 +141,7 @@ class UserFlow {
|
|
|
131
141
|
const gatherResult = await navigationGather(this._page, requestor, {
|
|
132
142
|
config: this._options?.config,
|
|
133
143
|
flags: nextFlags,
|
|
144
|
+
signal: this._controller.signal,
|
|
134
145
|
});
|
|
135
146
|
|
|
136
147
|
this._addGatherStep(gatherResult, nextFlags);
|
|
@@ -162,6 +173,7 @@ class UserFlow {
|
|
|
162
173
|
() => new Promise(continueNavigation => completeSetup(continueNavigation)),
|
|
163
174
|
stepOptions
|
|
164
175
|
).catch(err => {
|
|
176
|
+
if (this._controller.signal.aborted) return;
|
|
165
177
|
if (this.currentNavigation) {
|
|
166
178
|
// If the navigation already started, re-throw the error so it is emitted when `navigationResultPromise` is awaited.
|
|
167
179
|
throw err;
|