browser-debugger-cli 0.9.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.
Files changed (133) hide show
  1. package/README.md +4 -1
  2. package/dist/commands/dom/a11y.js +2 -1
  3. package/dist/commands/dom/formInteraction.js +56 -25
  4. package/dist/commands/dom/helpers/keyAttributes.d.ts +20 -0
  5. package/dist/commands/dom/helpers/keyAttributes.js +54 -0
  6. package/dist/commands/dom/helpers/query.d.ts +1 -1
  7. package/dist/commands/dom/helpers/query.js +66 -19
  8. package/dist/commands/dom/helpers/runElementCommand.js +4 -3
  9. package/dist/commands/dom/helpers/screenshot.js +85 -12
  10. package/dist/commands/dom/index.d.ts +1 -0
  11. package/dist/commands/dom/index.js +8 -3
  12. package/dist/commands/dom/inspect.d.ts +15 -0
  13. package/dist/commands/dom/inspect.js +82 -0
  14. package/dist/commands/dom/layout.js +2 -2
  15. package/dist/commands/dom/listeners.js +2 -2
  16. package/dist/commands/dom/semanticUtils.d.ts +14 -1
  17. package/dist/commands/dom/semanticUtils.js +44 -3
  18. package/dist/commands/network/list.js +13 -2
  19. package/dist/commands/optionBehaviors.js +48 -6
  20. package/dist/commands/page.d.ts +1 -1
  21. package/dist/commands/page.js +62 -3
  22. package/dist/commands/shared/commonOptions.d.ts +4 -0
  23. package/dist/commands/shared/commonOptions.js +9 -0
  24. package/dist/commands/shared/optionTypes.d.ts +21 -0
  25. package/dist/commands/shared/startHelpers.d.ts +66 -0
  26. package/dist/commands/shared/startHelpers.js +91 -10
  27. package/dist/commands/shared/validation.d.ts +11 -0
  28. package/dist/commands/shared/validation.js +16 -0
  29. package/dist/daemon/launcher.d.ts +8 -1
  30. package/dist/daemon/launcher.js +3 -1
  31. package/dist/daemon/session/Session.d.ts +7 -0
  32. package/dist/daemon/session/Session.js +23 -1
  33. package/dist/daemon/session/commandRegistry.d.ts +14 -1
  34. package/dist/daemon/session/commandRegistry.js +65 -9
  35. package/dist/daemon/session/interactions.d.ts +18 -5
  36. package/dist/daemon/session/interactions.js +22 -12
  37. package/dist/daemon.js +3565 -329
  38. package/dist/errors/messages.d.ts +69 -0
  39. package/dist/errors/messages.js +102 -1
  40. package/dist/index.js +2416 -1320
  41. package/dist/ipc/client.d.ts +9 -0
  42. package/dist/ipc/client.js +13 -0
  43. package/dist/ipc/protocol/commands.d.ts +56 -1
  44. package/dist/ipc/protocol/commands.js +2 -0
  45. package/dist/ipc/protocol/domTypes.d.ts +35 -2
  46. package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
  47. package/dist/ipc/protocol/inspectTypes.js +10 -0
  48. package/dist/runtime/dom/actionEffects.d.ts +94 -15
  49. package/dist/runtime/dom/actionEffects.js +173 -27
  50. package/dist/runtime/dom/actionEffectsScripts.d.ts +52 -14
  51. package/dist/runtime/dom/actionEffectsScripts.js +224 -32
  52. package/dist/runtime/dom/elementInfo.d.ts +26 -0
  53. package/dist/runtime/dom/elementInfo.js +65 -0
  54. package/dist/runtime/dom/eventListeners.js +14 -4
  55. package/dist/runtime/dom/formFillHelpers/fill.d.ts +3 -4
  56. package/dist/runtime/dom/formFillHelpers/fill.js +77 -28
  57. package/dist/runtime/dom/frameSelection.d.ts +11 -0
  58. package/dist/runtime/dom/frameSelection.js +20 -1
  59. package/dist/runtime/dom/frames.d.ts +38 -5
  60. package/dist/runtime/dom/frames.js +136 -21
  61. package/dist/runtime/dom/inspect.d.ts +28 -0
  62. package/dist/runtime/dom/inspect.js +557 -0
  63. package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
  64. package/dist/runtime/dom/inspectAllStyles.js +385 -0
  65. package/dist/runtime/dom/inspectCascade.d.ts +94 -0
  66. package/dist/runtime/dom/inspectCascade.js +371 -0
  67. package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
  68. package/dist/runtime/dom/inspectCascadeModel.js +232 -0
  69. package/dist/runtime/dom/inspectHints.d.ts +62 -0
  70. package/dist/runtime/dom/inspectHints.js +305 -0
  71. package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
  72. package/dist/runtime/dom/inspectLayoutModel.js +346 -0
  73. package/dist/runtime/dom/inspectModel.d.ts +74 -0
  74. package/dist/runtime/dom/inspectModel.js +184 -0
  75. package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
  76. package/dist/runtime/dom/inspectPaintModel.js +461 -0
  77. package/dist/runtime/dom/inspectRules.d.ts +37 -0
  78. package/dist/runtime/dom/inspectRules.js +101 -0
  79. package/dist/runtime/dom/inspectScripts.d.ts +132 -0
  80. package/dist/runtime/dom/inspectScripts.js +263 -0
  81. package/dist/runtime/dom/inspectTree.d.ts +40 -0
  82. package/dist/runtime/dom/inspectTree.js +134 -0
  83. package/dist/runtime/dom/inspectVariables.d.ts +33 -0
  84. package/dist/runtime/dom/inspectVariables.js +94 -0
  85. package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
  86. package/dist/runtime/dom/inspectWhyModel.js +134 -0
  87. package/dist/runtime/dom/layout.d.ts +5 -1
  88. package/dist/runtime/dom/layout.js +10 -3
  89. package/dist/runtime/dom/listenerPageScripts.d.ts +11 -5
  90. package/dist/runtime/dom/listenerPageScripts.js +95 -9
  91. package/dist/runtime/dom/listenerSummary.d.ts +4 -0
  92. package/dist/runtime/dom/listenerSummary.js +26 -9
  93. package/dist/runtime/dom/reactEventHelpers.d.ts +5 -0
  94. package/dist/runtime/dom/reactEventHelpers.js +12 -4
  95. package/dist/runtime/page/emulation.d.ts +20 -0
  96. package/dist/runtime/page/emulation.js +37 -0
  97. package/dist/telemetry/a11y.d.ts +10 -0
  98. package/dist/telemetry/a11y.js +78 -1
  99. package/dist/telemetry/console.d.ts +1 -0
  100. package/dist/telemetry/console.js +100 -5
  101. package/dist/telemetry/network.js +3 -1
  102. package/dist/types.d.ts +32 -0
  103. package/dist/ui/formatters/details.d.ts +8 -0
  104. package/dist/ui/formatters/details.js +59 -3
  105. package/dist/ui/formatters/dom.d.ts +2 -1
  106. package/dist/ui/formatters/dom.js +25 -9
  107. package/dist/ui/formatters/inspect.d.ts +39 -0
  108. package/dist/ui/formatters/inspect.js +596 -0
  109. package/dist/ui/formatters/keyAttributes.d.ts +19 -0
  110. package/dist/ui/formatters/keyAttributes.js +84 -0
  111. package/dist/ui/formatters/layout.js +2 -2
  112. package/dist/ui/formatters/networkHeaders.d.ts +13 -0
  113. package/dist/ui/formatters/networkHeaders.js +23 -3
  114. package/dist/ui/formatters/networkList.d.ts +29 -1
  115. package/dist/ui/formatters/networkList.js +86 -20
  116. package/dist/ui/formatters/status.js +1 -1
  117. package/dist/ui/formatting.d.ts +9 -0
  118. package/dist/ui/formatting.js +6 -3
  119. package/dist/ui/messages/commands.d.ts +123 -7
  120. package/dist/ui/messages/commands.js +181 -10
  121. package/dist/ui/messages/networkMessages.d.ts +14 -0
  122. package/dist/ui/messages/networkMessages.js +18 -0
  123. package/dist/ui/messages/session.d.ts +14 -0
  124. package/dist/ui/messages/session.js +20 -0
  125. package/dist/utils/async.d.ts +9 -0
  126. package/dist/utils/async.js +17 -0
  127. package/dist/utils/color.d.ts +84 -0
  128. package/dist/utils/color.js +376 -0
  129. package/dist/utils/cssValues.d.ts +109 -0
  130. package/dist/utils/cssValues.js +236 -0
  131. package/dist/utils/selectorFilters.d.ts +12 -0
  132. package/dist/utils/selectorFilters.js +29 -0
  133. package/package.json +1 -1
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { indexSourceText } from '../../errors/messages.js';
5
5
  import { OutputFormatter } from '../formatting.js';
