browser-debugger-cli 0.8.0 → 0.10.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 +7 -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 +29 -6
- 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 +189 -119
- 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/keyAttributes.d.ts +20 -0
- package/dist/commands/dom/helpers/keyAttributes.js +54 -0
- package/dist/commands/dom/helpers/query.d.ts +44 -17
- package/dist/commands/dom/helpers/query.js +300 -106
- package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
- package/dist/commands/dom/helpers/runElementCommand.js +98 -30
- package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
- package/dist/commands/dom/helpers/screenshot.js +239 -51
- package/dist/commands/dom/index.d.ts +4 -1
- package/dist/commands/dom/index.js +22 -7
- package/dist/commands/dom/inspect.d.ts +15 -0
- package/dist/commands/dom/inspect.js +82 -0
- 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 +15 -5
- 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 +16 -10
- package/dist/commands/dom/semanticUtils.js +53 -16
- 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 +17 -13
- package/dist/commands/optionBehaviors.js +154 -21
- package/dist/commands/page.d.ts +3 -2
- package/dist/commands/page.js +100 -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/commonOptions.d.ts +4 -0
- package/dist/commands/shared/commonOptions.js +9 -0
- 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 +61 -5
- package/dist/commands/shared/startHelpers.d.ts +66 -0
- package/dist/commands/shared/startHelpers.js +103 -13
- package/dist/commands/shared/validation.d.ts +14 -2
- package/dist/commands/shared/validation.js +20 -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 +10 -2
- package/dist/daemon/launcher.js +8 -7
- package/dist/daemon/server/SocketServer.js +1 -2
- package/dist/daemon/session/Session.d.ts +20 -0
- package/dist/daemon/session/Session.js +80 -9
- package/dist/daemon/session/chromeConnection.d.ts +9 -0
- package/dist/daemon/session/chromeConnection.js +45 -8
- package/dist/daemon/session/commandRegistry.d.ts +14 -1
- package/dist/daemon/session/commandRegistry.js +113 -67
- package/dist/daemon/session/interactions.d.ts +48 -9
- package/dist/daemon/session/interactions.js +46 -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 +10630 -3601
- package/dist/errors/messages.d.ts +456 -24
- package/dist/errors/messages.js +862 -67
- package/dist/index.js +6915 -3401
- package/dist/ipc/client.d.ts +21 -1
- package/dist/ipc/client.js +35 -3
- package/dist/ipc/protocol/commands.d.ts +145 -5
- package/dist/ipc/protocol/commands.js +4 -0
- package/dist/ipc/protocol/domTypes.d.ts +291 -7
- package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
- package/dist/ipc/protocol/inspectTypes.js +10 -0
- 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 +185 -0
- package/dist/runtime/dom/actionEffects.js +402 -0
- package/dist/runtime/dom/actionEffectsScripts.d.ts +90 -0
- package/dist/runtime/dom/actionEffectsScripts.js +426 -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 +103 -0
- package/dist/runtime/dom/elementInfo.js +256 -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 +184 -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 +9 -0
- package/dist/runtime/dom/formFillHelpers/fill.js +178 -14
- 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 +12 -1
- package/dist/runtime/dom/frameSelection.js +22 -3
- package/dist/runtime/dom/frames.d.ts +61 -5
- package/dist/runtime/dom/frames.js +329 -75
- package/dist/runtime/dom/inspect.d.ts +28 -0
- package/dist/runtime/dom/inspect.js +557 -0
- package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
- package/dist/runtime/dom/inspectAllStyles.js +385 -0
- package/dist/runtime/dom/inspectCascade.d.ts +94 -0
- package/dist/runtime/dom/inspectCascade.js +371 -0
- package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
- package/dist/runtime/dom/inspectCascadeModel.js +232 -0
- package/dist/runtime/dom/inspectHints.d.ts +62 -0
- package/dist/runtime/dom/inspectHints.js +305 -0
- package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
- package/dist/runtime/dom/inspectLayoutModel.js +346 -0
- package/dist/runtime/dom/inspectModel.d.ts +74 -0
- package/dist/runtime/dom/inspectModel.js +184 -0
- package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
- package/dist/runtime/dom/inspectPaintModel.js +461 -0
- package/dist/runtime/dom/inspectRules.d.ts +37 -0
- package/dist/runtime/dom/inspectRules.js +101 -0
- package/dist/runtime/dom/inspectScripts.d.ts +132 -0
- package/dist/runtime/dom/inspectScripts.js +263 -0
- package/dist/runtime/dom/inspectTree.d.ts +40 -0
- package/dist/runtime/dom/inspectTree.js +134 -0
- package/dist/runtime/dom/inspectVariables.d.ts +33 -0
- package/dist/runtime/dom/inspectVariables.js +94 -0
- package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
- package/dist/runtime/dom/inspectWhyModel.js +134 -0
- package/dist/runtime/dom/layout.d.ts +71 -0
- package/dist/runtime/dom/layout.js +340 -0
- package/dist/runtime/dom/listenerPageScripts.d.ts +72 -0
- package/dist/runtime/dom/listenerPageScripts.js +365 -0
- package/dist/runtime/dom/listenerSummary.d.ts +136 -11
- package/dist/runtime/dom/listenerSummary.js +361 -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 +63 -2
- package/dist/runtime/dom/reactEventHelpers.js +220 -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 +71 -0
- package/dist/runtime/page/emulation.js +117 -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 +18 -3
- package/dist/telemetry/a11y.js +170 -29
- package/dist/telemetry/console.d.ts +1 -0
- package/dist/telemetry/console.js +100 -5
- package/dist/telemetry/network.js +3 -1
- 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 +112 -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.d.ts +8 -0
- package/dist/ui/formatters/details.js +61 -4
- package/dist/ui/formatters/dom.d.ts +27 -14
- package/dist/ui/formatters/dom.js +88 -59
- package/dist/ui/formatters/form.js +29 -18
- package/dist/ui/formatters/inspect.d.ts +39 -0
- package/dist/ui/formatters/inspect.js +596 -0
- package/dist/ui/formatters/keyAttributes.d.ts +19 -0
- package/dist/ui/formatters/keyAttributes.js +84 -0
- 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.d.ts +13 -0
- package/dist/ui/formatters/networkHeaders.js +36 -3
- package/dist/ui/formatters/networkList.d.ts +29 -1
- package/dist/ui/formatters/networkList.js +86 -20
- 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 +19 -0
- package/dist/ui/formatting.js +31 -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 +504 -14
- package/dist/ui/messages/commands.js +835 -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/networkMessages.d.ts +14 -0
- package/dist/ui/messages/networkMessages.js +18 -0
- package/dist/ui/messages/preview.js +5 -4
- package/dist/ui/messages/session.d.ts +30 -21
- package/dist/ui/messages/session.js +48 -26
- package/dist/ui/messages/sessionCommand.d.ts +43 -0
- package/dist/ui/messages/sessionCommand.js +52 -0
- package/dist/utils/async.d.ts +17 -0
- package/dist/utils/async.js +36 -0
- package/dist/utils/color.d.ts +84 -0
- package/dist/utils/color.js +376 -0
- package/dist/utils/cssValues.d.ts +109 -0
- package/dist/utils/cssValues.js +236 -0
- package/dist/utils/http.d.ts +22 -1
- package/dist/utils/http.js +28 -9
- package/dist/utils/selectorFilters.d.ts +48 -8
- package/dist/utils/selectorFilters.js +296 -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,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readiness of a discovered form (`bdg dom form`): which fields are filled,
|
|
3
|
+
* which required ones are still empty, and which button submits it.
|
|
4
|
+
*/
|
|
5
|
+
import { REQUIRED_FIELD_EMPTY_REASON } from '../../ui/messages/commands.js';
|
|
6
|
+
/**
|
|
7
|
+
* Button labels that leave or clear a form instead of submitting it (English,
|
|
8
|
+
* German, French, Spanish, Italian and Polish cancel/back words)
|
|
9
|
+
*/
|
|
10
|
+
const DISMISSIVE_BUTTON_LABEL = /^(cancel|reset|back|go back|previous|prev|close|clear|discard|delete|remove|abbrechen|zurück|annuler|retour|cancelar|volver|annulla|indietro|anuluj|wstecz)\b/iu;
|
|
11
|
+
/**
|
|
12
|
+
* Fields a user fills as one: the options of a radio or checkbox group (same
|
|
13
|
+
* name in the same form), or a single field.
|
|
14
|
+
*
|
|
15
|
+
* @param fields - Form fields
|
|
16
|
+
* @returns Groups, in the order their first field appears
|
|
17
|
+
*/
|
|
18
|
+
export function groupFields(fields) {
|
|
19
|
+
const groups = new Map();
|
|
20
|
+
for (const field of fields) {
|
|
21
|
+
const type = (field.inputType ?? field.type).toLowerCase();
|
|
22
|
+
const choice = (type === 'radio' || type === 'checkbox') && field.name;
|
|
23
|
+
const key = choice ? `${field.formIndex}:${type}:${field.name}` : `#${field.index}`;
|
|
24
|
+
groups.set(key, [...(groups.get(key) ?? []), field]);
|
|
25
|
+
}
|
|
26
|
+
return [...groups.values()];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Whether a field has a value (a checked option for radios and checkboxes).
|
|
30
|
+
*
|
|
31
|
+
* @param field - Form field
|
|
32
|
+
* @returns True when filled or checked
|
|
33
|
+
*/
|
|
34
|
+
function isFilled(field) {
|
|
35
|
+
return field.state === 'filled' || field.state === 'checked';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Label of a field group: the group's name (legend, radiogroup label, name)
|
|
39
|
+
* for several options, the field's own label otherwise.
|
|
40
|
+
*
|
|
41
|
+
* @param group - Fields of one group (at least one)
|
|
42
|
+
* @returns Label
|
|
43
|
+
*/
|
|
44
|
+
function groupLabel(group) {
|
|
45
|
+
const [first] = group;
|
|
46
|
+
return group.length > 1 ? (first.groupLabel ?? first.label) : first.label;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* What keeps a form from being submitted: required groups left empty,
|
|
50
|
+
* invalid fields, a disabled submit button.
|
|
51
|
+
*
|
|
52
|
+
* @param groups - Field groups of the editable, visible fields
|
|
53
|
+
* @param buttons - Form buttons
|
|
54
|
+
* @returns Blockers, required fields first
|
|
55
|
+
*/
|
|
56
|
+
function findBlockers(groups, buttons) {
|
|
57
|
+
const blockers = [];
|
|
58
|
+
for (const group of groups) {
|
|
59
|
+
const first = group[0];
|
|
60
|
+
if (group.some((field) => field.required) && !group.some(isFilled)) {
|
|
61
|
+
blockers.push({
|
|
62
|
+
index: first.index,
|
|
63
|
+
label: groupLabel(group),
|
|
64
|
+
reason: REQUIRED_FIELD_EMPTY_REASON,
|
|
65
|
+
command: first.command,
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const invalid = group.find((field) => !field.validation.valid);
|
|
70
|
+
if (invalid) {
|
|
71
|
+
blockers.push({
|
|
72
|
+
index: invalid.index,
|
|
73
|
+
label: invalid.label,
|
|
74
|
+
reason: invalid.validation.message ?? 'Validation failed',
|
|
75
|
+
command: invalid.command,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const submitButton = buttons.find((b) => b.type === 'submit' && b.primary);
|
|
80
|
+
if (submitButton && !submitButton.enabled) {
|
|
81
|
+
blockers.push({
|
|
82
|
+
index: submitButton.index,
|
|
83
|
+
label: submitButton.label,
|
|
84
|
+
reason: submitButton.disabledReason ?? 'Submit button is disabled',
|
|
85
|
+
command: submitButton.command,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return blockers;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Summarize a form's state. Only visible, editable fields count, and a radio
|
|
92
|
+
* or checkbox group counts once (filled when any option is checked; required
|
|
93
|
+
* when any option is). The form is ready when nothing blocks it and at least
|
|
94
|
+
* one field is filled (an untouched form is not ready), or it has no fields.
|
|
95
|
+
*
|
|
96
|
+
* @param fields - Form fields
|
|
97
|
+
* @param buttons - Form buttons
|
|
98
|
+
* @returns Form summary
|
|
99
|
+
*/
|
|
100
|
+
export function calculateSummary(fields, buttons) {
|
|
101
|
+
const editable = fields.filter((f) => !f.hidden && !f.disabled && !f.readOnly);
|
|
102
|
+
const groups = groupFields(editable);
|
|
103
|
+
const filled = groups.filter((group) => group.some(isFilled));
|
|
104
|
+
const empty = groups.filter((group) => !group.some(isFilled));
|
|
105
|
+
const required = groups.filter((group) => group.some((field) => field.required));
|
|
106
|
+
const requiredRemaining = required.filter((group) => !group.some(isFilled)).length;
|
|
107
|
+
const invalid = groups.filter((group) => group.some((field) => !field.validation.valid)).length;
|
|
108
|
+
const blockers = findBlockers(groups, buttons);
|
|
109
|
+
return {
|
|
110
|
+
totalFields: groups.length,
|
|
111
|
+
filledFields: filled.length,
|
|
112
|
+
emptyFields: empty.length,
|
|
113
|
+
validFields: groups.length - invalid,
|
|
114
|
+
invalidFields: invalid,
|
|
115
|
+
requiredTotal: required.length,
|
|
116
|
+
requiredFilled: required.length - requiredRemaining,
|
|
117
|
+
requiredRemaining,
|
|
118
|
+
emptyFieldLabels: empty.map(groupLabel),
|
|
119
|
+
readyToSubmit: blockers.length === 0 && (filled.length > 0 || groups.length === 0),
|
|
120
|
+
blockers,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The button that submits the form, as a user would pick it. Buttons that
|
|
125
|
+
* cancel, reset, go back or delete ({@link DISMISSIVE_BUTTON_LABEL}) never
|
|
126
|
+
* are. Then, in order: a button written as a submit button
|
|
127
|
+
* (`type="submit"`, `<input type=submit>`); among the form's untyped
|
|
128
|
+
* `<button>`s (each submits it) one styled as primary, else the last one
|
|
129
|
+
* (forms put Cancel or Back first); else any button styled as primary.
|
|
130
|
+
* Buttons outside a form submit nothing, so only their style counts.
|
|
131
|
+
*
|
|
132
|
+
* @param buttons - Raw buttons of one form
|
|
133
|
+
* @returns Index of the primary button, or undefined when there is none
|
|
134
|
+
*/
|
|
135
|
+
export function primaryButtonIndex(buttons) {
|
|
136
|
+
const candidates = buttons.filter((button) => button.type !== 'reset' && !DISMISSIVE_BUTTON_LABEL.test(button.label.trim()));
|
|
137
|
+
const formDefaults = candidates.filter((button) => button.formDefault);
|
|
138
|
+
const primary = candidates.find((button) => button.explicitSubmit) ??
|
|
139
|
+
formDefaults.find((button) => button.primaryClass) ??
|
|
140
|
+
formDefaults.at(-1) ??
|
|
141
|
+
candidates.find((button) => button.primaryClass);
|
|
142
|
+
return primary?.index;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Where a form is listed: shown in an open dialog first (what the user is
|
|
146
|
+
* looking at), then other visible forms, then hidden ones.
|
|
147
|
+
*
|
|
148
|
+
* @param form - Raw form
|
|
149
|
+
* @returns Rank, lower first
|
|
150
|
+
*/
|
|
151
|
+
function visibilityRank(form) {
|
|
152
|
+
if (form.hidden)
|
|
153
|
+
return 2;
|
|
154
|
+
return form.inDialog ? 0 : 1;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Put forms in listing order (by {@link visibilityRank}, then by relevance)
|
|
158
|
+
* and number them, their fields and their buttons in that order, so the
|
|
159
|
+
* first field listed is 0 and `bdg dom fill <index>` / `click <index>` reach
|
|
160
|
+
* the element listed with that index (the indices are cached in this order).
|
|
161
|
+
* Within a form, fields come before buttons, both in document order.
|
|
162
|
+
*
|
|
163
|
+
* @param forms - Raw forms in document order
|
|
164
|
+
* @returns Forms in listing order, renumbered (the input is not changed)
|
|
165
|
+
*/
|
|
166
|
+
export function orderForms(forms) {
|
|
167
|
+
const ordered = forms
|
|
168
|
+
.map((form, position) => ({ form, position }))
|
|
169
|
+
.sort((a, b) => visibilityRank(a.form) - visibilityRank(b.form) ||
|
|
170
|
+
b.form.relevanceScore - a.form.relevanceScore ||
|
|
171
|
+
a.position - b.position);
|
|
172
|
+
let next = 0;
|
|
173
|
+
return ordered.map(({ form }, formIndex) => ({
|
|
174
|
+
...form,
|
|
175
|
+
index: formIndex,
|
|
176
|
+
fields: form.fields.map((field) => ({ ...field, index: next++, formIndex })),
|
|
177
|
+
buttons: form.buttons.map((button) => ({ ...button, index: next++ })),
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=formSummary.js.map
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { DomFramesCommandOptions } from '../shared/optionTypes.js';
|
|
8
8
|
/**
|
|
9
|
-
* Handle `bdg dom frames`.
|
|
9
|
+
* Handle `bdg dom frames`. The list of a page still loading says it may be
|
|
10
|
+
* incomplete (`readyState` in the data): its iframes may not exist yet.
|
|
10
11
|
*/
|
|
11
12
|
export declare function handleDomFrames(options: DomFramesCommandOptions): Promise<void>;
|
|
12
13
|
//# sourceMappingURL=frames.d.ts.map
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
* CLI-side handler. Frames are discovered in the daemon via the `dom_frames`
|
|
5
5
|
* IPC command, out-of-process (cross-site) ones included.
|
|
6
6
|
*/
|
|
7
|
+
import { documentReadyState } from './helpers/query.js';
|
|
7
8
|
import { runCommand } from '../shared/CommandRunner.js';
|
|
8
9
|
import { domFrames } from '../../ipc/client.js';
|
|
9
10
|
import { formatDomFrames } from '../../ui/formatters/dom.js';
|
|
10
11
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
11
12
|
/**
|
|
12
|
-
* Handle `bdg dom frames`.
|
|
13
|
+
* Handle `bdg dom frames`. The list of a page still loading says it may be
|
|
14
|
+
* incomplete (`readyState` in the data): its iframes may not exist yet.
|
|
13
15
|
*/
|
|
14
16
|
export async function handleDomFrames(options) {
|
|
15
17
|
await runCommand(async () => {
|
|
@@ -22,7 +24,20 @@ export async function handleDomFrames(options) {
|
|
|
22
24
|
...(response.suggestion && { errorContext: { suggestion: response.suggestion } }),
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
|
-
return { success: true, data:
|
|
27
|
+
return { success: true, data: await withReadyState(response.data.frames) };
|
|
26
28
|
}, options, formatDomFrames);
|
|
27
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The frames, with the page's `readyState` while it is still loading (one
|
|
32
|
+
* page evaluation).
|
|
33
|
+
*
|
|
34
|
+
* @param frames - Frames of the page
|
|
35
|
+
* @returns Frames, and `readyState` unless the page has loaded (or did not answer)
|
|
36
|
+
*/
|
|
37
|
+
async function withReadyState(frames) {
|
|
38
|
+
const readyState = await documentReadyState();
|
|
39
|
+
return readyState === undefined || readyState === 'complete'
|
|
40
|
+
? { frames }
|
|
41
|
+
: { frames, readyState };
|
|
42
|
+
}
|
|
28
43
|
//# sourceMappingURL=frames.js.map
|
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|
* - Raw: full HTML, attributes, and classes
|
|
7
7
|
*/
|
|
8
8
|
import type { DomGetCommandOptions } from '../shared/optionTypes.js';
|
|
9
|
+
/** What `bdg dom get` reads without a selector */
|
|
10
|
+
export declare const DOM_GET_DEFAULT_SELECTOR = "body";
|
|
9
11
|
/**
|
|
10
|
-
* Handle `bdg dom get [selectorOrIndex] [--node-id <id>]`.
|
|
12
|
+
* Handle `bdg dom get [selectorOrIndex] [--index <n>] [--node-id <id>]`.
|
|
11
13
|
*
|
|
12
|
-
* `--node-id` reads that node directly (raw output); otherwise
|
|
13
|
-
*
|
|
14
|
-
* numeric index.
|
|
14
|
+
* `--node-id` reads that node directly (raw output); otherwise reads a cached
|
|
15
|
+
* index or a selector's match (`body` without an argument).
|
|
15
16
|
*
|
|
16
|
-
* @param selectorOrIndex - CSS selector or cached index (
|
|
17
|
+
* @param selectorOrIndex - CSS selector or cached index (default: body)
|
|
17
18
|
* @param options - Command options
|
|
18
19
|
*/
|
|
19
20
|
export declare function handleDomGet(selectorOrIndex: string | undefined, options: DomGetCommandOptions): Promise<void>;
|
package/dist/commands/dom/get.js
CHANGED
|
@@ -6,86 +6,93 @@
|
|
|
6
6
|
* - Raw: full HTML, attributes, and classes
|
|
7
7
|
*/
|
|
8
8
|
import { DomElementResolver } from './DomElementResolver.js';
|
|
9
|
-
import { getDOMElements, getDomContext,
|
|
10
|
-
import { formatSemanticNodeWithContext,
|
|
9
|
+
import { getDOMElements, getDomContext, selectMatch, } from './helpers/index.js';
|
|
10
|
+
import { formatSemanticNodeWithContext, resolveNodeWithFallback, } from './semanticUtils.js';
|
|
11
11
|
import { runCommand } from '../shared/CommandRunner.js';
|
|
12
12
|
import { CommandError } from '../../errors/index.js';
|
|
13
|
-
import {
|
|
13
|
+
import { conflictingOptionsMessage, indexWithIndexOptionError, nodeIdNotFoundError, optionRequiresMessage, } from '../../errors/messages.js';
|
|
14
14
|
import { resolveA11yNode } from '../../telemetry/a11y.js';
|
|
15
15
|
import { formatDomGet } from '../../ui/formatters/dom.js';
|
|
16
16
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
17
17
|
import { filterDefined } from '../../utils/objects.js';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
/** What `bdg dom get` reads without a selector */
|
|
19
|
+
export const DOM_GET_DEFAULT_SELECTOR = 'body';
|
|
20
|
+
/**
|
|
21
|
+
* The element to read: a cached index or a selector match.
|
|
22
|
+
*
|
|
23
|
+
* @param selectorOrIndex - CSS selector or cached index
|
|
24
|
+
* @param index - Which match of the selector (0-based)
|
|
25
|
+
* @returns Backend node id
|
|
26
|
+
* @throws CommandError (83) no match, (81) index out of range, (87) stale cached index
|
|
27
|
+
*/
|
|
28
|
+
async function targetNodeId(selectorOrIndex, index) {
|
|
28
29
|
const resolver = DomElementResolver.getInstance();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const ref = { backendNodeId: targetNode.nodeId };
|
|
32
|
-
const [a11yNode, domContext] = await Promise.all([resolveA11yNode(ref), getDomContext(ref)]);
|
|
33
|
-
const node = resolveNodeWithFallback(a11yNode, domContext, targetNode.nodeId);
|
|
34
|
-
if (!node) {
|
|
35
|
-
const err = elementAtIndexNotFoundError(index, 'cached query');
|
|
36
|
-
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
37
|
-
}
|
|
38
|
-
return { success: true, data: { node, domContext } };
|
|
39
|
-
}, options, formatSemanticNodeWithContext);
|
|
40
|
-
}
|
|
41
|
-
async function handleIndexGet(index, options) {
|
|
42
|
-
if (options.raw) {
|
|
43
|
-
await handleIndexGetRaw(index, options);
|
|
30
|
+
if (resolver.isNumericIndex(selectorOrIndex)) {
|
|
31
|
+
return (await resolver.getNodeIdForIndex(Number(selectorOrIndex))).nodeId;
|
|
44
32
|
}
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
return selectMatch(selectorOrIndex, index ?? 0);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Semantic view of one element: its accessibility node (or one inferred from
|
|
37
|
+
* the DOM) and its DOM context.
|
|
38
|
+
*
|
|
39
|
+
* @param backendNodeId - The element
|
|
40
|
+
* @param full - All of its text instead of the first 500 characters
|
|
41
|
+
* @returns Node and context
|
|
42
|
+
* @throws CommandError (83) when the element is gone
|
|
43
|
+
*/
|
|
44
|
+
async function semanticElement(backendNodeId, full) {
|
|
45
|
+
const ref = { backendNodeId };
|
|
46
|
+
const [a11yNode, domContext] = await Promise.all([
|
|
47
|
+
resolveA11yNode(ref),
|
|
48
|
+
getDomContext(ref, { full }),
|
|
49
|
+
]);
|
|
50
|
+
const node = resolveNodeWithFallback(a11yNode, domContext, backendNodeId);
|
|
51
|
+
if (!node) {
|
|
52
|
+
const err = nodeIdNotFoundError(backendNodeId);
|
|
53
|
+
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
47
54
|
}
|
|
55
|
+
return { node, domContext };
|
|
48
56
|
}
|
|
49
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Raw view: the element(s) with attributes and outer HTML.
|
|
59
|
+
*
|
|
60
|
+
* @param selectorOrIndex - CSS selector or cached index
|
|
61
|
+
* @param options - Command options (`--all`, `--index`)
|
|
62
|
+
*/
|
|
63
|
+
async function handleRawGet(selectorOrIndex, options) {
|
|
50
64
|
await runCommand(async () => {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
const resolver = DomElementResolver.getInstance();
|
|
66
|
+
const getOptions = resolver.isNumericIndex(selectorOrIndex)
|
|
67
|
+
? { nodeId: (await resolver.getNodeIdForIndex(Number(selectorOrIndex))).nodeId }
|
|
68
|
+
: filterDefined({
|
|
69
|
+
selector: selectorOrIndex,
|
|
70
|
+
all: options.all,
|
|
71
|
+
nth: matchIndex(options),
|
|
72
|
+
});
|
|
73
|
+
return { success: true, data: await getDOMElements(getOptions) };
|
|
58
74
|
}, options, formatDomGet);
|
|
59
75
|
}
|
|
60
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Semantic view of the target.
|
|
78
|
+
*
|
|
79
|
+
* @param selectorOrIndex - CSS selector or cached index
|
|
80
|
+
* @param options - Command options (`--index`, `--full`)
|
|
81
|
+
*/
|
|
82
|
+
async function handleSemanticGet(selectorOrIndex, options) {
|
|
61
83
|
await runCommand(async () => {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
let nodeId;
|
|
65
|
-
if (a11yNode?.backendDOMNodeId) {
|
|
66
|
-
nodeId = a11yNode.backendDOMNodeId;
|
|
67
|
-
domContext = await getDomContext({ backendNodeId: nodeId });
|
|
68
|
-
}
|
|
69
|
-
else if (!a11yNode) {
|
|
70
|
-
const queryResult = await queryDomContextBySelector(selector);
|
|
71
|
-
nodeId = queryResult.nodeId;
|
|
72
|
-
domContext = queryResult.domContext;
|
|
73
|
-
}
|
|
74
|
-
const node = resolveNodeWithFallback(a11yNode, domContext, nodeId);
|
|
75
|
-
if (!node) {
|
|
76
|
-
const err = noNodesFoundError(selector);
|
|
77
|
-
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
78
|
-
}
|
|
79
|
-
return { success: true, data: { node, domContext } };
|
|
84
|
+
const backendNodeId = await targetNodeId(selectorOrIndex, matchIndex(options));
|
|
85
|
+
return { success: true, data: await semanticElement(backendNodeId, options.full === true) };
|
|
80
86
|
}, options, formatSemanticNodeWithContext);
|
|
81
87
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Which match of the selector to read: `--index`, or its alias `--nth`.
|
|
90
|
+
*
|
|
91
|
+
* @param options - Command options
|
|
92
|
+
* @returns 0-based index, undefined for the first match
|
|
93
|
+
*/
|
|
94
|
+
function matchIndex(options) {
|
|
95
|
+
return options.index ?? options.nth;
|
|
89
96
|
}
|
|
90
97
|
/**
|
|
91
98
|
* Options of `dom get` that cannot be combined (one would be ignored).
|
|
@@ -98,22 +105,26 @@ function getOptionsConflict(selectorOrIndex, options) {
|
|
|
98
105
|
if (options.nodeId !== undefined && selectorOrIndex !== undefined) {
|
|
99
106
|
return conflictingOptionsMessage('--node-id', 'a selector or index');
|
|
100
107
|
}
|
|
101
|
-
if (options.
|
|
102
|
-
return conflictingOptionsMessage('--
|
|
108
|
+
if (options.full && (options.raw || options.nodeId !== undefined)) {
|
|
109
|
+
return conflictingOptionsMessage('--full', options.raw ? '--raw' : '--node-id');
|
|
103
110
|
}
|
|
104
|
-
if (
|
|
105
|
-
return
|
|
111
|
+
if (options.index !== undefined && options.nth !== undefined) {
|
|
112
|
+
return conflictingOptionsMessage('--index', '--nth');
|
|
106
113
|
}
|
|
114
|
+
if (options.all && matchIndex(options) !== undefined) {
|
|
115
|
+
return conflictingOptionsMessage('--all', '--index');
|
|
116
|
+
}
|
|
117
|
+
if (options.all && !options.raw)
|
|
118
|
+
return optionRequiresMessage('--all', '--raw');
|
|
107
119
|
return null;
|
|
108
120
|
}
|
|
109
121
|
/**
|
|
110
|
-
* Handle `bdg dom get [selectorOrIndex] [--node-id <id>]`.
|
|
122
|
+
* Handle `bdg dom get [selectorOrIndex] [--index <n>] [--node-id <id>]`.
|
|
111
123
|
*
|
|
112
|
-
* `--node-id` reads that node directly (raw output); otherwise
|
|
113
|
-
*
|
|
114
|
-
* numeric index.
|
|
124
|
+
* `--node-id` reads that node directly (raw output); otherwise reads a cached
|
|
125
|
+
* index or a selector's match (`body` without an argument).
|
|
115
126
|
*
|
|
116
|
-
* @param selectorOrIndex - CSS selector or cached index (
|
|
127
|
+
* @param selectorOrIndex - CSS selector or cached index (default: body)
|
|
117
128
|
* @param options - Command options
|
|
118
129
|
*/
|
|
119
130
|
export async function handleDomGet(selectorOrIndex, options) {
|
|
@@ -126,16 +137,15 @@ export async function handleDomGet(selectorOrIndex, options) {
|
|
|
126
137
|
await runCommand(async () => ({ success: true, data: await getDOMElements({ nodeId }) }), options, formatDomGet);
|
|
127
138
|
return;
|
|
128
139
|
}
|
|
129
|
-
|
|
130
|
-
|
|
140
|
+
const target = selectorOrIndex ?? DOM_GET_DEFAULT_SELECTOR;
|
|
141
|
+
if (DomElementResolver.getInstance().isNumericIndex(target) &&
|
|
142
|
+
matchIndex(options) !== undefined) {
|
|
143
|
+
const err = indexWithIndexOptionError(target, 'get');
|
|
131
144
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
132
145
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
else {
|
|
138
|
-
await handleSelectorGet(selectorOrIndex, options);
|
|
139
|
-
}
|
|
146
|
+
if (options.raw)
|
|
147
|
+
await handleRawGet(target, options);
|
|
148
|
+
else
|
|
149
|
+
await handleSemanticGet(target, options);
|
|
140
150
|
}
|
|
141
151
|
//# sourceMappingURL=get.js.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* - `query.ts` — selector → backend node ids (shadow roots, same-origin iframes), DOM.describeNode
|
|
6
6
|
* - `screenshot.ts` — page / element capture, element bounds, scroll helpers
|
|
7
7
|
*/
|
|
8
|
-
export { queryDOMElements, getDomContext, getDOMElements, resolveSelector, resolveBackendNodeIds,
|
|
8
|
+
export { documentReadyState, noMatchesError, queryDOMElements, getDomContext, getDOMElements, resolveSelector, resolveBackendNodeIds, selectMatch, assertNodeAttached, } from './query.js';
|
|
9
9
|
export { capturePageScreenshot, captureElementScreenshot, getElementBounds, } from './screenshot.js';
|
|
10
10
|
export type { DomQueryResult, DomGetResult, ScreenshotResult, DomGetOptions, ScreenshotOptions, DomContext, ElementBounds, } from '../../../types.js';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* - `query.ts` — selector → backend node ids (shadow roots, same-origin iframes), DOM.describeNode
|
|
6
6
|
* - `screenshot.ts` — page / element capture, element bounds, scroll helpers
|
|
7
7
|
*/
|
|
8
|
-
export { queryDOMElements, getDomContext, getDOMElements, resolveSelector, resolveBackendNodeIds,
|
|
8
|
+
export { documentReadyState, noMatchesError, queryDOMElements, getDomContext, getDOMElements, resolveSelector, resolveBackendNodeIds, selectMatch, assertNodeAttached, } from './query.js';
|
|
9
9
|
export { capturePageScreenshot, captureElementScreenshot, getElementBounds, } from './screenshot.js';
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The attributes that identify an element by its type (an image's `src`, a
|
|
3
|
+
* link's `href`, a field's name and value), shown by `dom query`, `dom get`
|
|
4
|
+
* and `dom a11y describe`.
|
|
5
|
+
*/
|
|
6
|
+
import type { ElementState, KeyAttributes } from '../../../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* The key attributes of an element: the identifying attributes of its type
|
|
9
|
+
* that are set (empty ones left out) and the live state of a form control
|
|
10
|
+
* (type, current value, checked, selected options). Values arrive masked
|
|
11
|
+
* from the page (`ELEMENT_STATE_JS`); a hidden input's value is never read,
|
|
12
|
+
* and a sensitive field's value is masked here again in case it was not.
|
|
13
|
+
*
|
|
14
|
+
* @param tag - Lower-case tag name
|
|
15
|
+
* @param attributes - Element attributes
|
|
16
|
+
* @param state - Live state read in the page (`ELEMENT_STATE_JS`)
|
|
17
|
+
* @returns Key attributes, or undefined for an element type without any
|
|
18
|
+
*/
|
|
19
|
+
export declare function keyAttributes(tag: string, attributes: Record<string, string>, state?: ElementState): KeyAttributes | undefined;
|
|
20
|
+
//# sourceMappingURL=keyAttributes.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The attributes that identify an element by its type (an image's `src`, a
|
|
3
|
+
* link's `href`, a field's name and value), shown by `dom query`, `dom get`
|
|
4
|
+
* and `dom a11y describe`.
|
|
5
|
+
*/
|
|
6
|
+
import { MASKED_VALUE } from '../../../runtime/dom/elementInfo.js';
|
|
7
|
+
/** Attributes read for each element type (live state is added for form controls) */
|
|
8
|
+
const ATTRIBUTES_BY_TAG = {
|
|
9
|
+
img: ['src', 'alt'],
|
|
10
|
+
a: ['href'],
|
|
11
|
+
input: ['name', 'placeholder'],
|
|
12
|
+
textarea: ['name', 'placeholder'],
|
|
13
|
+
button: ['name'],
|
|
14
|
+
select: ['name'],
|
|
15
|
+
iframe: ['src'],
|
|
16
|
+
form: ['action', 'method'],
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The key attributes of an element: the identifying attributes of its type
|
|
20
|
+
* that are set (empty ones left out) and the live state of a form control
|
|
21
|
+
* (type, current value, checked, selected options). Values arrive masked
|
|
22
|
+
* from the page (`ELEMENT_STATE_JS`); a hidden input's value is never read,
|
|
23
|
+
* and a sensitive field's value is masked here again in case it was not.
|
|
24
|
+
*
|
|
25
|
+
* @param tag - Lower-case tag name
|
|
26
|
+
* @param attributes - Element attributes
|
|
27
|
+
* @param state - Live state read in the page (`ELEMENT_STATE_JS`)
|
|
28
|
+
* @returns Key attributes, or undefined for an element type without any
|
|
29
|
+
*/
|
|
30
|
+
export function keyAttributes(tag, attributes, state = {}) {
|
|
31
|
+
const names = ATTRIBUTES_BY_TAG[tag];
|
|
32
|
+
if (!names)
|
|
33
|
+
return undefined;
|
|
34
|
+
const result = {};
|
|
35
|
+
const type = state.type ?? attributes['type'];
|
|
36
|
+
if (type)
|
|
37
|
+
result['type'] = type;
|
|
38
|
+
for (const name of names) {
|
|
39
|
+
const value = attributes[name];
|
|
40
|
+
if (value)
|
|
41
|
+
result[name] = value;
|
|
42
|
+
}
|
|
43
|
+
if (type === 'hidden')
|
|
44
|
+
return result;
|
|
45
|
+
const secret = state.sensitive === true || type === 'password';
|
|
46
|
+
if (state.value)
|
|
47
|
+
result['value'] = secret ? MASKED_VALUE : state.value;
|
|
48
|
+
if (state.checked !== undefined)
|
|
49
|
+
result['checked'] = state.checked;
|
|
50
|
+
if (state.selected)
|
|
51
|
+
result['selected'] = secret ? MASKED_VALUE : state.selected;
|
|
52
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=keyAttributes.js.map
|
|
@@ -9,15 +9,35 @@
|
|
|
9
9
|
* bdg invocations. Selectors are matched in the page, including open shadow
|
|
10
10
|
* roots and same-origin iframes, like a user sees the page.
|
|
11
11
|
*/
|
|
12
|
-
import
|
|
12
|
+
import { type ErrorWithSuggestion, type NoMatchContext } from '../../../errors/messages.js';
|
|
13
|
+
import type { DomQueryResult, DomGetResult, DomGetOptions, DomContext, IndexSource, NodeRef } from '../../../types.js';
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* The "no nodes" error for a selector that matched nothing. One more page
|
|
16
|
+
* evaluation, on this failure path only, tells what the page says about it
|
|
17
|
+
* ({@link noMatchContext}).
|
|
16
18
|
*
|
|
17
|
-
* @param
|
|
18
|
-
* @returns
|
|
19
|
+
* @param selector - Selector as given
|
|
20
|
+
* @returns Message and suggestion
|
|
19
21
|
*/
|
|
20
|
-
export declare function
|
|
22
|
+
export declare function noMatchesError(selector: string): Promise<ErrorWithSuggestion>;
|
|
23
|
+
/**
|
|
24
|
+
* What the page says about a selector that matched nothing, in one
|
|
25
|
+
* evaluation: whether it is still loading, how many elements match with the
|
|
26
|
+
* selector's `:visible` filters removed, whether it has cross-origin iframes
|
|
27
|
+
* or embeds (which selectors do not search), and for a selector that is a
|
|
28
|
+
* single id or class, the similar ids or classes on the page.
|
|
29
|
+
*
|
|
30
|
+
* @param selector - Selector as given
|
|
31
|
+
* @returns Context for {@link noNodesFoundError} (empty when the page did not answer)
|
|
32
|
+
*/
|
|
33
|
+
export declare function noMatchContext(selector: string): Promise<NoMatchContext>;
|
|
34
|
+
/**
|
|
35
|
+
* The page's `document.readyState`, read for a failure that may come from a
|
|
36
|
+
* page still loading.
|
|
37
|
+
*
|
|
38
|
+
* @returns The state, or undefined when the page did not answer
|
|
39
|
+
*/
|
|
40
|
+
export declare function documentReadyState(): Promise<string | undefined>;
|
|
21
41
|
/**
|
|
22
42
|
* Query elements by selector for `bdg dom query`.
|
|
23
43
|
*
|
|
@@ -26,12 +46,26 @@ export declare function textPreview(text: string): string;
|
|
|
26
46
|
*/
|
|
27
47
|
export declare function queryDOMElements(selector: string): Promise<DomQueryResult>;
|
|
28
48
|
/**
|
|
29
|
-
* Get DOM context (tag, classes, text preview) for a node
|
|
49
|
+
* Get DOM context (tag, classes, key attributes, text preview) for a node: a one-line
|
|
50
|
+
* preview, and up to {@link ELEMENT_TEXT_LENGTH} characters of text when it
|
|
51
|
+
* is longer (all of it with `full`).
|
|
30
52
|
*
|
|
31
53
|
* @param ref - Node reference
|
|
54
|
+
* @param options - `full`: the whole text instead of its first 500 characters
|
|
32
55
|
* @returns DOM context, or null if the node does not exist
|
|
33
56
|
*/
|
|
34
|
-
export declare function getDomContext(ref: NodeRef
|
|
57
|
+
export declare function getDomContext(ref: NodeRef, options?: {
|
|
58
|
+
full?: boolean;
|
|
59
|
+
}): Promise<DomContext | null>;
|
|
60
|
+
/**
|
|
61
|
+
* One match of a selector.
|
|
62
|
+
*
|
|
63
|
+
* @param selector - CSS selector
|
|
64
|
+
* @param index - Which match (0-based)
|
|
65
|
+
* @returns Its backend node id
|
|
66
|
+
* @throws CommandError (83) when nothing matches, (81) for an index beyond the matches
|
|
67
|
+
*/
|
|
68
|
+
export declare function selectMatch(selector: string, index?: number): Promise<number>;
|
|
35
69
|
/**
|
|
36
70
|
* Get full details (attributes, outer HTML) for `bdg dom get --raw`.
|
|
37
71
|
*
|
|
@@ -55,13 +89,6 @@ export declare function resolveSelector(selector: string): Promise<NodeRef>;
|
|
|
55
89
|
* @returns Backend node id per selector, or undefined when it matches nothing
|
|
56
90
|
*/
|
|
57
91
|
export declare function resolveBackendNodeIds(selectors: string[]): Promise<(number | undefined)[]>;
|
|
58
|
-
/**
|
|
59
|
-
* Accessibility node of the first element matching a selector.
|
|
60
|
-
*
|
|
61
|
-
* @param selector - CSS selector
|
|
62
|
-
* @returns A11y node, or null when nothing matches or the node is not exposed
|
|
63
|
-
*/
|
|
64
|
-
export declare function resolveA11yNodeForSelector(selector: string): Promise<A11yNode | null>;
|
|
65
92
|
/**
|
|
66
93
|
* Check that a cached element is still part of the current page.
|
|
67
94
|
*
|
|
@@ -71,8 +98,8 @@ export declare function resolveA11yNodeForSelector(selector: string): Promise<A1
|
|
|
71
98
|
* false for removed elements.
|
|
72
99
|
*
|
|
73
100
|
* @param backendNodeId - Backend node id from the query cache
|
|
74
|
-
* @param
|
|
101
|
+
* @param source - Index the user gave and the list it refers to, for the error message
|
|
75
102
|
* @throws CommandError (87) when the element is gone
|
|
76
103
|
*/
|
|
77
|
-
export declare function assertNodeAttached(backendNodeId: number,
|
|
104
|
+
export declare function assertNodeAttached(backendNodeId: number, source?: IndexSource): Promise<void>;
|
|
78
105
|
//# sourceMappingURL=query.d.ts.map
|