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
|
@@ -1,28 +1,15 @@
|
|
|
1
1
|
import { OutputFormatter } from '../formatting.js';
|
|
2
|
-
import {
|
|
3
|
-
import { parseSelectorFilters } from '../../utils/selectorFilters.js';
|
|
2
|
+
import { frameLabel, moreMatchesNote, framesStillLoadingNote, noFramesMessage, queryNextSteps, screenshotGrownNote, viewportPositionHint, } from '../messages/commands.js';
|
|
4
3
|
/** Matches listed in human output (JSON has all of them) */
|
|
5
4
|
const QUERY_DISPLAY_LIMIT = 50;
|
|
6
|
-
/**
|
|
7
|
-
* A shell-quoted `dom eval` script reading the text (or a field's value) of
|
|
8
|
-
* the n-th match in the main document, as rendered (null for matches inside iframes or
|
|
9
|
-
* shadow roots, which `document.querySelectorAll` does not reach).
|
|
10
|
-
*
|
|
11
|
-
* @param selector - CSS selector
|
|
12
|
-
* @param index - Match to read
|
|
13
|
-
* @returns Single-quoted script, safe to paste into a shell
|
|
14
|
-
*/
|
|
15
|
-
function textExtractionScript(selector, index) {
|
|
16
|
-
const script = `(el => el && (el.value ?? el.innerText))(document.querySelectorAll(${JSON.stringify(selector)})[${index}])`;
|
|
17
|
-
return `'${script.replace(/'/g, `'\\''`)}'`;
|
|
18
|
-
}
|
|
19
5
|
/**
|
|
20
6
|
* Format DOM query results for human-readable output.
|
|
21
7
|
*
|
|
22
|
-
* Displays found nodes with their index, tag, classes, and preview text
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
8
|
+
* Displays found nodes with their index, tag, classes, and preview text
|
|
9
|
+
* (plus where they are when outside the viewport or hidden, e.g.
|
|
10
|
+
* `(below fold)`), up to {@link QUERY_DISPLAY_LIMIT} of them (no match is an error, exit 83).
|
|
11
|
+
* One line of next commands follows; they take the match's index, so they
|
|
12
|
+
* work for matches in shadow roots and iframes too.
|
|
26
13
|
*
|
|
27
14
|
* @param data - DOM query result containing selector, count, and matching nodes
|
|
28
15
|
* @returns Formatted output string
|
|
@@ -51,27 +38,23 @@ export function formatDomQuery(data) {
|
|
|
51
38
|
node.id && ` id="${node.id}"`,
|
|
52
39
|
node.name && ` name="${node.name}"`,
|
|
53
40
|
node.type && ` type="${node.type}"`,
|
|
41
|
+
node.value !== undefined && ` value="${node.value}"`,
|
|
54
42
|
node.classes?.length && ` class="${node.classes.join(' ')}"`,
|
|
55
43
|
]
|
|
56
44
|
.filter(Boolean)
|
|
57
45
|
.join('');
|
|
58
46
|
const context = node.context ? ` (in ${node.context})` : '';
|
|
59
47
|
const preview = node.preview ? ` ${node.preview}` : '';
|
|
60
|
-
|
|
48
|
+
const position = node.inViewport && viewportPositionHint(node.inViewport, node.clippedBy);
|
|
49
|
+
const location = position ? ` (${position})` : '';
|
|
50
|
+
return `[${node.index}] <${node.tag}${attributes}>${context}${preview}${location}`;
|
|
61
51
|
});
|
|
62
|
-
const
|
|
63
|
-
const exampleIndex = hasMultipleResults ? (nodes[0]?.index ?? 0) : 0;
|
|
52
|
+
const exampleIndex = nodes[0]?.index ?? 0;
|
|
64
53
|
return fmt
|
|
65
54
|
.text(`Found ${count} node${count === 1 ? '' : 's'} matching "${selector}":`)
|
|
66
55
|
.list(nodeLines)
|
|
67
56
|
.list(count > QUERY_DISPLAY_LIMIT ? [moreMatchesNote(count - QUERY_DISPLAY_LIMIT)] : [])
|
|
68
|
-
.
|
|
69
|
-
`Get HTML: bdg dom get ${exampleIndex} --raw`,
|
|
70
|
-
`Accessibility: bdg dom get ${exampleIndex}`,
|
|
71
|
-
...(parseSelectorFilters(selector)
|
|
72
|
-
? []
|
|
73
|
-
: [`Extract text: bdg dom eval ${textExtractionScript(selector, exampleIndex)}`]),
|
|
74
|
-
])
|
|
57
|
+
.tip(queryNextSteps(exampleIndex))
|
|
75
58
|
.build();
|
|
76
59
|
}
|
|
77
60
|
/**
|
|
@@ -118,18 +101,23 @@ export function formatDomGet(data) {
|
|
|
118
101
|
/**
|
|
119
102
|
* Format DOM eval results for human-readable output.
|
|
120
103
|
*
|
|
121
|
-
*
|
|
122
|
-
* `
|
|
104
|
+
* A string result is printed as is (not JSON-quoted), so text reads and
|
|
105
|
+
* pipes like `echo`, unless that would read as another value (empty,
|
|
106
|
+
* `undefined`, or valid JSON such as `42` or `[1,2]`): then it stays
|
|
107
|
+
* JSON-quoted. Other values are formatted JSON, and values Chrome only
|
|
108
|
+
* describes (functions, DOM nodes) their description. The iframe it ran in
|
|
109
|
+
* (`--frame`) is reported on stderr, so stdout stays the bare value. `--json`
|
|
110
|
+
* output is unchanged (the value in `data.result`).
|
|
123
111
|
*
|
|
124
|
-
* @param data - DOM eval result containing the evaluated value
|
|
125
|
-
* @returns
|
|
112
|
+
* @param data - DOM eval result containing the evaluated value
|
|
113
|
+
* @returns The string, or formatted JSON
|
|
126
114
|
*
|
|
127
115
|
* @example
|
|
128
116
|
* ```typescript
|
|
129
|
-
* formatDomEval({ result: 'My Page Title' });
|
|
130
|
-
* // Output:
|
|
117
|
+
* formatDomEval({ result: 'My Page Title', type: 'string' });
|
|
118
|
+
* // Output: My Page Title
|
|
131
119
|
*
|
|
132
|
-
* formatDomEval({ result: { url: 'https://example.com', title: 'Example' } });
|
|
120
|
+
* formatDomEval({ result: { url: 'https://example.com', title: 'Example' }, type: 'object' });
|
|
133
121
|
* // Output:
|
|
134
122
|
* // {
|
|
135
123
|
* // "url": "https://example.com",
|
|
@@ -138,39 +126,58 @@ export function formatDomGet(data) {
|
|
|
138
126
|
* ```
|
|
139
127
|
*/
|
|
140
128
|
export function formatDomEval(data) {
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
if (data.type === 'undefined')
|
|
130
|
+
return 'undefined';
|
|
131
|
+
const { result } = data;
|
|
132
|
+
if (typeof result === 'string' && (data.type !== 'string' || !looksLikeOtherValue(result))) {
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
return JSON.stringify(result ?? null, null, 2);
|
|
143
136
|
}
|
|
144
137
|
/**
|
|
145
|
-
*
|
|
138
|
+
* Whether a string printed as is would read as another value: empty,
|
|
139
|
+
* `undefined`, or valid JSON (`42`, `true`, `null`, `[1,2]`, `{"a":1}`).
|
|
146
140
|
*
|
|
147
|
-
* @param
|
|
148
|
-
* @returns
|
|
141
|
+
* @param text - String result
|
|
142
|
+
* @returns True when it must be JSON-quoted to read as a string
|
|
149
143
|
*/
|
|
150
|
-
function
|
|
151
|
-
if (
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return
|
|
156
|
-
|
|
144
|
+
function looksLikeOtherValue(text) {
|
|
145
|
+
if (text === '' || text === 'undefined')
|
|
146
|
+
return true;
|
|
147
|
+
try {
|
|
148
|
+
JSON.parse(text);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
157
154
|
}
|
|
158
155
|
/**
|
|
159
|
-
* Format the page's iframes, one per line
|
|
156
|
+
* Format the page's iframes, one per line, nested frames indented below
|
|
157
|
+
* their parent. While the page is still loading (`readyState` set), the list
|
|
158
|
+
* may be incomplete, and says so.
|
|
160
159
|
*
|
|
161
|
-
* @param data - Frames from `bdg dom frames
|
|
160
|
+
* @param data - Frames from `bdg dom frames`, with the readyState of a page still loading
|
|
162
161
|
* @returns Formatted list
|
|
163
162
|
*
|
|
164
163
|
* @example
|
|
165
164
|
* ```
|
|
166
165
|
* [0] http://localhost:3000/widget name=widget same-origin
|
|
167
166
|
* [1] https://pay.example/ #checkout cross-origin, out-of-process
|
|
167
|
+
* [2] about:blank same-origin
|
|
168
168
|
* ```
|
|
169
169
|
*/
|
|
170
170
|
export function formatDomFrames(data) {
|
|
171
|
+
const loading = data.readyState !== undefined && data.readyState !== 'complete';
|
|
171
172
|
if (data.frames.length === 0)
|
|
172
|
-
return noFramesMessage();
|
|
173
|
-
|
|
173
|
+
return loading ? framesStillLoadingNote(true) : noFramesMessage();
|
|
174
|
+
const depthOf = new Map();
|
|
175
|
+
const lines = data.frames.map((frame) => {
|
|
176
|
+
const depth = frame.parentIndex === undefined ? 0 : (depthOf.get(frame.parentIndex) ?? 0) + 1;
|
|
177
|
+
depthOf.set(frame.index, depth);
|
|
178
|
+
return ' '.repeat(depth) + frameLabel(frame);
|
|
179
|
+
});
|
|
180
|
+
return [...lines, ...(loading ? [framesStillLoadingNote(false)] : [])].join('\n');
|
|
174
181
|
}
|
|
175
182
|
/**
|
|
176
183
|
* Format screenshot capture result for human-readable display.
|
|
@@ -187,6 +194,9 @@ export function formatDomFrames(data) {
|
|
|
187
194
|
*
|
|
188
195
|
* formatDomScreenshot({ path: './page.png', fullPageSkipped: { reason: 'page_too_tall', ... } });
|
|
189
196
|
* // Output: Screenshot saved to ./page.png (viewport only - page too tall)
|
|
197
|
+
*
|
|
198
|
+
* // An element whose floated children overflow it
|
|
199
|
+
* // Output: Screenshot saved to ./el.png (grown from 940×37 to 940×285 to include content overflowing the element)
|
|
190
200
|
* ```
|
|
191
201
|
*/
|
|
192
202
|
export function formatDomScreenshot(data) {
|
|
@@ -194,6 +204,9 @@ export function formatDomScreenshot(data) {
|
|
|
194
204
|
if (data.fullPageSkipped && !data.scrolledTo) {
|
|
195
205
|
output += ' (viewport only - page too tall)';
|
|
196
206
|
}
|
|
207
|
+
if (data.element?.captured) {
|
|
208
|
+
output += ` (${screenshotGrownNote(data.element.bounds, data.element.captured)})`;
|
|
209
|
+
}
|
|
197
210
|
return output;
|
|
198
211
|
}
|
|
199
212
|
//# sourceMappingURL=dom.js.map
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* values, validation state, and suggested commands.
|
|
6
6
|
*/
|
|
7
7
|
import { OutputFormatter, areHintsHidden } from '../formatting.js';
|
|
8
|
+
import { REQUIRED_FIELD_EMPTY_REASON, formReadinessMessage, requiredFieldsEmptyMessage, } from '../messages/commands.js';
|
|
8
9
|
const COLUMN_WIDTHS = {
|
|
9
10
|
index: 4,
|
|
10
11
|
type: 12,
|
|
@@ -64,6 +65,9 @@ function formatFieldValue(field) {
|
|
|
64
65
|
* @returns Status string with icon
|
|
65
66
|
*/
|
|
66
67
|
function formatFieldStatus(field) {
|
|
68
|
+
if (field.hidden) {
|
|
69
|
+
return 'hidden';
|
|
70
|
+
}
|
|
67
71
|
if (field.disabled) {
|
|
68
72
|
return 'disabled';
|
|
69
73
|
}
|
|
@@ -127,12 +131,23 @@ function formatButtonRow(button) {
|
|
|
127
131
|
* @returns Header string
|
|
128
132
|
*/
|
|
129
133
|
function formatFormHeader(form) {
|
|
130
|
-
let header = `Form: "${form.name ?? 'Unnamed'}"`;
|
|
134
|
+
let header = `Form: "${form.name ?? 'Unnamed'}"${formVisibilityMarker(form)}`;
|
|
131
135
|
if (form.step) {
|
|
132
136
|
header += ` (step ${form.step.current} of ${form.step.total})`;
|
|
133
137
|
}
|
|
134
138
|
return header;
|
|
135
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Marker of a form shown in an open dialog or not shown at all.
|
|
142
|
+
*
|
|
143
|
+
* @param form - Form (or its listing in "Other forms")
|
|
144
|
+
* @returns ` (in dialog)`, ` (hidden)`, or empty
|
|
145
|
+
*/
|
|
146
|
+
function formVisibilityMarker(form) {
|
|
147
|
+
if (form.hidden)
|
|
148
|
+
return ' (hidden)';
|
|
149
|
+
return form.inDialog ? ' (in dialog)' : '';
|
|
150
|
+
}
|
|
136
151
|
/**
|
|
137
152
|
* Format table header row.
|
|
138
153
|
*
|
|
@@ -147,7 +162,9 @@ function formatTableHeader() {
|
|
|
147
162
|
return `${idx} ${type} ${label} ${value} ${status}`;
|
|
148
163
|
}
|
|
149
164
|
/**
|
|
150
|
-
* Format summary line.
|
|
165
|
+
* Format summary line, e.g. "Summary: 1/3 fields filled | 2 required fields
|
|
166
|
+
* empty: Last Name, Zip | NOT ready" (a radio or checkbox group counts as one
|
|
167
|
+
* field).
|
|
151
168
|
*
|
|
152
169
|
* @param summary - Form summary
|
|
153
170
|
* @returns Summary string
|
|
@@ -158,15 +175,12 @@ function formatSummaryLine(summary) {
|
|
|
158
175
|
if (summary.invalidFields > 0) {
|
|
159
176
|
parts.push(`${summary.invalidFields} invalid`);
|
|
160
177
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
parts.push(
|
|
166
|
-
|
|
167
|
-
else {
|
|
168
|
-
parts.push('NOT ready');
|
|
169
|
-
}
|
|
178
|
+
const requiredEmpty = summary.blockers
|
|
179
|
+
.filter((blocker) => blocker.reason === REQUIRED_FIELD_EMPTY_REASON)
|
|
180
|
+
.map((blocker) => blocker.label);
|
|
181
|
+
if (requiredEmpty.length > 0)
|
|
182
|
+
parts.push(requiredFieldsEmptyMessage(requiredEmpty));
|
|
183
|
+
parts.push(formReadinessMessage(summary));
|
|
170
184
|
return `Summary: ${parts.join(' | ')}`;
|
|
171
185
|
}
|
|
172
186
|
/**
|
|
@@ -197,9 +211,7 @@ function formatSingleForm(form, fmt, brief = false) {
|
|
|
197
211
|
fmt.text(formatTableHeader());
|
|
198
212
|
fmt.text('─'.repeat(70));
|
|
199
213
|
for (const field of form.fields) {
|
|
200
|
-
|
|
201
|
-
fmt.text(formatFieldRow(field));
|
|
202
|
-
}
|
|
214
|
+
fmt.text(formatFieldRow(field));
|
|
203
215
|
}
|
|
204
216
|
if (form.buttons.length > 0) {
|
|
205
217
|
fmt.text('─'.repeat(70));
|
|
@@ -228,13 +240,12 @@ function formatBriefFields(form, fmt) {
|
|
|
228
240
|
fmt.text('IDX TYPE LABEL REQ VALUE');
|
|
229
241
|
fmt.text('─'.repeat(70));
|
|
230
242
|
for (const field of form.fields) {
|
|
231
|
-
if (field.hidden)
|
|
232
|
-
continue;
|
|
233
243
|
const idx = `[${field.index}]`.padEnd(4);
|
|
234
244
|
const type = (field.inputType ?? field.type).slice(0, 11).padEnd(12);
|
|
235
245
|
const label = (field.label ?? field.name ?? '(no label)').slice(0, 23).padEnd(24);
|
|
236
246
|
const req = (field.required ? '*' : '').padEnd(3);
|
|
237
|
-
|
|
247
|
+
const hidden = field.hidden ? ' (hidden)' : '';
|
|
248
|
+
fmt.text(`${idx} ${type} ${label} ${req} ${formatFieldValue(field)}${hidden}`);
|
|
238
249
|
}
|
|
239
250
|
if (form.buttons.length > 0) {
|
|
240
251
|
fmt.text('─'.repeat(70));
|
|
@@ -258,7 +269,7 @@ function formatOtherForms(others, fmt) {
|
|
|
258
269
|
fmt.blank();
|
|
259
270
|
fmt.text('Other forms on page:');
|
|
260
271
|
for (const form of others) {
|
|
261
|
-
fmt.text(` Form ${form.index}: "${form.name ?? 'Unnamed'}" - ${form.fieldCount} field(s)`);
|
|
272
|
+
fmt.text(` Form ${form.index}: "${form.name ?? 'Unnamed'}"${formVisibilityMarker(form)} - ${form.fieldCount} field(s)`);
|
|
262
273
|
}
|
|
263
274
|
fmt.blank();
|
|
264
275
|
fmt.text('Use --all to see all forms');
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable output of `bdg dom layout`.
|
|
3
|
+
*/
|
|
4
|
+
import type { ElementLayout, LayoutResult, LayoutSize } from '../../ipc/protocol/domTypes.js';
|
|
5
|
+
import type { IndexSource } from '../../types.js';
|
|
6
|
+
/** `bdg dom layout` data (the `success` flag is implied by the envelope), with the list an index refers to */
|
|
7
|
+
type LayoutOutput = Omit<LayoutResult, 'success'> & {
|
|
8
|
+
indexSource?: IndexSource | undefined;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* One element as a compact line: index, description, text, page position
|
|
12
|
+
* and size (not for hidden elements, which have no meaningful box), where it
|
|
13
|
+
* is relative to the viewport, what covers it, an inert or invisible element
|
|
14
|
+
* and the iframe or shadow root it is in (unless the position already names
|
|
15
|
+
* it as the clipping iframe).
|
|
16
|
+
*
|
|
17
|
+
* @param element - Element layout
|
|
18
|
+
* @param viewport - Viewport size, when known (an element larger than it is not centred by the scroll)
|
|
19
|
+
* @returns e.g. `[0] button#save "Save" 420,1180 120×40 below fold (scroll down 500px to centre it)`
|
|
20
|
+
*/
|
|
21
|
+
export declare function layoutLine(element: ElementLayout, viewport?: LayoutSize): string;
|
|
22
|
+
/**
|
|
23
|
+
* Format `bdg dom layout` output: the page dimensions, then one line per
|
|
24
|
+
* element (the first {@link LAYOUT_DISPLAY_LIMIT}).
|
|
25
|
+
*
|
|
26
|
+
* @param data - Layout report
|
|
27
|
+
* @returns Formatted output
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatLayout(data: LayoutOutput): string;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable output of `bdg dom layout`.
|
|
3
|
+
*/
|
|
4
|
+
import { indexSourceText } from '../../errors/messages.js';
|
|
5
|
+
import { OutputFormatter } from '../formatting.js';
|
|
6
|
+
import { indexLayoutHeadline, layoutHeadline, layoutPositionLabel, moreMatchesNote, pageLayoutLine, } from '../messages/commands.js';
|
|
7
|
+
/** Elements listed in human output (JSON has up to 100) */
|
|
8
|
+
const LAYOUT_DISPLAY_LIMIT = 20;
|
|
9
|
+
/**
|
|
10
|
+
* One element as a compact line: index, description, text, page position
|
|
11
|
+
* and size (not for hidden elements, which have no meaningful box), where it
|
|
12
|
+
* is relative to the viewport, what covers it, an inert or invisible element
|
|
13
|
+
* and the iframe or shadow root it is in (unless the position already names
|
|
14
|
+
* it as the clipping iframe).
|
|
15
|
+
*
|
|
16
|
+
* @param element - Element layout
|
|
17
|
+
* @param viewport - Viewport size, when known (an element larger than it is not centred by the scroll)
|
|
18
|
+
* @returns e.g. `[0] button#save "Save" 420,1180 120×40 below fold (scroll down 500px to centre it)`
|
|
19
|
+
*/
|
|
20
|
+
export function layoutLine(element, viewport) {
|
|
21
|
+
const { bounds } = element;
|
|
22
|
+
return [
|
|
23
|
+
`[${element.index}] ${element.element}${element.text ? ` "${element.text}"` : ''}`,
|
|
24
|
+
element.inViewport !== 'hidden' && `${bounds.x},${bounds.y} ${bounds.width}×${bounds.height}`,
|
|
25
|
+
layoutPositionLabel(element, viewport),
|
|
26
|
+
element.coveredBy && `covered by ${element.coveredBy}`,
|
|
27
|
+
element.inert && 'inert',
|
|
28
|
+
element.invisible,
|
|
29
|
+
element.context && element.context !== element.clippedBy && `in ${element.context}`,
|
|
30
|
+
]
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(' ');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format `bdg dom layout` output: the page dimensions, then one line per
|
|
36
|
+
* element (the first {@link LAYOUT_DISPLAY_LIMIT}).
|
|
37
|
+
*
|
|
38
|
+
* @param data - Layout report
|
|
39
|
+
* @returns Formatted output
|
|
40
|
+
*/
|
|
41
|
+
export function formatLayout(data) {
|
|
42
|
+
const shown = data.elements.slice(0, LAYOUT_DISPLAY_LIMIT);
|
|
43
|
+
const more = data.elements.length - shown.length + (data.omitted ?? 0);
|
|
44
|
+
return new OutputFormatter()
|
|
45
|
+
.text(pageLayoutLine(data.page))
|
|
46
|
+
.text(data.indexSource
|
|
47
|
+
? indexLayoutHeadline(indexSourceText(data.indexSource))
|
|
48
|
+
: layoutHeadline(data.count, data.elements.length + (data.omitted ?? 0), data.selector))
|
|
49
|
+
.list(shown.map((element) => layoutLine(element, data.page.viewport)))
|
|
50
|
+
.list(more > 0 ? [moreMatchesNote(more, data.omitted ? data.elements.length : undefined)] : [])
|
|
51
|
+
.build();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -12,8 +12,9 @@ type ListenersOutput = Omit<ListenersResult, 'success'>;
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function handlerLocation(handler: ElementListener['handler']): string;
|
|
14
14
|
/**
|
|
15
|
-
* Format `bdg dom listeners` output: listeners grouped by event type,
|
|
16
|
-
* nearest first,
|
|
15
|
+
* Format `bdg dom listeners` output: listeners grouped by event type, the
|
|
16
|
+
* handlers nearest the element first, then one line per framework root,
|
|
17
|
+
* with notes for events the element has no listener of its own for.
|
|
17
18
|
*
|
|
18
19
|
* @param result - Listener report
|
|
19
20
|
* @param types - Event types asked for with --type, if any
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Human-readable output of `bdg dom listeners`.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { delegationNotes } from '../../runtime/dom/listenerSummary.js';
|
|
5
5
|
import { OutputFormatter } from '../formatting.js';
|
|
6
|
-
import { NO_LISTENERS_HINT,
|
|
6
|
+
import { COLLAPSED_LISTENERS_HEADING, NO_LISTENERS_HINT, collapsedListenersSummary, delegationNote, eventTypeSuggestion, jqueryHandlersSkippedNote, listenersHeadline, noListenersMessage, reactHandlersSkippedNote, } from '../messages/commands.js';
|
|
7
7
|
import { truncateByLength } from '../../utils/strings.js';
|
|
8
8
|
/** Longest handler name shown (JSON has the full name) */
|
|
9
9
|
const NAME_MAX_LENGTH = 30;
|
|
@@ -29,6 +29,9 @@ export function handlerLocation(handler) {
|
|
|
29
29
|
*/
|
|
30
30
|
function listenerCells(listener) {
|
|
31
31
|
const flags = [
|
|
32
|
+
listener.reactProp ? `React ${listener.reactProp}` : listener.framework,
|
|
33
|
+
listener.delegateSelector && `delegate ${listener.delegateSelector}`,
|
|
34
|
+
listener.noop && 'no-op',
|
|
32
35
|
listener.useCapture && 'capture',
|
|
33
36
|
listener.passive && 'passive',
|
|
34
37
|
listener.once && 'once',
|
|
@@ -54,9 +57,31 @@ function alignColumns(rows) {
|
|
|
54
57
|
.map((cell, column) => (column === row.length - 1 ? cell : cell.padEnd(widths[column] ?? 0)))
|
|
55
58
|
.join(' '));
|
|
56
59
|
}
|
|
60
|
+
/** Dispatcher names listed per collapsed framework root */
|
|
61
|
+
const COLLAPSED_HANDLERS_SHOWN = 3;
|
|
57
62
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
63
|
+
* Listeners by where they are attached, collapsed framework roots included.
|
|
64
|
+
*
|
|
65
|
+
* @param listeners - Listed listeners
|
|
66
|
+
* @param collapsed - Collapsed framework roots
|
|
67
|
+
* @returns Counts on the element, its ancestors, and document or window
|
|
68
|
+
*/
|
|
69
|
+
function listenerCounts(listeners, collapsed) {
|
|
70
|
+
const counts = { target: 0, ancestor: 0, global: 0 };
|
|
71
|
+
const add = (on, count) => {
|
|
72
|
+
if (on === 'target' || on === 'ancestor')
|
|
73
|
+
counts[on] += count;
|
|
74
|
+
else
|
|
75
|
+
counts.global += count;
|
|
76
|
+
};
|
|
77
|
+
listeners.forEach((listener) => add(listener.on, 1));
|
|
78
|
+
collapsed.forEach((root) => add(root.on, root.count));
|
|
79
|
+
return counts;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Format `bdg dom listeners` output: listeners grouped by event type, the
|
|
83
|
+
* handlers nearest the element first, then one line per framework root,
|
|
84
|
+
* with notes for events the element has no listener of its own for.
|
|
60
85
|
*
|
|
61
86
|
* @param result - Listener report
|
|
62
87
|
* @param types - Event types asked for with --type, if any
|
|
@@ -64,21 +89,60 @@ function alignColumns(rows) {
|
|
|
64
89
|
*/
|
|
65
90
|
export function formatListeners(result, types) {
|
|
66
91
|
const fmt = new OutputFormatter();
|
|
67
|
-
|
|
92
|
+
const collapsed = result.collapsed ?? [];
|
|
93
|
+
if (result.listeners.length === 0 && collapsed.length === 0) {
|
|
68
94
|
fmt.text(noListenersMessage(result.element, types));
|
|
95
|
+
if (result.typeSuggestions?.length)
|
|
96
|
+
fmt.text(eventTypeSuggestion(result.typeSuggestions));
|
|
69
97
|
fmt.tip(NO_LISTENERS_HINT);
|
|
70
98
|
}
|
|
71
99
|
else {
|
|
72
|
-
fmt.text(listenersHeadline(result.element, result.listeners
|
|
100
|
+
fmt.text(listenersHeadline(result.element, listenerCounts(result.listeners, collapsed), result));
|
|
73
101
|
appendListenerGroups(fmt, result.listeners);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
appendCollapsed(fmt, collapsed);
|
|
103
|
+
appendDelegationNotes(fmt, result.listeners, collapsed);
|
|
104
|
+
}
|
|
105
|
+
if (result.jqueryHandlersSkipped) {
|
|
106
|
+
fmt.blank().text(jqueryHandlersSkippedNote(result.jqueryHandlersSkipped));
|
|
107
|
+
}
|
|
108
|
+
if (result.reactHandlersSkipped) {
|
|
109
|
+
fmt.blank().text(reactHandlersSkippedNote(result.reactHandlersSkipped));
|
|
77
110
|
}
|
|
78
111
|
if (result.warning)
|
|
79
112
|
fmt.blank().text(`⚠ Warning: ${result.warning}`);
|
|
80
113
|
return fmt.build();
|
|
81
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Add a note per way events reach their handlers without a listener on the
|
|
117
|
+
* element itself (React props, React root, jQuery, plain delegation).
|
|
118
|
+
*
|
|
119
|
+
* @param fmt - Output being built
|
|
120
|
+
* @param listeners - Listeners
|
|
121
|
+
* @param collapsed - Collapsed roots
|
|
122
|
+
*/
|
|
123
|
+
function appendDelegationNotes(fmt, listeners, collapsed) {
|
|
124
|
+
const notes = delegationNotes(listeners, collapsed).flatMap((note) => delegationNote(note) ?? []);
|
|
125
|
+
if (notes.length > 0)
|
|
126
|
+
fmt.blank();
|
|
127
|
+
notes.forEach((note) => fmt.text(note));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Add the collapsed framework roots, one line per node.
|
|
131
|
+
*
|
|
132
|
+
* @param fmt - Output being built
|
|
133
|
+
* @param collapsed - Collapsed roots
|
|
134
|
+
*/
|
|
135
|
+
function appendCollapsed(fmt, collapsed) {
|
|
136
|
+
if (collapsed.length === 0)
|
|
137
|
+
return;
|
|
138
|
+
fmt.blank().text(COLLAPSED_LISTENERS_HEADING);
|
|
139
|
+
const rows = collapsed.map((root) => {
|
|
140
|
+
const names = root.handlers.map((handler) => truncateByLength(handler.name || ANONYMOUS, NAME_MAX_LENGTH));
|
|
141
|
+
const shown = [...new Set(names)].slice(0, COLLAPSED_HANDLERS_SHOWN);
|
|
142
|
+
return [root.on, root.node, collapsedListenersSummary({ ...root, handlers: shown })];
|
|
143
|
+
});
|
|
144
|
+
alignColumns(rows).forEach((line) => fmt.text(` ${line}`));
|
|
145
|
+
}
|
|
82
146
|
/**
|
|
83
147
|
* Add one block per event type: the type, then its listeners.
|
|
84
148
|
*
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Formats network request and response headers for human-readable display.
|
|
5
5
|
*/
|
|
6
|
+
import { formatRequestStatus } from './requestStatus.js';
|
|
6
7
|
import { OutputFormatter } from '../formatting.js';
|
|
7
8
|
/**
|
|
8
9
|
* Format network request headers for display.
|
|
@@ -14,6 +15,7 @@ export function formatNetworkHeaders(data) {
|
|
|
14
15
|
const fmt = new OutputFormatter();
|
|
15
16
|
fmt.text('Network Request Headers').separator('━', 60).blank();
|
|
16
17
|
fmt.text('URL:').text(` ${data.url}`).blank();
|
|
18
|
+
fmt.text(`Status: ${requestStatusLine(data)}`).blank();
|
|
17
19
|
if (Object.keys(data.responseHeaders).length > 0) {
|
|
18
20
|
fmt.text('Response Headers:');
|
|
19
21
|
formatHeaderSection(fmt, data.responseHeaders);
|
|
@@ -47,4 +49,15 @@ function formatHeaderSection(fmt, headers) {
|
|
|
47
49
|
value.split('\n').forEach((line) => fmt.keyValue(` ${key}`, line, keyWidth));
|
|
48
50
|
});
|
|
49
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Status line of a request: method, HTTP status and status text, or how it failed.
|
|
54
|
+
*
|
|
55
|
+
* @param data - Network headers data
|
|
56
|
+
* @returns e.g. `GET 404 Not Found`, `GET FAILED (net::ERR_NAME_NOT_RESOLVED)`, `GET pending`
|
|
57
|
+
*/
|
|
58
|
+
function requestStatusLine(data) {
|
|
59
|
+
const status = formatRequestStatus(data);
|
|
60
|
+
const text = data.statusText && /^\d+$/.test(status) ? ` ${data.statusText}` : '';
|
|
61
|
+
return [data.method, `${status}${text}`].filter(Boolean).join(' ');
|
|
62
|
+
}
|
|
50
63
|
//# sourceMappingURL=networkHeaders.js.map
|
|
@@ -4,6 +4,7 @@ import { formatTimestamp } from './console/shared.js';
|
|
|
4
4
|
import { failureReason, formatRequestStatus, getRequestState, } from './requestStatus.js';
|
|
5
5
|
import { OutputFormatter, truncateUrl, truncateText } from '../formatting.js';
|
|
6
6
|
import { PREVIEW_EMPTY_STATES, PREVIEW_HEADERS, compactTipsMessage, verboseCommandsMessage, } from '../messages/preview.js';
|
|
7
|
+
import { sessionCommand } from '../messages/sessionCommand.js';
|
|
7
8
|
/**
|
|
8
9
|
* Infer resource type from MIME type when CDP doesn't provide it.
|
|
9
10
|
*
|
|
@@ -218,7 +219,7 @@ function formatPreviewVerbose(output, options) {
|
|
|
218
219
|
if (req.mimeType) {
|
|
219
220
|
fmt.text(` MIME: ${req.mimeType}`);
|
|
220
221
|
}
|
|
221
|
-
fmt.text(` ID: ${req.requestId} (use 'bdg details network ${req.requestId}' for full details)`);
|
|
222
|
+
fmt.text(` ID: ${req.requestId} (use '${sessionCommand(`bdg details network ${req.requestId}`)}' for full details)`);
|
|
222
223
|
});
|
|
223
224
|
}
|
|
224
225
|
fmt.blank();
|
|
@@ -6,23 +6,7 @@
|
|
|
6
6
|
* response keeps its HTTP status even if loading failed afterwards.
|
|
7
7
|
*/
|
|
8
8
|
import type { NetworkRequest } from '../../types.js';
|
|
9
|
-
|
|
10
|
-
export type RequestState = 'pending' | 'failed' | 'complete';
|
|
11
|
-
/**
|
|
12
|
-
* Classify a request.
|
|
13
|
-
*
|
|
14
|
-
* @param request - Captured request
|
|
15
|
-
* @returns Its lifecycle state
|
|
16
|
-
*/
|
|
17
|
-
export declare function getRequestState(request: Pick<NetworkRequest, 'status'>): RequestState;
|
|
18
|
-
/**
|
|
19
|
-
* Why a request failed, leaving out Chrome stopping an unneeded body after a
|
|
20
|
-
* complete response (204/304 report `net::ERR_ABORTED` that way).
|
|
21
|
-
*
|
|
22
|
-
* @param request - Captured request
|
|
23
|
-
* @returns Reason, or undefined when there is none worth showing
|
|
24
|
-
*/
|
|
25
|
-
export declare function failureReason(request: Pick<NetworkRequest, 'status' | 'errorText'>): string | undefined;
|
|
9
|
+
export { failureReason, getRequestState, type RequestState } from '../../telemetry/requestState.js';
|
|
26
10
|
/**
|
|
27
11
|
* Human-readable status: the HTTP status (with the failure reason if loading
|
|
28
12
|
* failed after the response), `FAILED (<reason>)`, or `pending`.
|
|
@@ -5,31 +5,8 @@
|
|
|
5
5
|
* without any response (DNS, refused, aborted, blocked); a request that got a
|
|
6
6
|
* response keeps its HTTP status even if loading failed afterwards.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*
|
|
11
|
-
* @param request - Captured request
|
|
12
|
-
* @returns Its lifecycle state
|
|
13
|
-
*/
|
|
14
|
-
export function getRequestState(request) {
|
|
15
|
-
if (request.status === undefined)
|
|
16
|
-
return 'pending';
|
|
17
|
-
return request.status === 0 ? 'failed' : 'complete';
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Why a request failed, leaving out Chrome stopping an unneeded body after a
|
|
21
|
-
* complete response (204/304 report `net::ERR_ABORTED` that way).
|
|
22
|
-
*
|
|
23
|
-
* @param request - Captured request
|
|
24
|
-
* @returns Reason, or undefined when there is none worth showing
|
|
25
|
-
*/
|
|
26
|
-
export function failureReason(request) {
|
|
27
|
-
if (!request.errorText)
|
|
28
|
-
return undefined;
|
|
29
|
-
return getRequestState(request) === 'complete' && request.errorText === BODY_ABORTED
|
|
30
|
-
? undefined
|
|
31
|
-
: request.errorText;
|
|
32
|
-
}
|
|
8
|
+
import { BODY_ABORTED, getRequestState } from '../../telemetry/requestState.js';
|
|
9
|
+
export { failureReason, getRequestState } from '../../telemetry/requestState.js';
|
|
33
10
|
/**
|
|
34
11
|
* Human-readable status: the HTTP status (with the failure reason if loading
|
|
35
12
|
* failed after the response), `FAILED (<reason>)`, or `pending`.
|
|
@@ -47,9 +24,4 @@ export function formatRequestStatus(request) {
|
|
|
47
24
|
? `${request.status} (${request.errorText})`
|
|
48
25
|
: String(request.status);
|
|
49
26
|
}
|
|
50
|
-
/**
|
|
51
|
-
* Error Chrome reports when it stops reading a response body nobody needs
|
|
52
|
-
* (the response itself arrived; not a failure of the request).
|
|
53
|
-
*/
|
|
54
|
-
const BODY_ABORTED = 'net::ERR_ABORTED';
|
|
55
27
|
//# sourceMappingURL=requestStatus.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RunningSessionInfo } from '../../session/sessionList.js';
|
|
2
|
+
/**
|
|
3
|
+
* Format the sessions as a table, followed by the cleanup commands of
|
|
4
|
+
* crashed and stale sessions.
|
|
5
|
+
*
|
|
6
|
+
* @param data - Sessions
|
|
7
|
+
* @returns Human-readable list
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatSessionList(data: {
|
|
10
|
+
sessions: RunningSessionInfo[];
|
|
11
|
+
}): string;
|
|
12
|
+
//# sourceMappingURL=sessions.d.ts.map
|