6
- import { indexLayoutHeadline, layoutHeadline, layoutPositionLabel, moreMatchesNote, pageLayoutLine, } from '../messages/commands.js';
6
+ import { coverText, indexLayoutHeadline, layoutHeadline, layoutPositionLabel, moreMatchesNote, pageLayoutLine, } from '../messages/commands.js';
7
7
  /** Elements listed in human output (JSON has up to 100) */
8
8
  const LAYOUT_DISPLAY_LIMIT = 20;
9
9
  /**
@@ -23,7 +23,7 @@ export function layoutLine(element, viewport) {
23
23
  `[${element.index}] ${element.element}${element.text ? ` "${element.text}"` : ''}`,
24
24
  element.inViewport !== 'hidden' && `${bounds.x},${bounds.y} ${bounds.width}×${bounds.height}`,
25
25
  layoutPositionLabel(element, viewport),
26
- element.coveredBy && `covered by ${element.coveredBy}`,
26
+ element.coveredBy && coverText(element.coveredBy, element.coverTransparent),
27
27
  element.inert && 'inert',
28
28
  element.invisible,
29
29
  element.context && element.context !== element.clippedBy && `in ${element.context}`,
@@ -11,4 +11,17 @@ import type { SessionNetworkHeadersData } from '../../ipc/protocol/commands.js';
11
11
  * @returns Formatted string for console output
12
12
  */
