browser-debugger-cli 0.8.0 → 0.9.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/README.md +4 -1
- package/dist/cdp/schema.d.ts +4 -1
- package/dist/cdp/schema.js +48 -7
- package/dist/commands/cdp.js +3 -2
- package/dist/commands/cleanup.d.ts +11 -0
- package/dist/commands/cleanup.js +161 -57
- package/dist/commands/console.d.ts +20 -1
- package/dist/commands/console.js +57 -17
- package/dist/commands/details.js +3 -2
- package/dist/commands/dom/DomElementResolver.d.ts +10 -3
- package/dist/commands/dom/DomElementResolver.js +35 -17
- package/dist/commands/dom/a11y.d.ts +10 -0
- package/dist/commands/dom/a11y.js +27 -5
- package/dist/commands/dom/eval.d.ts +3 -1
- package/dist/commands/dom/eval.js +29 -4
- package/dist/commands/dom/form.js +16 -62
- package/dist/commands/dom/formInteraction.js +152 -113
- package/dist/commands/dom/formSummary.d.ts +49 -0
- package/dist/commands/dom/formSummary.js +180 -0
- package/dist/commands/dom/frames.d.ts +2 -1
- package/dist/commands/dom/frames.js +17 -2
- package/dist/commands/dom/get.d.ts +6 -5
- package/dist/commands/dom/get.js +92 -82
- package/dist/commands/dom/helpers/index.d.ts +1 -1
- package/dist/commands/dom/helpers/index.js +1 -1
- package/dist/commands/dom/helpers/query.d.ts +44 -17
- package/dist/commands/dom/helpers/query.js +244 -97
- package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
- package/dist/commands/dom/helpers/runElementCommand.js +97 -30
- package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
- package/dist/commands/dom/helpers/screenshot.js +164 -49
- package/dist/commands/dom/index.d.ts +3 -1
- package/dist/commands/dom/index.js +16 -6
- package/dist/commands/dom/layout.d.ts +14 -0
- package/dist/commands/dom/layout.js +54 -0
- package/dist/commands/dom/listeners.d.ts +5 -1
- package/dist/commands/dom/listeners.js +13 -3
- package/dist/commands/dom/query.js +2 -3
- package/dist/commands/dom/screenshot.d.ts +12 -2
- package/dist/commands/dom/screenshot.js +27 -3
- package/dist/commands/dom/semanticUtils.d.ts +6 -13
- package/dist/commands/dom/semanticUtils.js +15 -19
- package/dist/commands/dom/wait.d.ts +13 -0
- package/dist/commands/dom/wait.js +83 -0
- package/dist/commands/helpJson.js +2 -2
- package/dist/commands/network/list.js +4 -11
- package/dist/commands/optionBehaviors.js +112 -21
- package/dist/commands/page.d.ts +2 -1
- package/dist/commands/page.js +41 -5
- package/dist/commands/peek.js +4 -11
- package/dist/commands/sessions.d.ts +8 -0
- package/dist/commands/sessions.js +19 -0
- package/dist/commands/shared/CommandRunner.js +4 -4
- package/dist/commands/shared/dataFetcher.js +2 -2
- package/dist/commands/shared/followMode.d.ts +21 -1
- package/dist/commands/shared/followMode.js +29 -2
- package/dist/commands/shared/handleValidationError.d.ts +2 -2
- package/dist/commands/shared/handleValidationError.js +12 -3
- package/dist/commands/shared/optionTypes.d.ts +40 -5
- package/dist/commands/shared/startHelpers.js +12 -3
- package/dist/commands/shared/validation.d.ts +3 -2
- package/dist/commands/shared/validation.js +4 -3
- package/dist/commands/start.d.ts +63 -0
- package/dist/commands/start.js +115 -15
- package/dist/commands/status.js +29 -7
- package/dist/commands/stop.js +7 -6
- package/dist/commands/tail.js +4 -11
- package/dist/commands/types.d.ts +2 -0
- package/dist/commands.js +2 -0
- package/dist/connection/chromeIdentity.d.ts +65 -0
- package/dist/connection/chromeIdentity.js +143 -0
- package/dist/connection/launcher/profilePreferences.d.ts +47 -0
- package/dist/connection/launcher/profilePreferences.js +151 -0
- package/dist/connection/launcher.d.ts +21 -2
- package/dist/connection/launcher.js +42 -16
- package/dist/connection/portReservation.d.ts +14 -4
- package/dist/connection/portReservation.js +21 -6
- package/dist/connection/startupExit.d.ts +8 -0
- package/dist/connection/startupExit.js +15 -6
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +9 -2
- package/dist/daemon/SessionController.js +23 -7
- package/dist/daemon/errors.d.ts +1 -1
- package/dist/daemon/errors.js +1 -1
- package/dist/daemon/launcher.d.ts +2 -1
- package/dist/daemon/launcher.js +5 -6
- package/dist/daemon/server/SocketServer.js +1 -2
- package/dist/daemon/session/Session.d.ts +13 -0
- package/dist/daemon/session/Session.js +57 -8
- package/dist/daemon/session/chromeConnection.d.ts +9 -0
- package/dist/daemon/session/chromeConnection.js +45 -8
- package/dist/daemon/session/commandRegistry.js +52 -62
- package/dist/daemon/session/interactions.d.ts +35 -9
- package/dist/daemon/session/interactions.js +36 -9
- package/dist/daemon/session/triggeredRequests.d.ts +67 -0
- package/dist/daemon/session/triggeredRequests.js +157 -0
- package/dist/daemon/session/types.d.ts +5 -1
- package/dist/daemon.js +5393 -1600
- package/dist/errors/messages.d.ts +387 -24
- package/dist/errors/messages.js +761 -67
- package/dist/index.js +3976 -1558
- package/dist/ipc/client.d.ts +12 -1
- package/dist/ipc/client.js +22 -3
- package/dist/ipc/protocol/commands.d.ts +89 -4
- package/dist/ipc/protocol/commands.js +2 -0
- package/dist/ipc/protocol/domTypes.d.ts +258 -7
- package/dist/ipc/session/lifecycle.d.ts +8 -1
- package/dist/ipc/session/queries.d.ts +5 -1
- package/dist/ipc/session/types.d.ts +5 -0
- package/dist/ipc/transport/index.d.ts +2 -1
- package/dist/ipc/transport/index.js +2 -2
- package/dist/runtime/dom/actionEffects.d.ts +106 -0
- package/dist/runtime/dom/actionEffects.js +256 -0
- package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -0
- package/dist/runtime/dom/actionEffectsScripts.js +234 -0
- package/dist/runtime/dom/elementGeometry.d.ts +170 -0
- package/dist/runtime/dom/elementGeometry.js +553 -0
- package/dist/runtime/dom/elementInfo.d.ts +77 -0
- package/dist/runtime/dom/elementInfo.js +191 -0
- package/dist/runtime/dom/evalHelpers.d.ts +51 -6
- package/dist/runtime/dom/evalHelpers.js +136 -26
- package/dist/runtime/dom/eventListeners.d.ts +2 -1
- package/dist/runtime/dom/eventListeners.js +174 -47
- package/dist/runtime/dom/formDiscovery.d.ts +1 -1
- package/dist/runtime/dom/formDiscovery.js +116 -16
- package/dist/runtime/dom/formFillHelpers/fill.d.ts +10 -0
- package/dist/runtime/dom/formFillHelpers/fill.js +125 -10
- package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
- package/dist/runtime/dom/formFillHelpers/index.js +2 -2
- package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
- package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
- package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
- package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
- package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
- package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
- package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
- package/dist/runtime/dom/formSubmitHelpers.js +89 -15
- package/dist/runtime/dom/frameLayout.d.ts +60 -0
- package/dist/runtime/dom/frameLayout.js +140 -0
- package/dist/runtime/dom/frameOrigin.d.ts +50 -0
- package/dist/runtime/dom/frameOrigin.js +62 -0
- package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
- package/dist/runtime/dom/frameScopedConnection.js +252 -0
- package/dist/runtime/dom/frameSelection.d.ts +1 -1
- package/dist/runtime/dom/frameSelection.js +2 -2
- package/dist/runtime/dom/frames.d.ts +25 -2
- package/dist/runtime/dom/frames.js +202 -63
- package/dist/runtime/dom/layout.d.ts +67 -0
- package/dist/runtime/dom/layout.js +333 -0
- package/dist/runtime/dom/listenerPageScripts.d.ts +66 -0
- package/dist/runtime/dom/listenerPageScripts.js +279 -0
- package/dist/runtime/dom/listenerSummary.d.ts +132 -11
- package/dist/runtime/dom/listenerSummary.js +344 -22
- package/dist/runtime/dom/pageActivity.d.ts +41 -0
- package/dist/runtime/dom/pageActivity.js +123 -0
- package/dist/runtime/dom/reactEventHelpers.d.ts +58 -2
- package/dist/runtime/dom/reactEventHelpers.js +212 -41
- package/dist/runtime/dom/targetNode.d.ts +80 -27
- package/dist/runtime/dom/targetNode.js +249 -33
- package/dist/runtime/dom/wait.d.ts +25 -0
- package/dist/runtime/dom/wait.js +199 -0
- package/dist/runtime/dom/waitCondition.d.ts +71 -0
- package/dist/runtime/dom/waitCondition.js +75 -0
- package/dist/runtime/page/emulation.d.ts +51 -0
- package/dist/runtime/page/emulation.js +80 -0
- package/dist/runtime/page/loadingState.d.ts +36 -0
- package/dist/runtime/page/loadingState.js +86 -0
- package/dist/runtime/page/navigation.d.ts +46 -2
- package/dist/runtime/page/navigation.js +69 -33
- package/dist/session/QueryCacheManager.d.ts +11 -1
- package/dist/session/QueryCacheManager.js +25 -3
- package/dist/session/chromeOwners.d.ts +34 -0
- package/dist/session/chromeOwners.js +51 -0
- package/dist/session/cleanup/staleSession.d.ts +11 -1
- package/dist/session/cleanup/staleSession.js +17 -6
- package/dist/session/cleanup/userCommands.js +2 -4
- package/dist/session/metadata.d.ts +5 -1
- package/dist/session/metadata.js +2 -1
- package/dist/session/paths.d.ts +77 -3
- package/dist/session/paths.js +111 -5
- package/dist/session/port.d.ts +31 -7
- package/dist/session/port.js +50 -43
- package/dist/session/portClaims.d.ts +66 -0
- package/dist/session/portClaims.js +284 -0
- package/dist/session/sessionList.d.ts +58 -0
- package/dist/session/sessionList.js +199 -0
- package/dist/session/sessionName.d.ts +46 -0
- package/dist/session/sessionName.js +97 -0
- package/dist/telemetry/a11y.d.ts +8 -3
- package/dist/telemetry/a11y.js +92 -28
- package/dist/telemetry/requestKinds.d.ts +32 -0
- package/dist/telemetry/requestKinds.js +61 -0
- package/dist/telemetry/requestState.d.ts +31 -0
- package/dist/telemetry/requestState.js +38 -0
- package/dist/types.d.ts +80 -3
- package/dist/ui/formatters/a11y.js +3 -0
- package/dist/ui/formatters/console/chronological.d.ts +8 -0
- package/dist/ui/formatters/console/chronological.js +17 -4
- package/dist/ui/formatters/console/json.js +3 -4
- package/dist/ui/formatters/console/shared.d.ts +12 -0
- package/dist/ui/formatters/console.d.ts +2 -2
- package/dist/ui/formatters/console.js +1 -1
- package/dist/ui/formatters/details.js +2 -1
- package/dist/ui/formatters/dom.d.ts +26 -14
- package/dist/ui/formatters/dom.js +65 -52
- package/dist/ui/formatters/form.js +29 -18
- package/dist/ui/formatters/layout.d.ts +31 -0
- package/dist/ui/formatters/layout.js +53 -0
- package/dist/ui/formatters/listeners.d.ts +3 -2
- package/dist/ui/formatters/listeners.js +73 -9
- package/dist/ui/formatters/networkHeaders.js +13 -0
- package/dist/ui/formatters/preview.js +2 -1
- package/dist/ui/formatters/requestStatus.d.ts +1 -17
- package/dist/ui/formatters/requestStatus.js +2 -30
- package/dist/ui/formatters/sessions.d.ts +12 -0
- package/dist/ui/formatters/sessions.js +40 -0
- package/dist/ui/formatters/status.d.ts +21 -2
- package/dist/ui/formatters/status.js +47 -10
- package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
- package/dist/ui/formatters/triggeredRequests.js +65 -0
- package/dist/ui/formatting.d.ts +10 -0
- package/dist/ui/formatting.js +28 -36
- package/dist/ui/messages/chrome.d.ts +9 -0
- package/dist/ui/messages/chrome.js +17 -5
- package/dist/ui/messages/commands.d.ts +388 -14
- package/dist/ui/messages/commands.js +664 -21
- package/dist/ui/messages/consoleMessages.d.ts +10 -0
- package/dist/ui/messages/consoleMessages.js +17 -0
- package/dist/ui/messages/hints.js +2 -1
- package/dist/ui/messages/preview.js +5 -4
- package/dist/ui/messages/session.d.ts +16 -21
- package/dist/ui/messages/session.js +28 -26
- package/dist/ui/messages/sessionCommand.d.ts +43 -0
- package/dist/ui/messages/sessionCommand.js +52 -0
- package/dist/utils/async.d.ts +8 -0
- package/dist/utils/async.js +19 -0
- package/dist/utils/http.d.ts +22 -1
- package/dist/utils/http.js +28 -9
- package/dist/utils/selectorFilters.d.ts +36 -8
- package/dist/utils/selectorFilters.js +267 -53
- package/dist/utils/shellDetection.d.ts +8 -2
- package/dist/utils/shellDetection.js +120 -33
- package/dist/utils/suggestions.d.ts +26 -0
- package/dist/utils/suggestions.js +73 -0
- package/dist/utils/taskMappings.js +10 -0
- package/dist/utils/url.d.ts +12 -2
- package/dist/utils/url.js +69 -7
- package/package.json +1 -1
- package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
- package/dist/ui/formatters/sessionFormatters.js +0 -121
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `bdg dom wait` waits for, and whether what the page shows meets it.
|
|
3
|
+
*
|
|
4
|
+
* The page reports a {@link WaitSnapshot} whenever it changes; the condition
|
|
5
|
+
* is decided here, in one place.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The text as the page compares it: whitespace collapsed, lower case (like `:has-text`).
|
|
9
|
+
*
|
|
10
|
+
* @param text - Text as given
|
|
11
|
+
* @returns Normalized text
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeWaitText(text) {
|
|
14
|
+
return text.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The matches the condition counts: visible ones with `visible`, else those
|
|
18
|
+
* containing the text (all matches without a text).
|
|
19
|
+
*
|
|
20
|
+
* @param snapshot - What the page shows
|
|
21
|
+
* @param condition - What is waited for
|
|
22
|
+
* @returns Number of counted matches
|
|
23
|
+
*/
|
|
24
|
+
export function countedMatches(snapshot, condition) {
|
|
25
|
+
return condition.visible ? snapshot.visibleCount : snapshot.textCount;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether the page shows what is waited for.
|
|
29
|
+
*
|
|
30
|
+
* Elements are gone only when two consecutive snapshots of the same
|
|
31
|
+
* document, neither of it still `loading`, show none: right after a
|
|
32
|
+
* navigation commits, the new document is empty for a moment.
|
|
33
|
+
*
|
|
34
|
+
* @param snapshot - What the page shows
|
|
35
|
+
* @param condition - What is waited for
|
|
36
|
+
* @param previous - The snapshot before it, if any
|
|
37
|
+
* @returns True when the elements are there (or gone with `gone`) and, with `load`, the page loaded
|
|
38
|
+
*/
|
|
39
|
+
export function isWaitConditionMet(snapshot, condition, previous) {
|
|
40
|
+
if (condition.load && snapshot.readyState !== 'complete')
|
|
41
|
+
return false;
|
|
42
|
+
if (condition.selector === undefined)
|
|
43
|
+
return true;
|
|
44
|
+
if (!condition.gone)
|
|
45
|
+
return countedMatches(snapshot, condition) > 0;
|
|
46
|
+
if (previous?.documentId !== snapshot.documentId)
|
|
47
|
+
return false;
|
|
48
|
+
return showsNoneSettled(previous, condition) && showsNoneSettled(snapshot, condition);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Whether a `--gone` wait should confirm this snapshot with another one: it
|
|
52
|
+
* shows no (counted) matches in a document past `loading`.
|
|
53
|
+
*
|
|
54
|
+
* @param snapshot - What the page shows
|
|
55
|
+
* @param condition - What is waited for
|
|
56
|
+
* @returns True when one more snapshot of the same document may meet the condition
|
|
57
|
+
*/
|
|
58
|
+
export function needsGoneConfirmation(snapshot, condition) {
|
|
59
|
+
if (!condition.gone || condition.selector === undefined)
|
|
60
|
+
return false;
|
|
61
|
+
if (condition.load && snapshot.readyState !== 'complete')
|
|
62
|
+
return false;
|
|
63
|
+
return showsNoneSettled(snapshot, condition);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* No counted matches, in a document that is no longer `loading`.
|
|
67
|
+
*
|
|
68
|
+
* @param snapshot - What the page shows
|
|
69
|
+
* @param condition - What is waited for
|
|
70
|
+
* @returns True when nothing counted matches in a settled document
|
|
71
|
+
*/
|
|
72
|
+
function showsNoneSettled(snapshot, condition) {
|
|
73
|
+
return snapshot.readyState !== 'loading' && countedMatches(snapshot, condition) === 0;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=waitCondition.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page emulation a session was started with: the viewport size
|
|
3
|
+
* (`--viewport`) and `prefers-color-scheme` (`--color-scheme`).
|
|
4
|
+
*
|
|
5
|
+
* The overrides belong to the session's CDP connection: they last across
|
|
6
|
+
* navigations and reloads, and Chrome drops them when the session ends, so
|
|
7
|
+
* an attached Chrome (`--chrome-ws-url`) gets its own settings back.
|
|
8
|
+
*/
|
|
9
|
+
import type { CDPConnection } from '../../connection/cdp.js';
|
|
10
|
+
import type { ColorScheme, ViewportSize } from '../../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* `Emulation.setDeviceMetricsOverride` parameters for a session viewport: a
|
|
13
|
+
* desktop viewport of that size at the display's own pixel ratio.
|
|
14
|
+
*
|
|
15
|
+
* @param viewport - Viewport size in CSS px
|
|
16
|
+
* @param deviceScaleFactor - Pixel ratio (0 keeps the display's)
|
|
17
|
+
* @returns CDP parameters
|
|
18
|
+
*/
|
|
19
|
+
export declare function viewportOverride(viewport: ViewportSize, deviceScaleFactor?: number): {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
deviceScaleFactor: number;
|
|
23
|
+
mobile: false;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Apply the session's emulation to its page.
|
|
27
|
+
*
|
|
28
|
+
* @param cdp - Session connection
|
|
29
|
+
* @param emulation - Viewport and color scheme, when given at start
|
|
30
|
+
*/
|
|
31
|
+
export declare function applySessionEmulation(cdp: CDPConnection, emulation: {
|
|
32
|
+
viewport?: ViewportSize;
|
|
33
|
+
colorScheme?: ColorScheme;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
/** What the page currently renders with, for `bdg status` */
|
|
36
|
+
export interface PageAppearance {
|
|
37
|
+
/** Layout viewport without scrollbars (as `dom layout` reports it) */
|
|
38
|
+
viewport?: ViewportSize;
|
|
39
|
+
/** `prefers-color-scheme` the page sees */
|
|
40
|
+
colorScheme?: ColorScheme;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The viewport and color scheme the page renders with. A busy page (or one
|
|
44
|
+
* still navigating) does not answer within {@link APPEARANCE_TIMEOUT_MS}; then
|
|
45
|
+
* nothing is reported rather than holding up `bdg status`.
|
|
46
|
+
*
|
|
47
|
+
* @param cdp - Session connection
|
|
48
|
+
* @returns Viewport and color scheme, or nothing
|
|
49
|
+
*/
|
|
50
|
+
export declare function pageAppearance(cdp: CDPConnection): Promise<PageAppearance>;
|
|
51
|
+
//# sourceMappingURL=emulation.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page emulation a session was started with: the viewport size
|
|
3
|
+
* (`--viewport`) and `prefers-color-scheme` (`--color-scheme`).
|
|
4
|
+
*
|
|
5
|
+
* The overrides belong to the session's CDP connection: they last across
|
|
6
|
+
* navigations and reloads, and Chrome drops them when the session ends, so
|
|
7
|
+
* an attached Chrome (`--chrome-ws-url`) gets its own settings back.
|
|
8
|
+
*/
|
|
9
|
+
import { VIEWPORT_SIZE_JS } from '../dom/elementGeometry.js';
|
|
10
|
+
import { createLogger } from '../../ui/logging/index.js';
|
|
11
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
12
|
+
const log = createLogger('session');
|
|
13
|
+
/**
|
|
14
|
+
* `Emulation.setDeviceMetricsOverride` parameters for a session viewport: a
|
|
15
|
+
* desktop viewport of that size at the display's own pixel ratio.
|
|
16
|
+
*
|
|
17
|
+
* @param viewport - Viewport size in CSS px
|
|
18
|
+
* @param deviceScaleFactor - Pixel ratio (0 keeps the display's)
|
|
19
|
+
* @returns CDP parameters
|
|
20
|
+
*/
|
|
21
|
+
export function viewportOverride(viewport, deviceScaleFactor = 0) {
|
|
22
|
+
return { width: viewport.width, height: viewport.height, deviceScaleFactor, mobile: false };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Apply the session's emulation to its page.
|
|
26
|
+
*
|
|
27
|
+
* @param cdp - Session connection
|
|
28
|
+
* @param emulation - Viewport and color scheme, when given at start
|
|
29
|
+
*/
|
|
30
|
+
export async function applySessionEmulation(cdp, emulation) {
|
|
31
|
+
if (emulation.viewport) {
|
|
32
|
+
await cdp.send('Emulation.setDeviceMetricsOverride', viewportOverride(emulation.viewport));
|
|
33
|
+
}
|
|
34
|
+
if (emulation.colorScheme) {
|
|
35
|
+
await cdp.send('Emulation.setEmulatedMedia', {
|
|
36
|
+
features: [{ name: 'prefers-color-scheme', value: emulation.colorScheme }],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** How long `bdg status` waits for the page to report its appearance */
|
|
41
|
+
const APPEARANCE_TIMEOUT_MS = 1000;
|
|
42
|
+
/**
|
|
43
|
+
* The viewport and color scheme the page renders with. A busy page (or one
|
|
44
|
+
* still navigating) does not answer within {@link APPEARANCE_TIMEOUT_MS}; then
|
|
45
|
+
* nothing is reported rather than holding up `bdg status`.
|
|
46
|
+
*
|
|
47
|
+
* @param cdp - Session connection
|
|
48
|
+
* @returns Viewport and color scheme, or nothing
|
|
49
|
+
*/
|
|
50
|
+
export async function pageAppearance(cdp) {
|
|
51
|
+
const expression = `(() => {
|
|
52
|
+
const size = (${VIEWPORT_SIZE_JS})(window);
|
|
53
|
+
return { width: Math.round(size.width), height: Math.round(size.height), dark: matchMedia('(prefers-color-scheme: dark)').matches };
|
|
54
|
+
})()`;
|
|
55
|
+
let timer;
|
|
56
|
+
const timeout = new Promise((resolve) => {
|
|
57
|
+
timer = setTimeout(() => resolve(null), APPEARANCE_TIMEOUT_MS);
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const response = (await Promise.race([
|
|
61
|
+
cdp.send('Runtime.evaluate', { expression, returnByValue: true }),
|
|
62
|
+
timeout,
|
|
63
|
+
]));
|
|
64
|
+
const value = response?.result?.value;
|
|
65
|
+
if (!value)
|
|
66
|
+
return {};
|
|
67
|
+
return {
|
|
68
|
+
viewport: { width: value.width, height: value.height },
|
|
69
|
+
colorScheme: value.dark ? 'dark' : 'light',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
log.debug(`Could not read the page's viewport and color scheme: ${getErrorMessage(error)}`);
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=emulation.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the page finished loading, and what it is still waiting for.
|
|
3
|
+
*
|
|
4
|
+
* Start and `bdg page` wait a limited time for the page; a document still
|
|
5
|
+
* `loading` after that (a script whose server never answers) makes every
|
|
6
|
+
* later command misleading, so they report it with the requests still
|
|
7
|
+
* running.
|
|
8
|
+
*/
|
|
9
|
+
import type { PendingRequestInfo, PageLoadingState } from '../../ipc/protocol/commands.js';
|
|
10
|
+
import type { PendingRequest } from '../../telemetry/network.js';
|
|
11
|
+
import type { CDPSender } from '../../telemetry/objectExpander.js';
|
|
12
|
+
/**
|
|
13
|
+
* The requests to name: load-blocking ones (scripts, styles, images, frames)
|
|
14
|
+
* first, the longest-running first within each group.
|
|
15
|
+
*
|
|
16
|
+
* @param pending - Requests still running
|
|
17
|
+
* @param now - Current time (ms)
|
|
18
|
+
* @returns Up to {@link MAX_NAMED_PENDING_REQUESTS} requests
|
|
19
|
+
*/
|
|
20
|
+
export declare function summarizePendingRequests(pending: Iterable<PendingRequest>, now: number): PendingRequestInfo[];
|
|
21
|
+
/**
|
|
22
|
+
* The page's `document.readyState`.
|
|
23
|
+
*
|
|
24
|
+
* @param cdp - CDP connection
|
|
25
|
+
* @returns The state, or undefined when the page did not answer in time
|
|
26
|
+
*/
|
|
27
|
+
export declare function readDocumentReadyState(cdp: CDPSender): Promise<string | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* What the page is still loading, if it has not finished.
|
|
30
|
+
*
|
|
31
|
+
* @param cdp - CDP connection
|
|
32
|
+
* @param pending - Requests still running (from the session's network telemetry)
|
|
33
|
+
* @returns The loading state, or undefined when the document is complete or did not answer
|
|
34
|
+
*/
|
|
35
|
+
export declare function readPageLoadingState(cdp: CDPSender, pending: Iterable<PendingRequest>): Promise<PageLoadingState | undefined>;
|
|
36
|
+
//# sourceMappingURL=loadingState.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the page finished loading, and what it is still waiting for.
|
|
3
|
+
*
|
|
4
|
+
* Start and `bdg page` wait a limited time for the page; a document still
|
|
5
|
+
* `loading` after that (a script whose server never answers) makes every
|
|
6
|
+
* later command misleading, so they report it with the requests still
|
|
7
|
+
* running.
|
|
8
|
+
*/
|
|
9
|
+
import { createLogger } from '../../ui/logging/index.js';
|
|
10
|
+
import { raceTimeout } from '../../utils/async.js';
|
|
11
|
+
import { getErrorMessage } from '../../utils/errors.js';
|
|
12
|
+
const log = createLogger('readiness');
|
|
13
|
+
/** Pending requests named in the report */
|
|
14
|
+
const MAX_NAMED_PENDING_REQUESTS = 3;
|
|
15
|
+
/** How long the page gets to report its readyState (a busy page is not waited on) */
|
|
16
|
+
const READY_STATE_TIMEOUT_MS = 1000;
|
|
17
|
+
/** Request types that never hold up the load event, listed after the ones that do */
|
|
18
|
+
const NON_BLOCKING_TYPES = new Set([
|
|
19
|
+
'XHR',
|
|
20
|
+
'Fetch',
|
|
21
|
+
'EventSource',
|
|
22
|
+
'Ping',
|
|
23
|
+
'Preflight',
|
|
24
|
+
'Prefetch',
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* The requests to name: load-blocking ones (scripts, styles, images, frames)
|
|
28
|
+
* first, the longest-running first within each group.
|
|
29
|
+
*
|
|
30
|
+
* @param pending - Requests still running
|
|
31
|
+
* @param now - Current time (ms)
|
|
32
|
+
* @returns Up to {@link MAX_NAMED_PENDING_REQUESTS} requests
|
|
33
|
+
*/
|
|
34
|
+
export function summarizePendingRequests(pending, now) {
|
|
35
|
+
const rank = (entry) => NON_BLOCKING_TYPES.has(entry.request.resourceType ?? '') ? 1 : 0;
|
|
36
|
+
return [...pending]
|
|
37
|
+
.sort((a, b) => rank(a) - rank(b) || a.request.timestamp - b.request.timestamp)
|
|
38
|
+
.slice(0, MAX_NAMED_PENDING_REQUESTS)
|
|
39
|
+
.map(({ request }) => ({
|
|
40
|
+
method: request.method,
|
|
41
|
+
url: request.url,
|
|
42
|
+
...(request.resourceType && { resourceType: request.resourceType }),
|
|
43
|
+
pendingMs: Math.max(0, now - request.timestamp),
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The page's `document.readyState`.
|
|
48
|
+
*
|
|
49
|
+
* @param cdp - CDP connection
|
|
50
|
+
* @returns The state, or undefined when the page did not answer in time
|
|
51
|
+
*/
|
|
52
|
+
export async function readDocumentReadyState(cdp) {
|
|
53
|
+
try {
|
|
54
|
+
const evaluated = cdp.send('Runtime.evaluate', {
|
|
55
|
+
expression: 'document.readyState',
|
|
56
|
+
returnByValue: true,
|
|
57
|
+
});
|
|
58
|
+
evaluated.catch(() => undefined);
|
|
59
|
+
const response = await raceTimeout(evaluated, READY_STATE_TIMEOUT_MS);
|
|
60
|
+
const value = response?.result?.value;
|
|
61
|
+
return typeof value === 'string' ? value : undefined;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
log.debug(`Could not read document.readyState: ${getErrorMessage(error)}`);
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* What the page is still loading, if it has not finished.
|
|
70
|
+
*
|
|
71
|
+
* @param cdp - CDP connection
|
|
72
|
+
* @param pending - Requests still running (from the session's network telemetry)
|
|
73
|
+
* @returns The loading state, or undefined when the document is complete or did not answer
|
|
74
|
+
*/
|
|
75
|
+
export async function readPageLoadingState(cdp, pending) {
|
|
76
|
+
const readyState = await readDocumentReadyState(cdp);
|
|
77
|
+
if (readyState === undefined || readyState === 'complete')
|
|
78
|
+
return undefined;
|
|
79
|
+
const requests = [...pending];
|
|
80
|
+
return {
|
|
81
|
+
readyState,
|
|
82
|
+
pending: summarizePendingRequests(requests, Date.now()),
|
|
83
|
+
pendingCount: requests.length,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=loadingState.js.map
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { CDPConnection } from '../../connection/cdp.js';
|
|
5
5
|
import type { PageAction, PageNavigationResult } from '../../ipc/protocol/commands.js';
|
|
6
|
+
import type { PendingRequest } from '../../telemetry/network.js';
|
|
6
7
|
import type { CDPSender } from '../../telemetry/objectExpander.js';
|
|
7
8
|
/**
|
|
8
9
|
* Navigate the session's page and wait until it has loaded.
|
|
@@ -11,17 +12,21 @@ import type { CDPSender } from '../../telemetry/objectExpander.js';
|
|
|
11
12
|
* navigation may still be waiting for the server). Otherwise the server gets
|
|
12
13
|
* {@link PAGE_READY_TIMEOUT_MS} to answer, then the new document is waited on
|
|
13
14
|
* to settle; its HTTP status is reported, with a warning for 4xx/5xx, for a
|
|
14
|
-
* URL that is a download, or a
|
|
15
|
+
* URL that is a download, or a server that has not answered. A document
|
|
16
|
+
* that has not finished loading by then is reported as `loading`, with the
|
|
17
|
+
* requests it waits on.
|
|
15
18
|
*
|
|
16
19
|
* @param cdp - CDP connection
|
|
17
20
|
* @param action - Navigate to a URL, reload, or go back/forward in history
|
|
18
|
-
* @param options - `url` for navigate, `wait: false` to return without waiting
|
|
21
|
+
* @param options - `url` for navigate, `wait: false` to return without waiting,
|
|
22
|
+
* `pendingRequests`: the session's requests still running
|
|
19
23
|
* @returns Where the page is now
|
|
20
24
|
* @throws CommandError (80) for an unreachable URL, (81) without a history entry
|
|
21
25
|
*/
|
|
22
26
|
export declare function navigatePage(cdp: CDPConnection, action: PageAction, options?: {
|
|
23
27
|
url?: string;
|
|
24
28
|
wait?: boolean;
|
|
29
|
+
pendingRequests?: () => Iterable<PendingRequest>;
|
|
25
30
|
}): Promise<PageNavigationResult>;
|
|
26
31
|
/**
|
|
27
32
|
* The URL of a navigation still waiting for the server, if any: the page
|
|
@@ -31,4 +36,43 @@ export declare function navigatePage(cdp: CDPConnection, action: PageAction, opt
|
|
|
31
36
|
* @returns The pending URL, or undefined when the page is not navigating
|
|
32
37
|
*/
|
|
33
38
|
export declare function pendingNavigationUrl(cdp: CDPSender): Promise<string | undefined>;
|
|
39
|
+
/** HTTP response of a document loaded in the main frame */
|
|
40
|
+
interface DocumentResponse {
|
|
41
|
+
status: number;
|
|
42
|
+
url: string;
|
|
43
|
+
}
|
|
44
|
+
/** Documents the main frame loaded during a navigation */
|
|
45
|
+
export interface DocumentResponses {
|
|
46
|
+
/** The navigation's own document (after HTTP redirects) */
|
|
47
|
+
first: DocumentResponse;
|
|
48
|
+
/** The last document loaded after it (a script or meta refresh moved on), if any */
|
|
49
|
+
later?: DocumentResponse;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add the HTTP status of the navigation's own document, with a warning for an
|
|
53
|
+
* error status or for a later document that answered differently (a 404 page
|
|
54
|
+
* whose script loads the app, as single-page apps on static hosts do).
|
|
55
|
+
*
|
|
56
|
+
* @param result - Navigation result
|
|
57
|
+
* @param documents - The main frame's document responses, if one arrived
|
|
58
|
+
* @returns Result with status
|
|
59
|
+
*/
|
|
60
|
+
export declare function withStatus(result: PageNavigationResult, documents: DocumentResponses | undefined): PageNavigationResult;
|
|
61
|
+
/**
|
|
62
|
+
* Watch for the responses of the main frame's documents. Only documents
|
|
63
|
+
* requested after the watch began count (a response to a request from
|
|
64
|
+
* before belongs to an earlier navigation). The navigation's own document
|
|
65
|
+
* is the one of its loader when the browser named it, else the first; the
|
|
66
|
+
* documents after it were loaded by the page itself.
|
|
67
|
+
*
|
|
68
|
+
* @param cdp - CDP connection
|
|
69
|
+
* @param mainFrameId - Main frame id
|
|
70
|
+
* @returns The responses seen so far (given the navigation's loader, if known),
|
|
71
|
+
* and a function to stop listening
|
|
72
|
+
*/
|
|
73
|
+
export declare function documentResponse(cdp: Pick<CDPConnection, 'on'>, mainFrameId: string): {
|
|
74
|
+
response: (loaderId?: string) => DocumentResponses | undefined;
|
|
75
|
+
stop: () => void;
|
|
76
|
+
};
|
|
77
|
+
export {};
|
|
34
78
|
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -5,8 +5,9 @@ import { waitForPageReady } from '../../connection/pageReadiness.js';
|
|
|
5
5
|
import { UNREACHABLE_ERRORS } from '../../daemon/session/cdpSetup.js';
|
|
6
6
|
import { CommandError } from '../../errors/index.js';
|
|
7
7
|
import { navigationFailedError, noHistoryEntryError } from '../../errors/messages.js';
|
|
8
|
+
import { readPageLoadingState } from './loadingState.js';
|
|
8
9
|
import { createLogger } from '../../ui/logging/index.js';
|
|
9
|
-
import {
|
|
10
|
+
import { documentStatusWarning, notAPageWarning, stillLoadingWarning, } from '../../ui/messages/commands.js';
|
|
10
11
|
import { delay } from '../../utils/async.js';
|
|
11
12
|
import { getErrorMessage } from '../../utils/errors.js';
|
|
12
13
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
@@ -21,11 +22,14 @@ const PAGE_READY_TIMEOUT_MS = 15_000;
|
|
|
21
22
|
* navigation may still be waiting for the server). Otherwise the server gets
|
|
22
23
|
* {@link PAGE_READY_TIMEOUT_MS} to answer, then the new document is waited on
|
|
23
24
|
* to settle; its HTTP status is reported, with a warning for 4xx/5xx, for a
|
|
24
|
-
* URL that is a download, or a
|
|
25
|
+
* URL that is a download, or a server that has not answered. A document
|
|
26
|
+
* that has not finished loading by then is reported as `loading`, with the
|
|
27
|
+
* requests it waits on.
|
|
25
28
|
*
|
|
26
29
|
* @param cdp - CDP connection
|
|
27
30
|
* @param action - Navigate to a URL, reload, or go back/forward in history
|
|
28
|
-
* @param options - `url` for navigate, `wait: false` to return without waiting
|
|
31
|
+
* @param options - `url` for navigate, `wait: false` to return without waiting,
|
|
32
|
+
* `pendingRequests`: the session's requests still running
|
|
29
33
|
* @returns Where the page is now
|
|
30
34
|
* @throws CommandError (80) for an unreachable URL, (81) without a history entry
|
|
31
35
|
*/
|
|
@@ -37,15 +41,17 @@ export async function navigatePage(cdp, action, options = {}) {
|
|
|
37
41
|
const navigated = nextNavigation(cdp, mainFrameId);
|
|
38
42
|
const document = documentResponse(cdp, mainFrameId);
|
|
39
43
|
const deadline = Date.now() + PAGE_READY_TIMEOUT_MS;
|
|
44
|
+
let loaderId;
|
|
40
45
|
try {
|
|
41
46
|
const sent = startAction(cdp, action, url);
|
|
42
47
|
sent.catch(() => undefined);
|
|
43
48
|
const started = await Promise.race([sent, delay(PAGE_READY_TIMEOUT_MS)]);
|
|
44
49
|
if (started === undefined)
|
|
45
50
|
return await stillLoading(cdp, action);
|
|
46
|
-
if (started
|
|
51
|
+
if (started.notAPage) {
|
|
47
52
|
return { action, ...(await currentLocation(cdp)), warning: notAPageWarning() };
|
|
48
53
|
}
|
|
54
|
+
loaderId = started.loaderId;
|
|
49
55
|
const how = await Promise.race([navigated.done, delay(Math.max(0, deadline - Date.now()))]);
|
|
50
56
|
if (how === 'loaded') {
|
|
51
57
|
await waitForPageReady(cdp, { maxWaitMs: Math.max(0, deadline - Date.now()) });
|
|
@@ -55,7 +61,9 @@ export async function navigatePage(cdp, action, options = {}) {
|
|
|
55
61
|
navigated.stop();
|
|
56
62
|
document.stop();
|
|
57
63
|
}
|
|
58
|
-
|
|
64
|
+
const result = withStatus({ action, ...(await currentLocation(cdp)) }, document.response(loaderId));
|
|
65
|
+
const loading = await readPageLoadingState(cdp, options.pendingRequests?.() ?? []);
|
|
66
|
+
return loading ? { ...result, loading } : result;
|
|
59
67
|
}
|
|
60
68
|
/** How long `--no-wait` waits for an action to be refused (no history entry, unreachable URL) */
|
|
61
69
|
const NO_WAIT_GRACE_MS = 1_000;
|
|
@@ -74,7 +82,7 @@ async function startWithoutWaiting(cdp, action, url) {
|
|
|
74
82
|
sent.catch((error) => log.debug(`Navigation not started: ${getErrorMessage(error)}`));
|
|
75
83
|
const started = await Promise.race([sent, delay(NO_WAIT_GRACE_MS)]);
|
|
76
84
|
const result = { action, url: url ?? (await pageTarget(cdp)).url, title: '' };
|
|
77
|
-
return started
|
|
85
|
+
return started?.notAPage ? { ...result, warning: notAPageWarning() } : result;
|
|
78
86
|
}
|
|
79
87
|
/**
|
|
80
88
|
* Send the command of an action.
|
|
@@ -82,7 +90,7 @@ async function startWithoutWaiting(cdp, action, url) {
|
|
|
82
90
|
* @param cdp - CDP connection
|
|
83
91
|
* @param action - What to do
|
|
84
92
|
* @param url - Normalized URL for navigate
|
|
85
|
-
* @returns
|
|
93
|
+
* @returns Whether a document is loading, and its loader when known
|
|
86
94
|
* @throws CommandError (80) when the URL cannot be reached, (81) without a history entry
|
|
87
95
|
*/
|
|
88
96
|
async function startAction(cdp, action, url) {
|
|
@@ -92,7 +100,7 @@ async function startAction(cdp, action, url) {
|
|
|
92
100
|
await cdp.send('Page.reload', {});
|
|
93
101
|
else
|
|
94
102
|
await goThroughHistory(cdp, action === 'back' ? -1 : 1);
|
|
95
|
-
return
|
|
103
|
+
return { notAPage: false };
|
|
96
104
|
}
|
|
97
105
|
/**
|
|
98
106
|
* The page target as the browser sees it. Unlike the page's own state, this
|
|
@@ -151,38 +159,64 @@ async function stillLoading(cdp, action) {
|
|
|
151
159
|
};
|
|
152
160
|
}
|
|
153
161
|
/**
|
|
154
|
-
* Add the
|
|
162
|
+
* Add the HTTP status of the navigation's own document, with a warning for an
|
|
163
|
+
* error status or for a later document that answered differently (a 404 page
|
|
164
|
+
* whose script loads the app, as single-page apps on static hosts do).
|
|
155
165
|
*
|
|
156
166
|
* @param result - Navigation result
|
|
157
|
-
* @param
|
|
167
|
+
* @param documents - The main frame's document responses, if one arrived
|
|
158
168
|
* @returns Result with status
|
|
159
169
|
*/
|
|
160
|
-
function withStatus(result,
|
|
161
|
-
if (!
|
|
170
|
+
export function withStatus(result, documents) {
|
|
171
|
+
if (!documents)
|
|
162
172
|
return result;
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
status: response.status,
|
|
168
|
-
...(response.status >= 400 && { warning: httpErrorWarning(response.status) }),
|
|
169
|
-
};
|
|
173
|
+
const { first, later } = documents;
|
|
174
|
+
const url = result.url.startsWith('chrome-error://') ? first.url : result.url;
|
|
175
|
+
const warning = documentStatusWarning(first.status, later);
|
|
176
|
+
return { ...result, url, status: first.status, ...(warning && { warning }) };
|
|
170
177
|
}
|
|
171
178
|
/**
|
|
172
|
-
* Watch for the
|
|
179
|
+
* Watch for the responses of the main frame's documents. Only documents
|
|
180
|
+
* requested after the watch began count (a response to a request from
|
|
181
|
+
* before belongs to an earlier navigation). The navigation's own document
|
|
182
|
+
* is the one of its loader when the browser named it, else the first; the
|
|
183
|
+
* documents after it were loaded by the page itself.
|
|
173
184
|
*
|
|
174
185
|
* @param cdp - CDP connection
|
|
175
186
|
* @param mainFrameId - Main frame id
|
|
176
|
-
* @returns The
|
|
187
|
+
* @returns The responses seen so far (given the navigation's loader, if known),
|
|
188
|
+
* and a function to stop listening
|
|
177
189
|
*/
|
|
178
|
-
function documentResponse(cdp, mainFrameId) {
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
export function documentResponse(cdp, mainFrameId) {
|
|
191
|
+
const requested = new Set();
|
|
192
|
+
const responses = [];
|
|
193
|
+
const isMainDocument = (params) => params.type === 'Document' && params.frameId === mainFrameId;
|
|
194
|
+
const stopRequests = cdp.on('Network.requestWillBeSent', (params) => {
|
|
195
|
+
if (isMainDocument(params))
|
|
196
|
+
requested.add(params.requestId);
|
|
184
197
|
});
|
|
185
|
-
|
|
198
|
+
const stopResponses = cdp.on('Network.responseReceived', (params) => {
|
|
199
|
+
if (!isMainDocument(params) || !requested.has(params.requestId))
|
|
200
|
+
return;
|
|
201
|
+
const { status, url } = params.response;
|
|
202
|
+
responses.push({ status, url, ...(params.loaderId && { loaderId: params.loaderId }) });
|
|
203
|
+
});
|
|
204
|
+
const response = (loaderId) => {
|
|
205
|
+
const index = loaderId ? responses.findIndex((r) => r.loaderId === loaderId) : 0;
|
|
206
|
+
const own = responses[index];
|
|
207
|
+
if (index < 0 || !own)
|
|
208
|
+
return undefined;
|
|
209
|
+
const last = responses.length - 1 > index ? responses[responses.length - 1] : undefined;
|
|
210
|
+
const first = { status: own.status, url: own.url };
|
|
211
|
+
return last ? { first, later: { status: last.status, url: last.url } } : { first };
|
|
212
|
+
};
|
|
213
|
+
return {
|
|
214
|
+
response,
|
|
215
|
+
stop: () => {
|
|
216
|
+
stopRequests();
|
|
217
|
+
stopResponses();
|
|
218
|
+
},
|
|
219
|
+
};
|
|
186
220
|
}
|
|
187
221
|
/**
|
|
188
222
|
* Resolve once the page has loaded a new document, moved within its
|
|
@@ -216,15 +250,17 @@ function nextNavigation(cdp, mainFrameId) {
|
|
|
216
250
|
*
|
|
217
251
|
* @param cdp - CDP connection
|
|
218
252
|
* @param url - Normalized URL
|
|
219
|
-
* @returns
|
|
253
|
+
* @returns Whether a document is loading (not for a download), and its loader
|
|
220
254
|
* @throws CommandError (80) when the URL cannot be reached
|
|
221
255
|
*/
|
|
222
256
|
async function navigateTo(cdp, url) {
|
|
223
257
|
const navigation = (await cdp.send('Page.navigate', { url }));
|
|
224
|
-
if (navigation.errorText === 'net::ERR_ABORTED' && !navigation.loaderId)
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
|
|
258
|
+
if (navigation.errorText === 'net::ERR_ABORTED' && !navigation.loaderId) {
|
|
259
|
+
return { notAPage: true };
|
|
260
|
+
}
|
|
261
|
+
if (!navigation.errorText || !UNREACHABLE_ERRORS.test(navigation.errorText)) {
|
|
262
|
+
return { notAPage: false, ...(navigation.loaderId && { loaderId: navigation.loaderId }) };
|
|
263
|
+
}
|
|
228
264
|
const err = navigationFailedError(url, navigation.errorText);
|
|
229
265
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_URL);
|
|
230
266
|
}
|
|
@@ -18,11 +18,21 @@
|
|
|
18
18
|
* }
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
|
-
import type { DomQueryResult } from '../types.js';
|
|
21
|
+
import type { DomQueryResult, IndexSource } from '../types.js';
|
|
22
22
|
/**
|
|
23
23
|
* Selector recorded for `dom form` results (fields carry their own selectors).
|
|
24
24
|
*/
|
|
25
25
|
export declare const FORM_DISCOVERY_CACHE_SELECTOR = "form:auto-discovered";
|
|
26
|
+
/** Prefix of the selector recorded for `dom a11y query` results (followed by the pattern) */
|
|
27
|
+
export declare const A11Y_CACHE_SELECTOR_PREFIX = "a11y ";
|
|
28
|
+
/**
|
|
29
|
+
* The list an index refers to, from the selector recorded with the cache.
|
|
30
|
+
*
|
|
31
|
+
* @param index - The index the user gave
|
|
32
|
+
* @param cacheSelector - Selector recorded with the cached results
|
|
33
|
+
* @returns The command whose results are cached, and its query
|
|
34
|
+
*/
|
|
35
|
+
export declare function indexSourceOf(index: number, cacheSelector: string): IndexSource;
|
|
26
36
|
/**
|
|
27
37
|
* Result of reading the cache.
|
|
28
38
|
*/
|