browser-debugger-cli 0.12.0 → 0.14.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/.claude/skills/bdg/SKILL.md +100 -186
- package/README.md +5 -4
- package/dist/commands/cdp.d.ts +22 -1
- package/dist/commands/cdp.js +100 -43
- package/dist/commands/console.d.ts +12 -0
- package/dist/commands/console.js +67 -13
- package/dist/commands/dom/DomElementResolver.d.ts +3 -1
- package/dist/commands/dom/DomElementResolver.js +10 -3
- package/dist/commands/dom/a11y.d.ts +1 -1
- package/dist/commands/dom/a11y.js +23 -22
- package/dist/commands/dom/eval.d.ts +4 -2
- package/dist/commands/dom/eval.js +31 -7
- package/dist/commands/dom/form.js +10 -9
- package/dist/commands/dom/formInteraction.js +9 -8
- package/dist/commands/dom/get.js +32 -14
- 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 +27 -3
- package/dist/commands/dom/helpers/query.js +152 -64
- package/dist/commands/dom/helpers/screenshot.js +13 -13
- package/dist/commands/dom/index.js +10 -3
- package/dist/commands/dom/query.d.ts +20 -2
- package/dist/commands/dom/query.js +39 -6
- package/dist/commands/dom/screenshot.js +3 -1
- package/dist/commands/dom/semanticUtils.d.ts +3 -2
- package/dist/commands/dom/semanticUtils.js +40 -9
- package/dist/commands/helpJson.d.ts +82 -19
- package/dist/commands/helpJson.js +112 -41
- package/dist/commands/helpTopic.d.ts +16 -1
- package/dist/commands/helpTopic.js +59 -1
- package/dist/commands/installSkill.d.ts +15 -5
- package/dist/commands/installSkill.js +86 -16
- package/dist/commands/network/list.js +65 -12
- package/dist/commands/optionBehaviors.d.ts +25 -2
- package/dist/commands/optionBehaviors.js +81 -46
- package/dist/commands/peek.js +3 -0
- package/dist/commands/shared/CommandRunner.js +13 -13
- package/dist/commands/shared/daemonErrorHandler.d.ts +5 -2
- package/dist/commands/shared/daemonErrorHandler.js +21 -10
- package/dist/commands/shared/dataFetcher.d.ts +14 -4
- package/dist/commands/shared/dataFetcher.js +20 -4
- package/dist/commands/shared/followMode.d.ts +9 -1
- package/dist/commands/shared/followMode.js +22 -4
- package/dist/commands/shared/handleValidationError.js +3 -3
- package/dist/commands/shared/optionTypes.d.ts +17 -3
- package/dist/commands/shared/outputFile.js +6 -1
- package/dist/commands/shared/startHelpers.js +3 -3
- package/dist/commands/start.d.ts +7 -5
- package/dist/commands/start.js +65 -21
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.js +24 -1
- package/dist/commands.js +1 -1
- package/dist/connection/cdp.d.ts +7 -0
- package/dist/connection/cdp.js +9 -0
- package/dist/connection/chromeIdentity.d.ts +8 -2
- package/dist/connection/chromeIdentity.js +85 -13
- package/dist/connection/launcher.js +3 -2
- package/dist/constants.d.ts +29 -1
- package/dist/constants.js +35 -1
- package/dist/daemon/SessionController.js +8 -1
- package/dist/daemon/launcher.d.ts +3 -2
- package/dist/daemon/launcher.js +47 -3
- package/dist/daemon/session/Session.d.ts +5 -1
- package/dist/daemon/session/Session.js +42 -3
- package/dist/daemon/session/TelemetryStore.d.ts +15 -1
- package/dist/daemon/session/TelemetryStore.js +19 -1
- package/dist/daemon/session/commandRegistry.js +52 -18
- package/dist/daemon/session/interactions.d.ts +2 -1
- package/dist/daemon/session/interactions.js +13 -1
- package/dist/daemon/session/matchedStylesReset.d.ts +26 -0
- package/dist/daemon/session/matchedStylesReset.js +46 -0
- package/dist/daemon/session/plugins.js +17 -2
- package/dist/daemon/session/teardown.js +1 -1
- package/dist/daemon/session/triggeredRequests.d.ts +0 -5
- package/dist/daemon/session/triggeredRequests.js +13 -7
- package/dist/daemon.js +2385 -1229
- package/dist/errors/messages.d.ts +62 -11
- package/dist/errors/messages.js +119 -22
- package/dist/index.js +14995 -9866
- package/dist/ipc/client.d.ts +18 -2
- package/dist/ipc/client.js +26 -5
- package/dist/ipc/protocol/auditTypes.d.ts +8 -2
- package/dist/ipc/protocol/commands.d.ts +16 -0
- package/dist/ipc/protocol/domTypes.d.ts +12 -0
- package/dist/ipc/protocol/inspectTypes.d.ts +7 -2
- package/dist/ipc/session/types.d.ts +7 -1
- package/dist/program.d.ts +14 -0
- package/dist/program.js +53 -0
- package/dist/runtime/dom/actionEffects.d.ts +5 -1
- package/dist/runtime/dom/actionEffects.js +26 -14
- package/dist/runtime/dom/audit.js +3 -2
- package/dist/runtime/dom/auditModel.js +6 -1
- package/dist/runtime/dom/auditScripts.d.ts +9 -3
- package/dist/runtime/dom/auditScripts.js +41 -5
- package/dist/runtime/dom/elementGeometry.d.ts +33 -3
- package/dist/runtime/dom/elementGeometry.js +44 -19
- package/dist/runtime/dom/elementInfo.d.ts +76 -18
- package/dist/runtime/dom/elementInfo.js +190 -40
- package/dist/runtime/dom/evalHelpers.d.ts +12 -2
- package/dist/runtime/dom/evalHelpers.js +67 -7
- package/dist/runtime/dom/formDiscovery.d.ts +6 -2
- package/dist/runtime/dom/formDiscovery.js +20 -3
- package/dist/runtime/dom/formFillHelpers/fill.js +7 -11
- package/dist/runtime/dom/formFillHelpers/pressKey.js +2 -2
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +16 -10
- package/dist/runtime/dom/formFillHelpers/shared.js +19 -52
- package/dist/runtime/dom/formSubmitHelpers.js +4 -3
- package/dist/runtime/dom/frameLayout.js +1 -0
- package/dist/runtime/dom/frameScopedConnection.d.ts +7 -0
- package/dist/runtime/dom/frameScopedConnection.js +2 -2
- package/dist/runtime/dom/inspect.d.ts +17 -3
- package/dist/runtime/dom/inspect.js +45 -32
- package/dist/runtime/dom/inspectAllStyles.js +1 -0
- package/dist/runtime/dom/inspectHints.d.ts +1 -1
- package/dist/runtime/dom/inspectModel.d.ts +5 -4
- package/dist/runtime/dom/inspectModel.js +7 -3
- package/dist/runtime/dom/inspectPaintModel.d.ts +2 -0
- package/dist/runtime/dom/inspectPaintModel.js +3 -1
- package/dist/runtime/dom/inspectRules.d.ts +29 -3
- package/dist/runtime/dom/inspectRules.js +205 -11
- package/dist/runtime/dom/inspectScripts.d.ts +29 -2
- package/dist/runtime/dom/inspectScripts.js +49 -10
- package/dist/runtime/dom/layout.d.ts +0 -2
- package/dist/runtime/dom/layout.js +10 -9
- package/dist/runtime/dom/reactEventHelpers.d.ts +17 -4
- package/dist/runtime/dom/reactEventHelpers.js +71 -28
- package/dist/runtime/dom/targetNode.d.ts +27 -10
- package/dist/runtime/dom/targetNode.js +283 -16
- package/dist/runtime/dom/wait.js +2 -1
- package/dist/runtime/page/bdgWorld.d.ts +57 -0
- package/dist/runtime/page/bdgWorld.js +180 -0
- package/dist/runtime/page/replacedBuiltins.d.ts +28 -0
- package/dist/runtime/page/replacedBuiltins.js +136 -0
- package/dist/session/QueryCacheManager.d.ts +4 -1
- package/dist/session/QueryCacheManager.js +5 -2
- package/dist/session/chrome.d.ts +4 -1
- package/dist/session/chrome.js +7 -1
- package/dist/session/cleanup/staleSession.d.ts +21 -4
- package/dist/session/cleanup/staleSession.js +79 -9
- package/dist/session/cleanup/userCommands.d.ts +4 -1
- package/dist/session/cleanup/userCommands.js +10 -5
- package/dist/session/daemonSocket.d.ts +10 -0
- package/dist/session/daemonSocket.js +22 -0
- package/dist/session/lastSession.d.ts +6 -3
- package/dist/session/lastSession.js +11 -5
- package/dist/session/paths.d.ts +3 -1
- package/dist/session/paths.js +5 -5
- package/dist/session/portClaims.js +4 -3
- package/dist/session/sessionList.d.ts +13 -5
- package/dist/session/sessionList.js +31 -7
- package/dist/telemetry/a11y.d.ts +15 -1
- package/dist/telemetry/a11y.js +85 -2
- package/dist/telemetry/console.d.ts +2 -1
- package/dist/telemetry/console.js +30 -21
- package/dist/telemetry/har/builder.js +1 -1
- package/dist/telemetry/network.d.ts +13 -16
- package/dist/telemetry/network.js +30 -52
- package/dist/telemetry/networkRetention.d.ts +83 -0
- package/dist/telemetry/networkRetention.js +117 -0
- package/dist/telemetry/pageCrash.d.ts +26 -0
- package/dist/telemetry/pageCrash.js +53 -0
- package/dist/types.d.ts +42 -0
- package/dist/ui/OutputBuilder.d.ts +10 -0
- package/dist/ui/OutputBuilder.js +12 -0
- package/dist/ui/formatters/a11y.d.ts +5 -7
- package/dist/ui/formatters/a11y.js +7 -61
- package/dist/ui/formatters/audit.js +14 -5
- package/dist/ui/formatters/cdp.d.ts +138 -0
- package/dist/ui/formatters/cdp.js +131 -0
- package/dist/ui/formatters/console/chronological.js +7 -5
- package/dist/ui/formatters/console/follow.d.ts +5 -2
- package/dist/ui/formatters/console/follow.js +7 -4
- package/dist/ui/formatters/console/json.d.ts +4 -7
- package/dist/ui/formatters/console/json.js +16 -14
- package/dist/ui/formatters/console/shared.d.ts +47 -2
- package/dist/ui/formatters/console/shared.js +33 -0
- package/dist/ui/formatters/console/summarize.d.ts +9 -2
- package/dist/ui/formatters/console/summarize.js +57 -11
- package/dist/ui/formatters/console.d.ts +3 -2
- package/dist/ui/formatters/console.js +8 -10
- package/dist/ui/formatters/details.js +4 -2
- package/dist/ui/formatters/dom.d.ts +14 -5
- package/dist/ui/formatters/dom.js +30 -13
- package/dist/ui/formatters/helpFormatters.js +1 -1
- package/dist/ui/formatters/inspect.js +9 -3
- package/dist/ui/formatters/installSkill.d.ts +9 -1
- package/dist/ui/formatters/installSkill.js +32 -6
- package/dist/ui/formatters/layout.js +4 -2
- package/dist/ui/formatters/longValues.d.ts +14 -0
- package/dist/ui/formatters/longValues.js +23 -0
- package/dist/ui/formatters/networkList.d.ts +8 -2
- package/dist/ui/formatters/networkList.js +11 -3
- package/dist/ui/formatters/preview.d.ts +6 -1
- package/dist/ui/formatters/preview.js +67 -15
- package/dist/ui/formatters/sessions.d.ts +2 -2
- package/dist/ui/formatters/sessions.js +9 -2
- package/dist/ui/formatters/status.js +7 -0
- package/dist/ui/formatters/triggeredRequests.js +2 -1
- package/dist/ui/logging/logger.d.ts +1 -1
- package/dist/ui/messages/chrome.d.ts +20 -1
- package/dist/ui/messages/chrome.js +29 -3
- package/dist/ui/messages/commands.d.ts +153 -12
- package/dist/ui/messages/commands.js +198 -15
- package/dist/ui/messages/consoleMessages.d.ts +24 -0
- package/dist/ui/messages/consoleMessages.js +32 -0
- package/dist/ui/messages/networkMessages.d.ts +24 -0
- package/dist/ui/messages/networkMessages.js +45 -0
- package/dist/ui/messages/preview.d.ts +6 -0
- package/dist/ui/messages/preview.js +9 -1
- package/dist/ui/messages/session.d.ts +13 -2
- package/dist/ui/messages/session.js +22 -3
- package/dist/utils/directories.d.ts +34 -0
- package/dist/utils/directories.js +88 -0
- package/dist/utils/display.d.ts +16 -0
- package/dist/utils/display.js +42 -0
- package/dist/utils/exitCodes.d.ts +1 -0
- package/dist/utils/exitCodes.js +6 -0
- package/dist/utils/http.d.ts +9 -2
- package/dist/utils/http.js +4 -3
- package/dist/utils/process.d.ts +12 -0
- package/dist/utils/process.js +25 -0
- package/dist/utils/strings.d.ts +19 -0
- package/dist/utils/strings.js +16 -0
- package/package.json +2 -2
|
@@ -17,10 +17,12 @@ import { inspectElement } from '../../runtime/dom/inspect.js';
|
|
|
17
17
|
import { inspectLayout } from '../../runtime/dom/layout.js';
|
|
18
18
|
import { onScriptTarget } from '../../runtime/dom/targetNode.js';
|
|
19
19
|
import { waitForCondition } from '../../runtime/dom/wait.js';
|
|
20
|
+
import { evaluateInBdgWorld, sendForBdgScript } from '../../runtime/page/bdgWorld.js';
|
|
20
21
|
import { emulatePage, pageAppearance } from '../../runtime/page/emulation.js';
|
|
21
22
|
import { readDocumentReadyState } from '../../runtime/page/loadingState.js';
|
|
22
23
|
import { navigatePage } from '../../runtime/page/navigation.js';
|
|
23
|
-
import { skippedBodyReason } from '../../telemetry/
|
|
24
|
+
import { skippedBodyReason } from '../../telemetry/networkRetention.js';
|
|
25
|
+
import { consoleMessageDroppedError } from '../../ui/messages/consoleMessages.js';
|
|
24
26
|
import { sessionCommand } from '../../ui/messages/sessionCommand.js';
|
|
25
27
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
26
28
|
import { filterDefined } from '../../utils/objects.js';
|
|
@@ -138,6 +140,20 @@ function webSocketAsRequest(connection) {
|
|
|
138
140
|
webSocket: { frames: connection.frames, ...(closedTime !== undefined && { closedTime }) },
|
|
139
141
|
};
|
|
140
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Status activity counts of what the network capture let go at its limits,
|
|
145
|
+
* left out when nothing was.
|
|
146
|
+
*
|
|
147
|
+
* @param store - Telemetry store
|
|
148
|
+
* @returns `networkRequestsDropped` and `networkBodiesEvicted` when non-zero
|
|
149
|
+
*/
|
|
150
|
+
function networkEvictionActivity(store) {
|
|
151
|
+
const { requestsDropped, bodiesEvicted } = store.networkEvictions;
|
|
152
|
+
return {
|
|
153
|
+
...(requestsDropped > 0 && { networkRequestsDropped: requestsDropped }),
|
|
154
|
+
...(bodiesEvicted > 0 && { networkBodiesEvicted: bodiesEvicted }),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
141
157
|
/**
|
|
142
158
|
* All captured network activity: finished and in-flight requests and
|
|
143
159
|
* WebSocket connections, in start order.
|
|
@@ -187,24 +203,28 @@ function findNetworkRequestOrThrow(store, id) {
|
|
|
187
203
|
return request;
|
|
188
204
|
}
|
|
189
205
|
/**
|
|
190
|
-
* Find console message by index or throw.
|
|
206
|
+
* Find console message by its session index or throw.
|
|
191
207
|
*
|
|
192
|
-
* @param messages -
|
|
208
|
+
* @param messages - Console messages kept
|
|
193
209
|
* @param indexStr - Index as string
|
|
210
|
+
* @param dropped - Messages dropped before the first kept one (its index)
|
|
194
211
|
* @returns Found message
|
|
195
|
-
* @throws
|
|
212
|
+
* @throws CommandError if the index is invalid, dropped or not found
|
|
196
213
|
*/
|
|
197
|
-
function findConsoleMessageOrThrow(messages, indexStr) {
|
|
214
|
+
function findConsoleMessageOrThrow(messages, indexStr, dropped) {
|
|
198
215
|
if (!/^\d+$/.test(indexStr)) {
|
|
199
216
|
throw new CommandError(`Invalid console message index: ${indexStr}`, { suggestion: `Use a 0-based index from: ${sessionCommand('bdg console --list')}` }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
200
217
|
}
|
|
201
218
|
const index = parseInt(indexStr, 10);
|
|
202
|
-
if (index
|
|
219
|
+
if (index < dropped) {
|
|
220
|
+
throw new CommandError(consoleMessageDroppedError(index, dropped), { suggestion: `List messages with: ${sessionCommand('bdg console --list')}` }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
221
|
+
}
|
|
222
|
+
if (index - dropped >= messages.length) {
|
|
203
223
|
throw new CommandError(messages.length === 0
|
|
204
224
|
? `Console message not found at index: ${indexStr} (no messages captured yet)`
|
|
205
|
-
: `Console message not found at index: ${indexStr} (available:
|
|
225
|
+
: `Console message not found at index: ${indexStr} (available: ${dropped}-${dropped + messages.length - 1})`, { suggestion: `List messages with: ${sessionCommand('bdg console --list')}` }, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
206
226
|
}
|
|
207
|
-
const message = messages[index];
|
|
227
|
+
const message = messages[index - dropped];
|
|
208
228
|
if (!message) {
|
|
209
229
|
throw new CommandError(`Console message not found at index: ${indexStr}`, {}, EXIT_CODES.RESOURCE_NOT_FOUND);
|
|
210
230
|
}
|
|
@@ -312,6 +332,8 @@ export function createCommandRegistry(store, emulation) {
|
|
|
312
332
|
const allNetwork = allNetworkRequests(store);
|
|
313
333
|
const totalNetwork = allNetwork.length;
|
|
314
334
|
const totalConsole = store.consoleMessages.length;
|
|
335
|
+
const dropped = store.consoleDropped;
|
|
336
|
+
const { requestsDropped, bodiesEvicted } = store.networkEvictions;
|
|
315
337
|
const networkBounds = calculateSliceBounds(totalNetwork, lastN, offset);
|
|
316
338
|
const consoleBounds = calculateSliceBounds(totalConsole, lastN, offset);
|
|
317
339
|
const recentNetwork = params.only === 'console'
|
|
@@ -323,7 +345,7 @@ export function createCommandRegistry(store, emulation) {
|
|
|
323
345
|
? []
|
|
324
346
|
: store.consoleMessages
|
|
325
347
|
.slice(consoleBounds.start, consoleBounds.end)
|
|
326
|
-
.map((msg, i) => mapConsoleMessageToPreview(msg, consoleBounds.start + i));
|
|
348
|
+
.map((msg, i) => mapConsoleMessageToPreview(msg, dropped + consoleBounds.start + i));
|
|
327
349
|
return Promise.resolve({
|
|
328
350
|
version: VERSION,
|
|
329
351
|
startTime: store.sessionStartTime,
|
|
@@ -334,10 +356,14 @@ export function createCommandRegistry(store, emulation) {
|
|
|
334
356
|
},
|
|
335
357
|
activeTelemetry: store.activeTelemetry,
|
|
336
358
|
currentNavigationId: store.getCurrentNavigationId?.() ?? 0,
|
|
359
|
+
...(store.pageCrashedAt !== undefined && { pageCrashedAt: store.pageCrashedAt }),
|
|
337
360
|
network: recentNetwork,
|
|
338
361
|
console: recentConsole,
|
|
339
362
|
totalNetwork,
|
|
340
363
|
totalConsole,
|
|
364
|
+
...(dropped > 0 && { droppedConsole: dropped }),
|
|
365
|
+
...(requestsDropped > 0 && { droppedNetwork: requestsDropped }),
|
|
366
|
+
...(bodiesEvicted > 0 && { evictedNetworkBodies: bodiesEvicted }),
|
|
341
367
|
hasMoreNetwork: networkBounds.start > 0,
|
|
342
368
|
hasMoreConsole: consoleBounds.start > 0,
|
|
343
369
|
});
|
|
@@ -348,7 +374,7 @@ export function createCommandRegistry(store, emulation) {
|
|
|
348
374
|
return Promise.resolve({ item: withBodyNotCaptured(request) });
|
|
349
375
|
}
|
|
350
376
|
if (params.itemType === 'console') {
|
|
351
|
-
const message = findConsoleMessageOrThrow(store.consoleMessages, params.id);
|
|
377
|
+
const message = findConsoleMessageOrThrow(store.consoleMessages, params.id, store.consoleDropped);
|
|
352
378
|
return Promise.resolve({ item: message });
|
|
353
379
|
}
|
|
354
380
|
return Promise.reject(new Error(`Unknown itemType: ${String(params.itemType)}. Expected 'network' or 'console'.`));
|
|
@@ -363,15 +389,18 @@ export function createCommandRegistry(store, emulation) {
|
|
|
363
389
|
target: {
|
|
364
390
|
url: store.targetInfo?.url ?? '',
|
|
365
391
|
title: store.targetInfo?.title ?? '',
|
|
366
|
-
...(
|
|
392
|
+
...(store.pageCrashedAt === undefined
|
|
393
|
+
? await pageAppearance(cdp)
|
|
394
|
+
: { crashedAt: store.pageCrashedAt }),
|
|
367
395
|
},
|
|
368
396
|
activeTelemetry: store.activeTelemetry,
|
|
369
|
-
activity:
|
|
397
|
+
activity: {
|
|
370
398
|
networkRequestsCaptured: store.networkRequests.length,
|
|
371
399
|
consoleMessagesCaptured: store.consoleMessages.length,
|
|
372
|
-
lastNetworkRequestAt: lastNetworkRequest
|
|
373
|
-
lastConsoleMessageAt: lastConsoleMessage
|
|
374
|
-
|
|
400
|
+
...(lastNetworkRequest && { lastNetworkRequestAt: lastNetworkRequest.timestamp }),
|
|
401
|
+
...(lastConsoleMessage && { lastConsoleMessageAt: lastConsoleMessage.timestamp }),
|
|
402
|
+
...networkEvictionActivity(store),
|
|
403
|
+
},
|
|
375
404
|
navigationId: store.getCurrentNavigationId?.() ?? 0,
|
|
376
405
|
};
|
|
377
406
|
return result;
|
|
@@ -401,10 +430,15 @@ export function createCommandRegistry(store, emulation) {
|
|
|
401
430
|
});
|
|
402
431
|
},
|
|
403
432
|
cdp_call: async (cdp, params) => {
|
|
404
|
-
const
|
|
433
|
+
const send = params.isolated
|
|
434
|
+
? sendForBdgScript(cdp, params.method, params.params ?? {})
|
|
435
|
+
: cdp.send(params.method, params.params ?? {});
|
|
436
|
+
const result = await withBusyPageRecovery(cdp, send.catch((error) => {
|
|
405
437
|
throw callerError(params.method, error) ?? error;
|
|
406
438
|
}));
|
|
407
|
-
const detectionResult =
|
|
439
|
+
const detectionResult = params.isolated
|
|
440
|
+
? { shouldShow: false, pattern: undefined }
|
|
441
|
+
: patternDetector.trackCommand(params.method);
|
|
408
442
|
let hint;
|
|
409
443
|
if (detectionResult.shouldShow && detectionResult.pattern) {
|
|
410
444
|
hint = {
|
|
@@ -475,7 +509,7 @@ export function createCommandRegistry(store, emulation) {
|
|
|
475
509
|
return { emulated, ...(await pageAppearance(cdp)) };
|
|
476
510
|
},
|
|
477
511
|
dom_form_discover: async (cdp) => {
|
|
478
|
-
const response = await withBusyPageRecovery(cdp, cdp
|
|
512
|
+
const response = await withBusyPageRecovery(cdp, evaluateInBdgWorld(cdp, {
|
|
479
513
|
expression: FORM_DISCOVERY_SCRIPT,
|
|
480
514
|
returnByValue: true,
|
|
481
515
|
}));
|
|
@@ -51,7 +51,8 @@ export type InteractionRunner = <T extends object>(cdp: CDPConnection, action: (
|
|
|
51
51
|
* queued. After each one, the bound target (`window.__bdgTarget`) is removed
|
|
52
52
|
* from the page (without waiting: during a pending navigation that takes until
|
|
53
53
|
* the new page commits), and the dialogs it opened, what it changed on the
|
|
54
|
-
* page (see {@link watchActionEffects}
|
|
54
|
+
* page (see {@link watchActionEffects}; a console message logged meanwhile
|
|
55
|
+
* counts as an effect) and the network requests it
|
|
55
56
|
* triggered (see {@link watchTriggeredRequests}) are added to its result,
|
|
56
57
|
* and, when asked, what the page was still working on (see
|
|
57
58
|
* {@link pendingChanges}). They are attributed by time: a dialog or request
|
|
@@ -18,6 +18,15 @@ const log = createLogger('dom');
|
|
|
18
18
|
function succeeded(result) {
|
|
19
19
|
return !('success' in result) || result.success !== false;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Console messages the session has logged, dropped ones included.
|
|
23
|
+
*
|
|
24
|
+
* @param store - Session store
|
|
25
|
+
* @returns Count that only grows
|
|
26
|
+
*/
|
|
27
|
+
function consoleMessagesLogged(store) {
|
|
28
|
+
return store.consoleDropped + store.consoleMessages.length;
|
|
29
|
+
}
|
|
21
30
|
/**
|
|
22
31
|
* Create the runner for a session's interactions.
|
|
23
32
|
*
|
|
@@ -26,7 +35,8 @@ function succeeded(result) {
|
|
|
26
35
|
* queued. After each one, the bound target (`window.__bdgTarget`) is removed
|
|
27
36
|
* from the page (without waiting: during a pending navigation that takes until
|
|
28
37
|
* the new page commits), and the dialogs it opened, what it changed on the
|
|
29
|
-
* page (see {@link watchActionEffects}
|
|
38
|
+
* page (see {@link watchActionEffects}; a console message logged meanwhile
|
|
39
|
+
* counts as an effect) and the network requests it
|
|
30
40
|
* triggered (see {@link watchTriggeredRequests}) are added to its result,
|
|
31
41
|
* and, when asked, what the page was still working on (see
|
|
32
42
|
* {@link pendingChanges}). They are attributed by time: a dialog or request
|
|
@@ -41,6 +51,7 @@ export function createInteractionRunner(store) {
|
|
|
41
51
|
return (cdp, action, options = {}) => {
|
|
42
52
|
const run = queue.then(async () => {
|
|
43
53
|
const firstDialog = store.dialogs.length;
|
|
54
|
+
const firstConsoleMessage = consoleMessagesLogged(store);
|
|
44
55
|
const collectRequests = options.reportRequests === false ? undefined : watchTriggeredRequests(store);
|
|
45
56
|
const effects = options.reportEffects === false ? undefined : watchActionEffects(cdp);
|
|
46
57
|
try {
|
|
@@ -50,6 +61,7 @@ export function createInteractionRunner(store) {
|
|
|
50
61
|
return { ...result, ...(dialogs.length > 0 && { dialogs }) };
|
|
51
62
|
const collected = await effects?.collect({
|
|
52
63
|
dialogs: dialogs.length,
|
|
64
|
+
consoleMessages: () => consoleMessagesLogged(store) - firstConsoleMessage,
|
|
53
65
|
detectNoEffect: options.detectNoEffect === true,
|
|
54
66
|
reportShown: options.reportShown === true,
|
|
55
67
|
detectUnsettled: options.detectUnsettled === true,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dom inspect` keeps slow matched-rules answers for a few seconds, but page
|
|
3
|
+
* state such as `:checked`, `:hover` or `:focus` changes without any CDP
|
|
4
|
+
* event. Every daemon command that may change the page drops them, before
|
|
5
|
+
* and after it runs. Hooking the commands rather than the CDP methods they
|
|
6
|
+
* send keeps `dom inspect`'s own page scripts from clearing its answers, and
|
|
7
|
+
* listing the read-only commands makes a new command reset by default.
|
|
8
|
+
*/
|
|
9
|
+
import type { CDPConnection } from '../../connection/cdp.js';
|
|
10
|
+
import type { CommandName } from '../../ipc/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Commands that leave the page as it is: they read it, or only the telemetry.
|
|
13
|
+
* Any command not listed (new ones included) resets by default.
|
|
14
|
+
*/
|
|
15
|
+
export declare const KEEPS_MATCHED_STYLES: ReadonlySet<CommandName>;
|
|
16
|
+
/**
|
|
17
|
+
* Run a command, dropping the kept matched rules before and after it unless
|
|
18
|
+
* it leaves the page as it is.
|
|
19
|
+
*
|
|
20
|
+
* @param cdp - CDP connection
|
|
21
|
+
* @param name - Command name
|
|
22
|
+
* @param run - The command
|
|
23
|
+
* @returns Its result
|
|
24
|
+
*/
|
|
25
|
+
export declare function withMatchedStylesReset<T>(cdp: CDPConnection, name: CommandName, run: () => Promise<T>): Promise<T>;
|
|
26
|
+
//# sourceMappingURL=matchedStylesReset.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dom inspect` keeps slow matched-rules answers for a few seconds, but page
|
|
3
|
+
* state such as `:checked`, `:hover` or `:focus` changes without any CDP
|
|
4
|
+
* event. Every daemon command that may change the page drops them, before
|
|
5
|
+
* and after it runs. Hooking the commands rather than the CDP methods they
|
|
6
|
+
* send keeps `dom inspect`'s own page scripts from clearing its answers, and
|
|
7
|
+
* listing the read-only commands makes a new command reset by default.
|
|
8
|
+
*/
|
|
9
|
+
import { resetMatchedStyles } from '../../runtime/dom/inspectRules.js';
|
|
10
|
+
/**
|
|
11
|
+
* Commands that leave the page as it is: they read it, or only the telemetry.
|
|
12
|
+
* Any command not listed (new ones included) resets by default.
|
|
13
|
+
*/
|
|
14
|
+
export const KEEPS_MATCHED_STYLES = new Set([
|
|
15
|
+
'session_peek',
|
|
16
|
+
'session_details',
|
|
17
|
+
'session_status',
|
|
18
|
+
'session_har_data',
|
|
19
|
+
'session_network_headers',
|
|
20
|
+
'dom_frames',
|
|
21
|
+
'dom_form_discover',
|
|
22
|
+
'dom_listeners',
|
|
23
|
+
'dom_layout',
|
|
24
|
+
'dom_audit',
|
|
25
|
+
'css_search',
|
|
26
|
+
'dom_inspect',
|
|
27
|
+
]);
|
|
28
|
+
/**
|
|
29
|
+
* Run a command, dropping the kept matched rules before and after it unless
|
|
30
|
+
* it leaves the page as it is.
|
|
31
|
+
*
|
|
32
|
+
* @param cdp - CDP connection
|
|
33
|
+
* @param name - Command name
|
|
34
|
+
* @param run - The command
|
|
35
|
+
* @returns Its result
|
|
36
|
+
*/
|
|
37
|
+
export function withMatchedStylesReset(cdp, name, run) {
|
|
38
|
+
if (KEEPS_MATCHED_STYLES.has(name))
|
|
39
|
+
return run();
|
|
40
|
+
const reset = () => resetMatchedStyles(cdp);
|
|
41
|
+
reset();
|
|
42
|
+
const result = run();
|
|
43
|
+
void result.then(reset, reset);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=matchedStylesReset.js.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { hideHeadlessUserAgent } from '../../runtime/page/userAgent.js';
|
|
1
2
|
import { startConsoleCollection } from '../../telemetry/console.js';
|
|
2
3
|
import { startDialogHandling } from '../../telemetry/dialogs.js';
|
|
3
4
|
import { prepareDOMCollection } from '../../telemetry/dom.js';
|
|
4
5
|
import { startNavigationTracking } from '../../telemetry/navigation.js';
|
|
5
6
|
import { startNetworkCollection, startWebSocketCollection } from '../../telemetry/network.js';
|
|
7
|
+
import { pageCrashedCommandError, startCrashTracking } from '../../telemetry/pageCrash.js';
|
|
6
8
|
import { getErrorMessage } from '../../utils/errors.js';
|
|
7
|
-
import { hideHeadlessUserAgent } from '../../runtime/page/userAgent.js';
|
|
8
9
|
import { filterDefined } from '../../utils/objects.js';
|
|
9
10
|
/** Delay before reading the title after a same-document navigation */
|
|
10
11
|
const TITLE_REFRESH_DELAY_MS = 300;
|
|
@@ -103,6 +104,17 @@ export function createDefaultTelemetryPlugins() {
|
|
|
103
104
|
return () => undefined;
|
|
104
105
|
},
|
|
105
106
|
},
|
|
107
|
+
{
|
|
108
|
+
name: 'page-crash',
|
|
109
|
+
runAlways: true,
|
|
110
|
+
async start({ cdp, store }) {
|
|
111
|
+
return startCrashTracking(cdp, (crashedAt) => {
|
|
112
|
+
store.pageCrashedAt = crashedAt;
|
|
113
|
+
if (crashedAt !== undefined)
|
|
114
|
+
cdp.rejectPending(pageCrashedCommandError(crashedAt));
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
},
|
|
106
118
|
{
|
|
107
119
|
name: 'navigation',
|
|
108
120
|
runAlways: true,
|
|
@@ -125,6 +137,7 @@ export function createDefaultTelemetryPlugins() {
|
|
|
125
137
|
fetchAllBodies: config.includeAll ?? false,
|
|
126
138
|
getCurrentNavigationId: store.getCurrentNavigationId ?? undefined,
|
|
127
139
|
pendingRequests: store.pendingNetworkRequests,
|
|
140
|
+
evictions: store.networkEvictions,
|
|
128
141
|
...filterDefined({
|
|
129
142
|
maxBodySize: config.maxBodySize,
|
|
130
143
|
}),
|
|
@@ -143,7 +156,9 @@ export function createDefaultTelemetryPlugins() {
|
|
|
143
156
|
name: 'console',
|
|
144
157
|
telemetry: 'console',
|
|
145
158
|
async start({ cdp, config, store }) {
|
|
146
|
-
return startConsoleCollection(cdp, store.consoleMessages, config.includeAll ?? false, store.getCurrentNavigationId ?? undefined)
|
|
159
|
+
return startConsoleCollection(cdp, store.consoleMessages, config.includeAll ?? false, store.getCurrentNavigationId ?? undefined, () => {
|
|
160
|
+
store.consoleDropped++;
|
|
161
|
+
});
|
|
147
162
|
},
|
|
148
163
|
},
|
|
149
164
|
{
|
|
@@ -5,11 +5,6 @@
|
|
|
5
5
|
import type { TelemetryStore } from './TelemetryStore.js';
|
|
6
6
|
import type { TriggeredRequest } from '../../ipc/protocol/domTypes.js';
|
|
7
7
|
import type { NetworkRequest } from '../../types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Requests listed in a result (a click that loads a page triggers its whole
|
|
10
|
-
* load); notable ones ({@link isNotableRequest}) are kept before assets
|
|
11
|
-
*/
|
|
12
|
-
export declare const MAX_TRIGGERED_REQUESTS = 50;
|
|
13
8
|
/** Requests started since the watch began: the first ones, and how many more there were */
|
|
14
9
|
export interface CollectedRequests {
|
|
15
10
|
triggeredRequests: TriggeredRequest[];
|
|
@@ -2,15 +2,11 @@
|
|
|
2
2
|
* Network requests an interaction triggered, read from the session's network
|
|
3
3
|
* telemetry (no CDP listeners of its own).
|
|
4
4
|
*/
|
|
5
|
+
import { MAX_TRIGGERED_REQUESTS } from '../../constants.js';
|
|
5
6
|
import { isNotableRequest } from '../../telemetry/requestKinds.js';
|
|
6
7
|
import { failureReason, getRequestState } from '../../telemetry/requestState.js';
|
|
7
8
|
/** URLs that never reach the network (inline data, in-page objects) */
|
|
8
9
|
const LOCAL_URL_PATTERN = /^(data|blob):/i;
|
|
9
|
-
/**
|
|
10
|
-
* Requests listed in a result (a click that loads a page triggers its whole
|
|
11
|
-
* load); notable ones ({@link isNotableRequest}) are kept before assets
|
|
12
|
-
*/
|
|
13
|
-
export const MAX_TRIGGERED_REQUESTS = 50;
|
|
14
10
|
/**
|
|
15
11
|
* Start attributing requests to an interaction.
|
|
16
12
|
*
|
|
@@ -28,11 +24,12 @@ export function watchTriggeredRequests(store) {
|
|
|
28
24
|
if (!store.activeTelemetry.includes('network'))
|
|
29
25
|
return () => undefined;
|
|
30
26
|
const startedAt = Date.now();
|
|
31
|
-
const firstFinished = store
|
|
27
|
+
const firstFinished = requestsFinished(store);
|
|
32
28
|
const firstWebSocket = store.websocketConnections.length;
|
|
33
29
|
return () => {
|
|
30
|
+
const firstKept = Math.max(0, firstFinished - store.networkEvictions.requestsDropped);
|
|
34
31
|
const started = [
|
|
35
|
-
...store.networkRequests.slice(
|
|
32
|
+
...store.networkRequests.slice(firstKept).map((request) => ({ request })),
|
|
36
33
|
...[...store.pendingNetworkRequests.values()].map((pending) => ({
|
|
37
34
|
request: pending.request,
|
|
38
35
|
inFlight: true,
|
|
@@ -52,6 +49,15 @@ export function watchTriggeredRequests(store) {
|
|
|
52
49
|
};
|
|
53
50
|
};
|
|
54
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Requests the session has finished, dropped ones included.
|
|
54
|
+
*
|
|
55
|
+
* @param store - Session store
|
|
56
|
+
* @returns Count that only grows
|
|
57
|
+
*/
|
|
58
|
+
function requestsFinished(store) {
|
|
59
|
+
return store.networkEvictions.requestsDropped + store.networkRequests.length;
|
|
60
|
+
}
|
|
55
61
|
/**
|
|
56
62
|
* At most `limit` requests, notable ones first (pages, API calls, sockets,
|
|
57
63
|
* failures), then assets, still in start order.
|