13
13
  export declare function formatNetworkHeaders(data: SessionNetworkHeadersData): string;
14
+ /**
15
+ * The values of a header, one per line. A header sent several times reaches
16
+ * CDP as one value with the values joined by newlines (`Set-Cookie`, or a
17
+ * server repeating `Strict-Transport-Security`); a value sent more than once
18
+ * is listed once, saying how often it was sent. `Set-Cookie` lines are all
19
+ * kept: each one sets a cookie, and repeating one is not the same as sending
20
+ * it once.
21
+ *
22
+ * @param name - Header name
23
+ * @param value - Header value as CDP reports it
24
+ * @returns e.g. `['max-age=63072000 (sent 2 times)']`
25
+ */
26
+ export declare function headerValueLines(name: string, value: string): string[];
14
27
  //# sourceMappingURL=networkHeaders.d.ts.map
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { formatRequestStatus } from './requestStatus.js';
7
7
  import { OutputFormatter } from '../formatting.js';
8
+ import { headerRepeatedNote } from '../messages/networkMessages.js';
8
9
  /**
9
10
  * Format network request headers for display.
10
11
  *
@@ -33,11 +34,30 @@ export function formatNetworkHeaders(data) {
33
34
  fmt.text(`Request ID: ${data.requestId}`);
34
35
  return fmt.build();
35
36
  }
37
+ /**
38
+ * The values of a header, one per line. A header sent several times reaches
39
+ * CDP as one value with the values joined by newlines (`Set-Cookie`, or a
40
+ * server repeating `Strict-Transport-Security`); a value sent more than once
41
+ * is listed once, saying how often it was sent. `Set-Cookie` lines are all
42
+ * kept: each one sets a cookie, and repeating one is not the same as sending
43
+ * it once.
44
+ *
45
+ * @param name - Header name
46
+ * @param value - Header value as CDP reports it
47
+ * @returns e.g. `['max-age=63072000 (sent 2 times)']`
48
+ */
49
+ export function headerValueLines(name, value) {
50
+ if (name.toLowerCase() === 'set-cookie')
51
+ return value.split('\n');
52
+ const counts = new Map();
53
+ for (const line of value.split('\n'))
54
+ counts.set(line, (counts.get(line) ?? 0) + 1);
55
+ return [...counts].map(([line, count]) => count > 1 ? `${line} ${headerRepeatedNote(count)}` : line);
56
+ }
36
57
  /**
37
58
  * Format a section of headers with consistent formatting.
38
59
  *
39
- * Repeated headers (CDP joins e.g. multiple `Set-Cookie` values with newlines)
40
- * are printed one per line.
60
+ * Repeated headers are printed one value per line ({@link headerValueLines}).
41
61
  *
42
62
  * @param fmt - Output formatter instance
43
63
  * @param headers - Headers to format
@@ -46,7 +66,7 @@ function formatHeaderSection(fmt, headers) {
46
66
  const entries = Object.entries(headers).sort(([a], [b]) => a.localeCompare(b));
47
67
  const keyWidth = Math.max(...entries.map(([k]) => k.length)) + 4;
48
68
  entries.forEach(([key, value]) => {
49
- value.split('\n').forEach((line) => fmt.keyValue(` ${key}`, line, keyWidth));
69
+ headerValueLines(key, value).forEach((line) => fmt.keyValue(` ${key}`, line, keyWidth));
50
70
  });
51
71
  }
52
72
  /**
@@ -7,22 +7,50 @@
7
7
  import type { NetworkRequest } from '../../types.js';
8
8
  export interface NetworkListOptions {
9
9
  verbose?: boolean;
10
+ /** Start of the current page, which the START column counts from ({@link pageStartOf}) */
11
+ pageStart?: PageStart;
10
12
  last?: number;
11
13
  totalCount?: number;
12
14
  /** Requests matching the filters, before --last (defaults to totalCount) */
13
15
  filteredCount?: number;
14
16
  }
17
+ /**
18
+ * When the current page started loading: the request of its document, in
19
+ * Chrome's monotonic time (`sentTime`, seconds) and wall-clock time
20
+ * (`timestamp`, epoch ms).
21
+ */
22
+ export type PageStart = Pick<NetworkRequest, 'sentTime' | 'timestamp'>;
23
+ /**
24
+ * The start of the current page: the earliest document request of the
25
+ * latest navigation among the requests (its earliest request when its
26
+ * document was not captured).
27
+ *
28
+ * @param requests - All captured requests (before filters, so the document is among them)
29
+ * @returns Its times, or undefined when there are no requests
30
+ */
31
+ export declare function pageStartOf(requests: NetworkRequest[]): PageStart | undefined;
32
+ /**
33
+ * Format a request's start for the START column, relative to the current
34
+ * page's start: tenths of a second up to 100 s, then whole seconds, then
35
+ * minutes.
36
+ *
37
+ * @param request - Request
38
+ * @param pageStart - Start of the current page (none: `-`)
39
+ * @returns e.g. "+0.0s", "+1.2s", "+250s", "+17m", "-35.2s" (earlier page)
40
+ */
41
+ export declare function formatStartOffset(request: NetworkRequest, pageStart: PageStart | undefined): string;
15
42
  /**
16
43
  * Rows of the network stream: requests that finished since the last poll,
17
44
  * with the column header the first time.
18
45
  *
19
46
  * @param requests - Newly finished requests
20
- * @param options - `header` the first time; `verbose` for full URLs
47
+ * @param options - `header` the first time; `verbose` for full URLs; the page start for START
21
48
  * @returns Text to print (empty when there is nothing new)
22
49
  */
23
50
  export declare function formatNetworkFollowRows(requests: NetworkRequest[], options?: {
24
51
  header?: boolean;
25
52
  verbose?: boolean;
53
+ pageStart?: PageStart;
26
54
  }): string;
27
55
  /**
28
56
  * Format network requests for display.
@@ -39,32 +39,99 @@ function formatDuration(ms) {
39
39
  return ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(1)}s`;
40
40
  }
41
41
  /**
42
- * Column header aligned to the widest request id in the list.
42
+ * The start of the current page: the earliest document request of the
43
+ * latest navigation among the requests (its earliest request when its
44
+ * document was not captured).
43
45
  *
44
- * @param idWidth - Width of the bracketed id column
46
+ * @param requests - All captured requests (before filters, so the document is among them)
47
+ * @returns Its times, or undefined when there are no requests
48
+ */
49
+ export function pageStartOf(requests) {
50
+ const navigationIds = requests.flatMap((r) => r.navigationId === undefined ? [] : [r.navigationId]);
51
+ const current = navigationIds.length > 0 ? Math.max(...navigationIds) : undefined;
52
+ const page = requests.filter((r) => r.navigationId === current);
53
+ const documents = page.filter((r) => r.resourceType === 'Document');
54
+ const first = (documents.length > 0 ? documents : page).reduce((earliest, r) => (earliest === undefined || r.timestamp < earliest.timestamp ? r : earliest), undefined);
55
+ return (first && {
56
+ timestamp: first.timestamp,
57
+ ...(first.sentTime !== undefined && { sentTime: first.sentTime }),
58
+ });
59
+ }
60
+ /**
61
+ * Milliseconds from the page start to a request's start, in Chrome's time
62
+ * when both have it (precise), else in wall-clock time.
63
+ *
64
+ * @param request - Request
65
+ * @param pageStart - Start of the current page
66
+ * @returns Offset (negative for requests of earlier pages)
67
+ */
68
+ function startOffsetMs(request, pageStart) {
69
+ if (request.sentTime !== undefined && pageStart.sentTime !== undefined) {
70
+ return (request.sentTime - pageStart.sentTime) * 1000;
71
+ }
72
+ return request.timestamp - pageStart.timestamp;
73
+ }
74
+ /**
75
+ * Format a request's start for the START column, relative to the current
76
+ * page's start: tenths of a second up to 100 s, then whole seconds, then
77
+ * minutes.
78
+ *
79
+ * @param request - Request
80
+ * @param pageStart - Start of the current page (none: `-`)
81
+ * @returns e.g. "+0.0s", "+1.2s", "+250s", "+17m", "-35.2s" (earlier page)
82
+ */
83
+ export function formatStartOffset(request, pageStart) {
84
+ if (!pageStart)
85
+ return '-';
86
+ const ms = startOffsetMs(request, pageStart);
87
+ const seconds = Math.abs(ms) / 1000;
88
+ const sign = ms < -50 ? '-' : '+';
89
+ if (seconds < 99.95)
90
+ return `${sign}${seconds.toFixed(1)}s`;
91
+ if (seconds < 999.5)
92
+ return `${sign}${Math.round(seconds)}s`;
93
+ return `${sign}${Math.floor(seconds / 60)}m`;
94
+ }
95
+ /**
96
+ * Column header aligned to the widest request id and method in the list.
97
+ *
98
+ * @param widths - Column widths
45
99
  * @returns Header line
46
100
  */
47
- function formatColumnHeader(idWidth) {
48
- return `${'[ID]'.padEnd(idWidth)} STS METH TYP ${'SIZE'.padStart(8)} ${'TIME'.padStart(6)} URL`;
101
+ function formatColumnHeader(widths) {
102
+ return `${'[ID]'.padEnd(widths.id)} ${'START'.padStart(6)} STS ${'METH'.padEnd(widths.method)} TYP ${'SIZE'.padStart(8)} ${'TIME'.padStart(6)} URL`;
49
103
  }
50
104
  /**
51
105
  * Format one request as a table row.
52
106
  *
53
107
  * @param request - Network request
54
- * @param verbose - Show full URLs
55
- * @param idWidth - Width of the bracketed id column (ids vary in length)
108
+ * @param options - Show full URLs (`verbose`), the page start for START
109
+ * @param widths - Column widths (ids and methods vary in length)
56
110
  * @returns Row text
57
111
  */
58
- function formatRequestLine(request, verbose, idWidth) {
59
- const id = `[${request.requestId}]`.padEnd(idWidth);
112
+ function formatRequestLine(request, options, widths) {
113
+ const id = `[${request.requestId}]`.padEnd(widths.id);
114
+ const start = formatStartOffset(request, options.pageStart).padStart(6);
60
115
  const status = formatStatus(request).padEnd(3);
61
- const method = request.method.padEnd(4);
116
+ const method = request.method.padEnd(widths.method);
62
117
  const type = getResourceTypeAbbr(request.resourceType, request.mimeType).padEnd(3);
63
118
  const size = formatSize(request.encodedDataLength).padStart(8);
64
119
  const time = formatDuration(request.duration).padStart(6);
65
- const urlMaxLength = verbose ? 120 : 50;
66
- const url = verbose ? request.url : truncateUrl(request.url, urlMaxLength);
67
- return `${id} ${status} ${method} ${type} ${size} ${time} ${url}`;
120
+ const url = options.verbose ? request.url : truncateUrl(request.url, 50);
121
+ return `${id} ${start} ${status} ${method} ${type} ${size} ${time} ${url}`;
122
+ }
123
+ /**
124
+ * Column widths fitting the rows.
125
+ *
126
+ * @param requests - Rows
127
+ * @param minIdWidth - Narrowest id column
128
+ * @returns Widths
129
+ */
130
+ function columnWidths(requests, minIdWidth) {
131
+ return {
132
+ id: Math.max(minIdWidth, ...requests.map((r) => r.requestId.length + 2)),
133
+ method: Math.max('METH'.length, ...requests.map((r) => r.method.length)),
134
+ };
68
135
  }
69
136
  /**
70
137
  * Header line with how many requests are shown.
@@ -91,12 +158,11 @@ function formatNetworkListHuman(requests, options) {
91
158
  fmt.text('No matching requests found.');
92
159
  return fmt.build();
93
160
  }
94
- const idWidth = Math.max('[ID]'.length, ...requests.map((r) => r.requestId.length + 2));
95
- fmt.text(formatColumnHeader(idWidth));
161
+ const widths = columnWidths(requests, '[ID]'.length);
162
+ fmt.text(formatColumnHeader(widths));
96
163
  fmt.separator('─', SEPARATOR_WIDTH);
97
- const verbose = options.verbose ?? false;
98
164
  for (const request of requests) {
99
- fmt.text(formatRequestLine(request, verbose, idWidth));
165
+ fmt.text(formatRequestLine(request, options, widths));
100
166
  }
101
167
  return fmt.build();
102
168
  }
@@ -107,19 +173,19 @@ const FOLLOW_ID_WIDTH = 14;
107
173
  * with the column header the first time.
108
174
  *
109
175
  * @param requests - Newly finished requests
110
- * @param options - `header` the first time; `verbose` for full URLs
176
+ * @param options - `header` the first time; `verbose` for full URLs; the page start for START
111
177
  * @returns Text to print (empty when there is nothing new)
112
178
  */
113
179
  export function formatNetworkFollowRows(requests, options = {}) {
114
180
  const fmt = new OutputFormatter();
115
- const idWidth = Math.max(FOLLOW_ID_WIDTH, ...requests.map((r) => r.requestId.length + 2));
181
+ const widths = columnWidths(requests, FOLLOW_ID_WIDTH);
116
182
  if (options.header) {
117
183
  fmt.text('Streaming network requests... (Ctrl+C to stop)');
118
- fmt.text(formatColumnHeader(idWidth));
184
+ fmt.text(formatColumnHeader(widths));
119
185
  fmt.separator('─', SEPARATOR_WIDTH);
120
186
  }
121
187
  for (const request of requests)
122
- fmt.text(formatRequestLine(request, options.verbose ?? false, idWidth));
188
+ fmt.text(formatRequestLine(request, options, widths));
123
189
  return fmt.build();
124
190
  }
125
191
  /**
@@ -98,7 +98,7 @@ export function appearanceLines(metadata, pageState) {
98
98
  ? [
99
99
  [
100
100
  'Viewport',
101
- `${viewport.width}×${viewport.height}${metadata.viewport ? ` (--viewport ${metadata.viewport.width}x${metadata.viewport.height})` : ''}`,
101
+ `${viewport.width}×${viewport.height}${metadata.viewport ? ` (emulated ${metadata.viewport.width}x${metadata.viewport.height})` : ''}`,
102
102
  ],
103
103
  ]
104
104
  : []),
@@ -72,6 +72,15 @@ export declare function truncateText(text: string, maxLines?: number): string;
72
72
  * @returns Shortened URL; non-web URLs (data:, blob:) cut at the end
73
73
  */
74
74
  export declare function truncateUrl(url: string, maxLength?: number): string;
75
+ /**
76
+ * Cut text in the middle, marking the cut with "…" (text that fits is
77
+ * returned as is).
78
+ *
79
+ * @param text - Text
80
+ * @param maxLength - Maximum length
81
+ * @returns Text, or its start and end around "…"
82
+ */
83
+ export declare function cutMiddle(text: string, maxLength: number): string;
75
84
  export declare function pluralize(count: number, singular: string, plural?: string): string;
76
85
  export declare function formatDuration(ms: number): string;
77
86
  //# sourceMappingURL=formatting.d.ts.map
@@ -167,13 +167,16 @@ export function truncateUrl(url, maxLength = 60) {
167
167
  /** Characters of path and query a shortened URL keeps at least besides its host */
168
168
  const MIN_URL_END_SHOWN = 12;
169
169
  /**
170
- * Cut text in the middle, marking the cut with "…".
170
+ * Cut text in the middle, marking the cut with "…" (text that fits is
171
+ * returned as is).
171
172
  *
172
173
  * @param text - Text
173
174
  * @param maxLength - Maximum length
174
- * @returns Start and end of the text around "…"
175
+ * @returns Text, or its start and end around "…"
175
176
  */
176
- function cutMiddle(text, maxLength) {
177
+ export function cutMiddle(text, maxLength) {
178
+ if (text.length <= maxLength)
179
+ return text;
177
180
  const head = Math.ceil((maxLength - 1) / 2);
178
181
  return `${text.substring(0, head)}…${text.substring(text.length - (maxLength - 1 - head))}`;
179
182
  }
@@ -5,7 +5,8 @@
5
5
  * cleaning up stale files, and validating command arguments.
6
6
  */
7
7
  import type { DomFrame, PageLoadingState, PendingRequestInfo } from '../../ipc/protocol/commands.js';
8
- import type { ElementLayout, FillValueMismatch, LayoutSize, NewMessage, PageLayout, PageNavigation } from '../../ipc/protocol/domTypes.js';
8
+ import type { ElementLayout, FillValueMismatch, LayoutSize, NewMessage, PageLayout, PageNavigation, PendingChanges, ShownElement } from '../../ipc/protocol/domTypes.js';
9
+ import type { InspectVisibility } from '../../ipc/protocol/inspectTypes.js';
9
10
  import type { DelegationNote } from '../../runtime/dom/listenerSummary.js';
10
11
  import type { WaitCondition, WaitSnapshot } from '../../runtime/dom/waitCondition.js';
11
12
  import type { DocumentRequestState, ViewportPosition } from '../../types.js';
@@ -58,12 +59,33 @@ export declare const NO_VISIBLE_EFFECT = "no visible effect observed: no DOM cha
58
59
  * Status line of a DOM action: a check mark only for a clean success.
59
60
  *
60
61
  * @param done - What was done, e.g. "Element Clicked"
61
- * @param warned - Whether the action has warnings (shown right below)
62
- * @param noEffect - Whether the action had no visible effect
63
- * @returns e.g. "✓ Element Clicked", "⚠ Element Clicked (with warnings)" or
62
+ * @param state - Whether the action has warnings (shown right below), had no
63
+ * visible effect, or returned while the page was still changing
64
+ * @returns e.g. "✓ Element Clicked", "⚠ Element Clicked (with warnings)",
65
+ * "⚠ Element Clicked (page still changing)" or
64
66
  * "⚠ Element Clicked (no visible effect observed: no DOM change, requests or navigation within 300 ms)"
65
67
  */
66
- export declare function actionStatusLine(done: string, warned: boolean, noEffect?: boolean): string;
68
+ export declare function actionStatusLine(done: string, state: {
69
+ warned: boolean;
70
+ noEffect?: boolean;
71
+ stillChanging?: boolean;
72
+ }): string;
73
+ /**
74
+ * Note under the status line of an action that returned while the page was
75
+ * still changing.
76
+ *
77
+ * @param action - What returned, e.g. "click", "key press"
78
+ * @param pending - What the page was still working on
79
+ * @returns e.g. "The page was still changing when the click returned (2 requests pending); wait for the result with bdg dom wait <selector>"
80
+ */
81
+ export declare function stillChangingNote(action: string, pending: PendingChanges): string;
82
+ /**
83
+ * An element an action showed, for its `Shown:` rows.
84
+ *
85
+ * @param element - Shown element
86
+ * @returns e.g. `div.figcaption "name: user2 View profile"`
87
+ */
88
+ export declare function shownElementText(element: ShownElement): string;
67
89
  /**
68
90
  * How an action changed the page's location, for its `Page:` row.
69
91
  *
@@ -191,7 +213,7 @@ export declare function layoutPositionLabel(element: LabelledLayout, viewport?:
191
213
  * comes from.
192
214
  *
193
215
  * @param scheme - Light or dark
194
- * @param emulated - Set with `--color-scheme` (otherwise the system setting)
216
+ * @param emulated - Set with `--color-scheme` or `page emulate` (otherwise the system setting)
195
217
  * @returns e.g. `prefers-color-scheme: dark (from the system setting)`
196
218
  */
197
219
  export declare function colorSchemeLabel(scheme: string, emulated: boolean): string;
@@ -229,6 +251,48 @@ export declare function layoutHeadline(count: number, listed: number, selector:
229
251
  * @returns e.g. `Element at index 0 of the last dom query "h3" (page x,y and size in CSS px):`
230
252
  */
231
253
  export declare function indexLayoutHeadline(target: string): string;
254
+ /** Help text explaining `bdg dom inspect`'s output notation */
255
+ export declare const INSPECT_OUTPUT_LEGEND = "\nOutput notation:\n WxH @x,y rendered border box size and page position (CSS px, no unit)\n m / p / b margin / padding / border widths, 1-4 values in CSS order (top right bottom left)\n in-parent distances to the parent's content edges (l t r b); sib: gaps to the sibling on each side\n scroll WxH the content (pseudo-elements too) is larger than the box\n 16/24 font size / line height; 'webfont loaded' = drawn with a downloaded font;\n (rendered \"X\") = drawn with another font than declared (a fallback)\n contrast 4.47 WCAG ratio, rounded down, against the background behind the text\n (+N not rendered) children with display: none (or not in the layout)\n hints declarations on this element that have no effect, why, the fix and where they are\n ('none': checked, nothing found)\n \u2190 sel (file:N) --rules: the declaration that sets the value (file:line, or file:line:column in\n minified files); 'over X': rules it beats; '= v': the value of a var() expression\n \u2713 / \u2717 --why: the winning declaration / ones it beats, highest precedence first;\n [0,2,0]: selector specificity (ids, classes, types); indented --name lines: where\n the winner's custom properties are set\nSessions follow the system color scheme; start with --color-scheme light|dark to choose.";
256
+ /**
257
+ * What covers an element: a cover that paints nothing at that point (a
258
+ * transparent box over it) does not hide it, but takes its clicks.
259
+ *
260
+ * @param cover - Description of the covering element
261
+ * @param transparent - The cover paints nothing there
262
+ * @returns e.g. `covered by div#modal`, `under transparent ul.filters (clicks land on it)`
263
+ */
264
+ export declare function coverText(cover: string, transparent: boolean | undefined): string;
265
+ /**
266
+ * Note when `bdg dom inspect` could not read the element's matched rules, so
267
+ * no hints, rules or why were computed.
268
+ *
269
+ * @param reason - `timeout` (very large stylesheets) or `failed` (Chrome reported an error)
270
+ * @returns Note
271
+ */
272
+ export declare function inspectCascadeNote(reason: 'timeout' | 'failed'): string;
273
+ /**
274
+ * Header badge of `bdg dom inspect` when the page is shown in its dark theme
275
+ * because the session follows the system's dark preference: the colors are
276
+ * the dark theme's, not what a light-mode visitor sees.
277
+ *
278
+ * @returns Badge
279
+ */
280
+ export declare function inspectDarkThemeBadge(): string;
281
+ /**
282
+ * Header badges of `bdg dom inspect` for what keeps an element from being seen.
283
+ *
284
+ * @param visibility - Not rendered, hidden, offscreen, covered
285
+ * @returns e.g. `[not rendered: display: none]`, `[offscreen: below]`, `[covered by div#modal]`
286
+ */
287
+ export declare function inspectVisibilityBadges(visibility: InspectVisibility): string[];
288
+ /**
289
+ * What `bdg dom inspect` did when several elements matched and no --index was given.
290
+ *
291
+ * @param picked - How the match was chosen
292
+ * @param index - Index of the inspected match
293
+ * @returns e.g. "inspected the first visible one ([2])"
294
+ */
295
+ export declare function inspectedMatchAction(picked: 'first-visible' | 'first', index: number): string;
232
296
  /**
233
297
  * Warning when a selector matched several elements and no --index was given.
234
298
  *
@@ -327,6 +391,13 @@ export declare const POINTER_ACTION_DONE: {
327
391
  readonly right: "Right-clicked";
328
392
  readonly hover: "Hovered";
329
393
  };
394
+ /** What each pointer action is called in notes ("when the click returned") */
395
+ export declare const POINTER_ACTION_NOUN: {
396
+ readonly click: "click";
397
+ readonly double: "double-click";
398
+ readonly right: "right-click";
399
+ readonly hover: "hover";
400
+ };
330
401
  /** Headline of each `bdg page` action */
331
402
  export declare const PAGE_ACTION_DONE: {
332
403
  readonly navigate: "Navigated";
@@ -334,9 +405,11 @@ export declare const PAGE_ACTION_DONE: {
334
405
  readonly back: "Went back";
335
406
  readonly forward: "Went forward";
336
407
  };
337
- /** Help text of the `bdg page` history commands */
338
408
  /** Description of `bdg page info` */
339
409
  export declare const PAGE_INFO_DESCRIPTION = "Show the URL and title of the session page";
410
+ /** Description of `bdg page emulate` */
411
+ export declare const PAGE_EMULATE_DESCRIPTION = "Change the viewport or color scheme mid-session (like --viewport and --color-scheme at start), or --reset both";
412
+ /** Help text of the `bdg page` history commands */
340
413
  export declare const PAGE_ACTION_DESCRIPTIONS: {
341
414
  readonly reload: "Reload the page";
342
415
  readonly back: "Go back one page (like the browser button)";
@@ -562,5 +635,48 @@ export declare function sessionStillActiveSuggestion(session: string | null): st
562
635
  * @returns Multi-line help message with examples
563
636
  * */
564
637
  export declare function startCommandHelpMessage(): string;
638
+ /**
639
+ * `bdg page emulate` without anything to change.
640
+ *
641
+ * @returns Message and suggestion
642
+ */
643
+ export declare function pageEmulateNothingError(): {
644
+ message: string;
645
+ suggestion: string;
646
+ };
647
+ /**
648
+ * Lines of `bdg page emulate`: what is emulated and what the page now has.
649
+ *
650
+ * @param result - Emulation and page appearance
651
+ * @returns Label/value pairs
652
+ */
653
+ export declare function pageEmulationLines(result: {
654
+ emulated: {
655
+ viewport?: {
656
+ width: number;
657
+ height: number;
658
+ };
659
+ colorScheme?: string;
660
+ };
661
+ viewport?: {
662
+ width: number;
663
+ height: number;
664
+ };
665
+ colorScheme?: string;
666
+ }): Array<[string, string]>;
667
+ /**
668
+ * Header badge of `bdg dom inspect` while CSS transitions or animations run
669
+ * on the element: the values read are mid-way.
670
+ *
671
+ * @param animating - Transitioned properties and animation names
672
+ * @returns e.g. `[animating: background-color; values are mid-way, inspect again]`
673
+ */
674
+ export declare function inspectAnimatingBadge(animating: readonly string[]): string;
675
+ /**
676
+ * `--why` note on a computed value read during its transition.
677
+ *
678
+ * @returns Note
679
+ */
680
+ export declare function inspectMidTransitionNote(): string;
565
681
  export {};
566
682
  //# sourceMappingURL=commands.d.ts.map