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
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { CDPConnection } from '../../connection/cdp.js';
|
|
5
5
|
import type { PageAction, PageNavigationResult } from '../../ipc/protocol/commands.js';
|
|
6
|
+
import type { PendingRequest } from '../../telemetry/network.js';
|
|
6
7
|
import type { CDPSender } from '../../telemetry/objectExpander.js';
|
|
7
8
|
/**
|
|
8
9
|
* Navigate the session's page and wait until it has loaded.
|
|
@@ -11,17 +12,21 @@ import type { CDPSender } from '../../telemetry/objectExpander.js';
|
|
|
11
12
|
* navigation may still be waiting for the server). Otherwise the server gets
|
|
12
13
|
* {@link PAGE_READY_TIMEOUT_MS} to answer, then the new document is waited on
|
|
13
14
|
* to settle; its HTTP status is reported, with a warning for 4xx/5xx, for a
|
|
14
|
-
* URL that is a download, or a
|
|
15
|
+
* URL that is a download, or a server that has not answered. A document
|
|
16
|
+
* that has not finished loading by then is reported as `loading`, with the
|
|
17
|
+
* requests it waits on.
|
|
15
18
|
*
|
|
16
19
|
* @param cdp - CDP connection
|
|
17
20
|
* @param action - Navigate to a URL, reload, or go back/forward in history
|
|
18
|
-
* @param options - `url` for navigate, `wait: false` to return without waiting
|
|
21
|
+
* @param options - `url` for navigate, `wait: false` to return without waiting,
|
|
22
|
+
* `pendingRequests`: the session's requests still running
|
|
19
23
|
* @returns Where the page is now
|
|
20
24
|
* @throws CommandError (80) for an unreachable URL, (81) without a history entry
|
|
21
25
|
*/
|
|
22
26
|
export declare function navigatePage(cdp: CDPConnection, action: PageAction, options?: {
|
|
23
27
|
url?: string;
|
|
24
28
|
wait?: boolean;
|
|
29
|
+
pendingRequests?: () => Iterable<PendingRequest>;
|
|
25
30
|
}): Promise<PageNavigationResult>;
|
|
26
31
|
/**
|
|
27
32
|
* The URL of a navigation still waiting for the server, if any: the page
|
|
@@ -31,4 +36,43 @@ export declare function navigatePage(cdp: CDPConnection, action: PageAction, opt
|
|
|
31
36
|
* @returns The pending URL, or undefined when the page is not navigating
|
|
32
37
|
*/
|
|
33
38
|
export declare function pendingNavigationUrl(cdp: CDPSender): Promise<string | undefined>;
|
|
39
|
+
/** HTTP response of a document loaded in the main frame */
|
|
40
|
+
interface DocumentResponse {
|
|
41
|
+
status: number;
|
|
42
|
+
url: string;
|
|
43
|
+
}
|
|
44
|
+
/** Documents the main frame loaded during a navigation */
|
|
45
|
+
export interface DocumentResponses {
|
|
46
|
+
/** The navigation's own document (after HTTP redirects) */
|
|
47
|
+
first: DocumentResponse;
|
|
48
|
+
/** The last document loaded after it (a script or meta refresh moved on), if any */
|
|
49
|
+
later?: DocumentResponse;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add the HTTP status of the navigation's own document, with a warning for an
|
|
53
|
+
* error status or for a later document that answered differently (a 404 page
|
|
54
|
+
* whose script loads the app, as single-page apps on static hosts do).
|
|
55
|
+
*
|
|
56
|
+
* @param result - Navigation result
|
|
57
|
+
* @param documents - The main frame's document responses, if one arrived
|
|
58
|
+
* @returns Result with status
|
|
59
|
+
*/
|
|
60
|
+
export declare function withStatus(result: PageNavigationResult, documents: DocumentResponses | undefined): PageNavigationResult;
|
|
61
|
+
/**
|
|
62
|
+
* Watch for the responses of the main frame's documents. Only documents
|
|
63
|
+
* requested after the watch began count (a response to a request from
|
|
64
|
+
* before belongs to an earlier navigation). The navigation's own document
|
|
65
|
+
* is the one of its loader when the browser named it, else the first; the
|
|
66
|
+
* documents after it were loaded by the page itself.
|
|
67
|
+
*
|
|
68
|
+
* @param cdp - CDP connection
|
|
69
|
+
* @param mainFrameId - Main frame id
|
|
70
|
+
* @returns The responses seen so far (given the navigation's loader, if known),
|
|
71
|
+
* and a function to stop listening
|
|
72
|
+
*/
|
|
73
|
+
export declare function documentResponse(cdp: Pick<CDPConnection, 'on'>, mainFrameId: string): {
|
|
74
|
+
response: (loaderId?: string) => DocumentResponses | undefined;
|
|
75
|
+
stop: () => void;
|
|
76
|
+
};
|
|
77
|
+
export {};
|
|
34
78
|
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -5,8 +5,9 @@ import { waitForPageReady } from '../../connection/pageReadiness.js';
|
|
|
5
5
|
import { UNREACHABLE_ERRORS } from '../../daemon/session/cdpSetup.js';
|
|
6
6
|
import { CommandError } from '../../errors/index.js';
|
|
7
7
|
import { navigationFailedError, noHistoryEntryError } from '../../errors/messages.js';
|
|
8
|
+
import { readPageLoadingState } from './loadingState.js';
|
|
8
9
|
import { createLogger } from '../../ui/logging/index.js';
|
|
9
|
-
import {
|
|
10
|
+
import { documentStatusWarning, notAPageWarning, stillLoadingWarning, } from '../../ui/messages/commands.js';
|
|
10
11
|
import { delay } from '../../utils/async.js';
|
|
11
12
|
import { getErrorMessage } from '../../utils/errors.js';
|
|
12
13
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
@@ -21,11 +22,14 @@ const PAGE_READY_TIMEOUT_MS = 15_000;
|
|
|
21
22
|
* navigation may still be waiting for the server). Otherwise the server gets
|
|
22
23
|
* {@link PAGE_READY_TIMEOUT_MS} to answer, then the new document is waited on
|
|
23
24
|
* to settle; its HTTP status is reported, with a warning for 4xx/5xx, for a
|
|
24
|
-
* URL that is a download, or a
|
|
25
|
+
* URL that is a download, or a server that has not answered. A document
|
|
26
|
+
* that has not finished loading by then is reported as `loading`, with the
|
|
27
|
+
* requests it waits on.
|
|
25
28
|
*
|
|
26
29
|
* @param cdp - CDP connection
|
|
27
30
|
* @param action - Navigate to a URL, reload, or go back/forward in history
|
|
28
|
-
* @param options - `url` for navigate, `wait: false` to return without waiting
|
|
31
|
+
* @param options - `url` for navigate, `wait: false` to return without waiting,
|
|
32
|
+
* `pendingRequests`: the session's requests still running
|
|
29
33
|
* @returns Where the page is now
|
|
30
34
|
* @throws CommandError (80) for an unreachable URL, (81) without a history entry
|
|
31
35
|
*/
|
|
@@ -37,15 +41,17 @@ export async function navigatePage(cdp, action, options = {}) {
|
|
|
37
41
|
const navigated = nextNavigation(cdp, mainFrameId);
|
|
38
42
|
const document = documentResponse(cdp, mainFrameId);
|
|
39
43
|
const deadline = Date.now() + PAGE_READY_TIMEOUT_MS;
|
|
44
|
+
let loaderId;
|
|
40
45
|
try {
|
|
41
46
|
const sent = startAction(cdp, action, url);
|
|
42
47
|
sent.catch(() => undefined);
|
|
43
48
|
const started = await Promise.race([sent, delay(PAGE_READY_TIMEOUT_MS)]);
|
|
44
49
|
if (started === undefined)
|
|
45
50
|
return await stillLoading(cdp, action);
|
|
46
|
-
if (started
|
|
51
|
+
if (started.notAPage) {
|
|
47
52
|
return { action, ...(await currentLocation(cdp)), warning: notAPageWarning() };
|
|
48
53
|
}
|
|
54
|
+
loaderId = started.loaderId;
|
|
49
55
|
const how = await Promise.race([navigated.done, delay(Math.max(0, deadline - Date.now()))]);
|
|
50
56
|
if (how === 'loaded') {
|
|
51
57
|
await waitForPageReady(cdp, { maxWaitMs: Math.max(0, deadline - Date.now()) });
|
|
@@ -55,7 +61,9 @@ export async function navigatePage(cdp, action, options = {}) {
|
|
|
55
61
|
navigated.stop();
|
|
56
62
|
document.stop();
|
|
57
63
|
}
|
|
58
|
-
|
|
64
|
+
const result = withStatus({ action, ...(await currentLocation(cdp)) }, document.response(loaderId));
|
|
65
|
+
const loading = await readPageLoadingState(cdp, options.pendingRequests?.() ?? []);
|
|
66
|
+
return loading ? { ...result, loading } : result;
|
|
59
67
|
}
|
|
60
68
|
/** How long `--no-wait` waits for an action to be refused (no history entry, unreachable URL) */
|
|
61
69
|
const NO_WAIT_GRACE_MS = 1_000;
|
|
@@ -74,7 +82,7 @@ async function startWithoutWaiting(cdp, action, url) {
|
|
|
74
82
|
sent.catch((error) => log.debug(`Navigation not started: ${getErrorMessage(error)}`));
|
|
75
83
|
const started = await Promise.race([sent, delay(NO_WAIT_GRACE_MS)]);
|
|
76
84
|
const result = { action, url: url ?? (await pageTarget(cdp)).url, title: '' };
|
|
77
|
-
return started
|
|
85
|
+
return started?.notAPage ? { ...result, warning: notAPageWarning() } : result;
|
|
78
86
|
}
|
|
79
87
|
/**
|
|
80
88
|
* Send the command of an action.
|
|
@@ -82,7 +90,7 @@ async function startWithoutWaiting(cdp, action, url) {
|
|
|
82
90
|
* @param cdp - CDP connection
|
|
83
91
|
* @param action - What to do
|
|
84
92
|
* @param url - Normalized URL for navigate
|
|
85
|
-
* @returns
|
|
93
|
+
* @returns Whether a document is loading, and its loader when known
|
|
86
94
|
* @throws CommandError (80) when the URL cannot be reached, (81) without a history entry
|
|
87
95
|
*/
|
|
88
96
|
async function startAction(cdp, action, url) {
|
|
@@ -92,7 +100,7 @@ async function startAction(cdp, action, url) {
|
|
|
92
100
|
await cdp.send('Page.reload', {});
|
|
93
101
|
else
|
|
94
102
|
await goThroughHistory(cdp, action === 'back' ? -1 : 1);
|
|
95
|
-
return
|
|
103
|
+
return { notAPage: false };
|
|
96
104
|
}
|
|
97
105
|
/**
|
|
98
106
|
* The page target as the browser sees it. Unlike the page's own state, this
|
|
@@ -151,38 +159,64 @@ async function stillLoading(cdp, action) {
|
|
|
151
159
|
};
|
|
152
160
|
}
|
|
153
161
|
/**
|
|
154
|
-
* Add the
|
|
162
|
+
* Add the HTTP status of the navigation's own document, with a warning for an
|
|
163
|
+
* error status or for a later document that answered differently (a 404 page
|
|
164
|
+
* whose script loads the app, as single-page apps on static hosts do).
|
|
155
165
|
*
|
|
156
166
|
* @param result - Navigation result
|
|
157
|
-
* @param
|
|
167
|
+
* @param documents - The main frame's document responses, if one arrived
|
|
158
168
|
* @returns Result with status
|
|
159
169
|
*/
|
|
160
|
-
function withStatus(result,
|
|
161
|
-
if (!
|
|
170
|
+
export function withStatus(result, documents) {
|
|
171
|
+
if (!documents)
|
|
162
172
|
return result;
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
status: response.status,
|
|
168
|
-
...(response.status >= 400 && { warning: httpErrorWarning(response.status) }),
|
|
169
|
-
};
|
|
173
|
+
const { first, later } = documents;
|
|
174
|
+
const url = result.url.startsWith('chrome-error://') ? first.url : result.url;
|
|
175
|
+
const warning = documentStatusWarning(first.status, later);
|
|
176
|
+
return { ...result, url, status: first.status, ...(warning && { warning }) };
|
|
170
177
|
}
|
|
171
178
|
/**
|
|
172
|
-
* Watch for the
|
|
179
|
+
* Watch for the responses of the main frame's documents. Only documents
|
|
180
|
+
* requested after the watch began count (a response to a request from
|
|
181
|
+
* before belongs to an earlier navigation). The navigation's own document
|
|
182
|
+
* is the one of its loader when the browser named it, else the first; the
|
|
183
|
+
* documents after it were loaded by the page itself.
|
|
173
184
|
*
|
|
174
185
|
* @param cdp - CDP connection
|
|
175
186
|
* @param mainFrameId - Main frame id
|
|
176
|
-
* @returns The
|
|
187
|
+
* @returns The responses seen so far (given the navigation's loader, if known),
|
|
188
|
+
* and a function to stop listening
|
|
177
189
|
*/
|
|
178
|
-
function documentResponse(cdp, mainFrameId) {
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
export function documentResponse(cdp, mainFrameId) {
|
|
191
|
+
const requested = new Set();
|
|
192
|
+
const responses = [];
|
|
193
|
+
const isMainDocument = (params) => params.type === 'Document' && params.frameId === mainFrameId;
|
|
194
|
+
const stopRequests = cdp.on('Network.requestWillBeSent', (params) => {
|
|
195
|
+
if (isMainDocument(params))
|
|
196
|
+
requested.add(params.requestId);
|
|
184
197
|
});
|
|
185
|
-
|
|
198
|
+
const stopResponses = cdp.on('Network.responseReceived', (params) => {
|
|
199
|
+
if (!isMainDocument(params) || !requested.has(params.requestId))
|
|
200
|
+
return;
|
|
201
|
+
const { status, url } = params.response;
|
|
202
|
+
responses.push({ status, url, ...(params.loaderId && { loaderId: params.loaderId }) });
|
|
203
|
+
});
|
|
204
|
+
const response = (loaderId) => {
|
|
205
|
+
const index = loaderId ? responses.findIndex((r) => r.loaderId === loaderId) : 0;
|
|
206
|
+
const own = responses[index];
|
|
207
|
+
if (index < 0 || !own)
|
|
208
|
+
return undefined;
|
|
209
|
+
const last = responses.length - 1 > index ? responses[responses.length - 1] : undefined;
|
|
210
|
+
const first = { status: own.status, url: own.url };
|
|
211
|
+
return last ? { first, later: { status: last.status, url: last.url } } : { first };
|
|
212
|
+
};
|
|
213
|
+
return {
|
|
214
|
+
response,
|
|
215
|
+
stop: () => {
|
|
216
|
+
stopRequests();
|
|
217
|
+
stopResponses();
|
|
218
|
+
},
|
|
219
|
+
};
|
|
186
220
|
}
|
|
187
221
|
/**
|
|
188
222
|
* Resolve once the page has loaded a new document, moved within its
|
|
@@ -216,15 +250,17 @@ function nextNavigation(cdp, mainFrameId) {
|
|
|
216
250
|
*
|
|
217
251
|
* @param cdp - CDP connection
|
|
218
252
|
* @param url - Normalized URL
|
|
219
|
-
* @returns
|
|
253
|
+
* @returns Whether a document is loading (not for a download), and its loader
|
|
220
254
|
* @throws CommandError (80) when the URL cannot be reached
|
|
221
255
|
*/
|
|
222
256
|
async function navigateTo(cdp, url) {
|
|
223
257
|
const navigation = (await cdp.send('Page.navigate', { url }));
|
|
224
|
-
if (navigation.errorText === 'net::ERR_ABORTED' && !navigation.loaderId)
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
|
|
258
|
+
if (navigation.errorText === 'net::ERR_ABORTED' && !navigation.loaderId) {
|
|
259
|
+
return { notAPage: true };
|
|
260
|
+
}
|
|
261
|
+
if (!navigation.errorText || !UNREACHABLE_ERRORS.test(navigation.errorText)) {
|
|
262
|
+
return { notAPage: false, ...(navigation.loaderId && { loaderId: navigation.loaderId }) };
|
|
263
|
+
}
|
|
228
264
|
const err = navigationFailedError(url, navigation.errorText);
|
|
229
265
|
throw new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.INVALID_URL);
|
|
230
266
|
}
|
|
@@ -18,11 +18,21 @@
|
|
|
18
18
|
* }
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
|
-
import type { DomQueryResult } from '../types.js';
|
|
21
|
+
import type { DomQueryResult, IndexSource } from '../types.js';
|
|
22
22
|
/**
|
|
23
23
|
* Selector recorded for `dom form` results (fields carry their own selectors).
|
|
24
24
|
*/
|
|
25
25
|
export declare const FORM_DISCOVERY_CACHE_SELECTOR = "form:auto-discovered";
|
|
26
|
+
/** Prefix of the selector recorded for `dom a11y query` results (followed by the pattern) */
|
|
27
|
+
export declare const A11Y_CACHE_SELECTOR_PREFIX = "a11y ";
|
|
28
|
+
/**
|
|
29
|
+
* The list an index refers to, from the selector recorded with the cache.
|
|
30
|
+
*
|
|
31
|
+
* @param index - The index the user gave
|
|
32
|
+
* @param cacheSelector - Selector recorded with the cached results
|
|
33
|
+
* @returns The command whose results are cached, and its query
|
|
34
|
+
*/
|
|
35
|
+
export declare function indexSourceOf(index: number, cacheSelector: string): IndexSource;
|
|
26
36
|
/**
|
|
27
37
|
* Result of reading the cache.
|
|
28
38
|
*/
|
|
@@ -23,6 +23,7 @@ import { readFile, rm, writeFile } from 'fs/promises';
|
|
|
23
23
|
import { join } from 'path';
|
|
24
24
|
import { getSessionDir } from './paths.js';
|
|
25
25
|
import { createLogger } from '../ui/logging/index.js';
|
|
26
|
+
import { sessionCommand } from '../ui/messages/sessionCommand.js';
|
|
26
27
|
import { getErrorMessage } from '../utils/errors.js';
|
|
27
28
|
const log = createLogger('session');
|
|
28
29
|
/**
|
|
@@ -34,6 +35,27 @@ const CACHE_VERSION = 2;
|
|
|
34
35
|
* Selector recorded for `dom form` results (fields carry their own selectors).
|
|
35
36
|
*/
|
|
36
37
|
export const FORM_DISCOVERY_CACHE_SELECTOR = 'form:auto-discovered';
|
|
38
|
+
/** Prefix of the selector recorded for `dom a11y query` results (followed by the pattern) */
|
|
39
|
+
export const A11Y_CACHE_SELECTOR_PREFIX = 'a11y ';
|
|
40
|
+
/**
|
|
41
|
+
* The list an index refers to, from the selector recorded with the cache.
|
|
42
|
+
*
|
|
43
|
+
* @param index - The index the user gave
|
|
44
|
+
* @param cacheSelector - Selector recorded with the cached results
|
|
45
|
+
* @returns The command whose results are cached, and its query
|
|
46
|
+
*/
|
|
47
|
+
export function indexSourceOf(index, cacheSelector) {
|
|
48
|
+
if (cacheSelector === FORM_DISCOVERY_CACHE_SELECTOR)
|
|
49
|
+
return { index, command: 'dom form' };
|
|
50
|
+
if (cacheSelector.startsWith(A11Y_CACHE_SELECTOR_PREFIX)) {
|
|
51
|
+
return {
|
|
52
|
+
index,
|
|
53
|
+
command: 'dom a11y query',
|
|
54
|
+
query: cacheSelector.slice(A11Y_CACHE_SELECTOR_PREFIX.length),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { index, command: 'dom query', query: cacheSelector };
|
|
58
|
+
}
|
|
37
59
|
/**
|
|
38
60
|
* Singleton manager for the on-disk query cache.
|
|
39
61
|
*/
|
|
@@ -89,7 +111,7 @@ export class QueryCacheManager {
|
|
|
89
111
|
valid: false,
|
|
90
112
|
cache: null,
|
|
91
113
|
error: 'No cached query results found',
|
|
92
|
-
suggestion:
|
|
114
|
+
suggestion: `Run "${sessionCommand('bdg dom query <selector>')}" first to generate indexed results`,
|
|
93
115
|
};
|
|
94
116
|
}
|
|
95
117
|
const { version, ...cache } = raw;
|
|
@@ -99,8 +121,8 @@ export class QueryCacheManager {
|
|
|
99
121
|
cache: null,
|
|
100
122
|
error: 'Cached query results are from an older bdg version',
|
|
101
123
|
suggestion: cache.selector === FORM_DISCOVERY_CACHE_SELECTOR
|
|
102
|
-
?
|
|
103
|
-
: `Re-run "bdg dom query ${cache.selector}" to refresh cached results`,
|
|
124
|
+
? `Re-run "${sessionCommand('bdg dom form')}" to refresh cached results`
|
|
125
|
+
: `Re-run "${sessionCommand(`bdg dom query ${cache.selector}`)}" to refresh cached results`,
|
|
104
126
|
};
|
|
105
127
|
}
|
|
106
128
|
return { valid: true, cache };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which other bdg session uses a Chrome, so `--chrome-ws-url` never takes over
|
|
3
|
+
* a tab another session drives, nor a Chrome another session launched (and
|
|
4
|
+
* closes when it stops).
|
|
5
|
+
*
|
|
6
|
+
* Sessions are found in this base directory and, through the machine-wide
|
|
7
|
+
* port registry, in other base directories whose sessions claimed a port.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A running session and the Chrome tab it drives.
|
|
11
|
+
*/
|
|
12
|
+
export interface ChromeOwner {
|
|
13
|
+
/** Session name, or null for a default session */
|
|
14
|
+
name: string | null;
|
|
15
|
+
/** Session directory */
|
|
16
|
+
dir: string;
|
|
17
|
+
/** Base directory of the session (its `BDG_SESSION_DIR`) */
|
|
18
|
+
baseDir: string;
|
|
19
|
+
/** Target (tab) the session drives */
|
|
20
|
+
targetId: string;
|
|
21
|
+
/** Whether the session launched that Chrome (it closes Chrome when it stops) */
|
|
22
|
+
launched: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Another running session that a new session attaching to a Chrome would
|
|
26
|
+
* collide with: one that launched that Chrome, or one driving the tab the
|
|
27
|
+
* new session would use.
|
|
28
|
+
*
|
|
29
|
+
* @param chromeTargetIds - Ids of every target of the Chrome being attached to
|
|
30
|
+
* @param targetId - Tab the new session would drive
|
|
31
|
+
* @returns The conflicting session, or null
|
|
32
|
+
*/
|
|
33
|
+
export declare function findConflictingOwner(chromeTargetIds: readonly string[], targetId: string): Promise<ChromeOwner | null>;
|
|
34
|
+
//# sourceMappingURL=chromeOwners.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which other bdg session uses a Chrome, so `--chrome-ws-url` never takes over
|
|
3
|
+
* a tab another session drives, nor a Chrome another session launched (and
|
|
4
|
+
* closes when it stops).
|
|
5
|
+
*
|
|
6
|
+
* Sessions are found in this base directory and, through the machine-wide
|
|
7
|
+
* port registry, in other base directories whose sessions claimed a port.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import { probeDaemonSocket } from './daemonSocket.js';
|
|
11
|
+
import { sessionFilePathIn, sessionOfDir } from './paths.js';
|
|
12
|
+
import { otherSessionDirs } from './portClaims.js';
|
|
13
|
+
import { createLogger, logDebugError } from '../ui/logging/index.js';
|
|
14
|
+
const log = createLogger('session');
|
|
15
|
+
/**
|
|
16
|
+
* The tab a running session drives, from its metadata.
|
|
17
|
+
*
|
|
18
|
+
* @param dir - Session directory
|
|
19
|
+
* @returns Owner info, or null without a running session or metadata
|
|
20
|
+
*/
|
|
21
|
+
async function readOwner(dir) {
|
|
22
|
+
if ((await probeDaemonSocket(sessionFilePathIn(dir, 'DAEMON_SOCKET'))) !== 'alive')
|
|
23
|
+
return null;
|
|
24
|
+
try {
|
|
25
|
+
const meta = JSON.parse(fs.readFileSync(sessionFilePathIn(dir, 'METADATA'), 'utf8'));
|
|
26
|
+
if (typeof meta.targetId !== 'string')
|
|
27
|
+
return null;
|
|
28
|
+
const launched = typeof meta.chromePid === 'number' && meta.chromePid > 0;
|
|
29
|
+
return { ...sessionOfDir(dir), dir, targetId: meta.targetId, launched };
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
logDebugError(log, `read the metadata in ${dir}`, error);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Another running session that a new session attaching to a Chrome would
|
|
38
|
+
* collide with: one that launched that Chrome, or one driving the tab the
|
|
39
|
+
* new session would use.
|
|
40
|
+
*
|
|
41
|
+
* @param chromeTargetIds - Ids of every target of the Chrome being attached to
|
|
42
|
+
* @param targetId - Tab the new session would drive
|
|
43
|
+
* @returns The conflicting session, or null
|
|
44
|
+
*/
|
|
45
|
+
export async function findConflictingOwner(chromeTargetIds, targetId) {
|
|
46
|
+
const owners = await Promise.all(otherSessionDirs().map(readOwner));
|
|
47
|
+
return (owners.find((owner) => owner !== null &&
|
|
48
|
+
chromeTargetIds.includes(owner.targetId) &&
|
|
49
|
+
(owner.launched || owner.targetId === targetId)) ?? null);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=chromeOwners.js.map
|
|
@@ -26,6 +26,15 @@ export declare function removeStaleDaemonFiles(): Promise<boolean>;
|
|
|
26
26
|
* @returns Chrome PID, or null
|
|
27
27
|
*/
|
|
28
28
|
export declare function findOrphanedChrome(): number | null;
|
|
29
|
+
/**
|
|
30
|
+
* Whether a process is the Chrome bdg launched for a session directory: its
|
|
31
|
+
* command line carries the directory's marker flag.
|
|
32
|
+
*
|
|
33
|
+
* @param pid - Process ID
|
|
34
|
+
* @param sessionDir - Session directory
|
|
35
|
+
* @returns True for that session's Chrome
|
|
36
|
+
*/
|
|
37
|
+
export declare function isSessionChrome(pid: number, sessionDir: string): boolean;
|
|
29
38
|
/**
|
|
30
39
|
* Kill the Chrome recorded in chrome.pid, if it is still the Chrome bdg launched
|
|
31
40
|
* for this session directory (verified by its marker flag).
|
|
@@ -43,7 +52,8 @@ export declare function reapOrphanedChrome(): Promise<boolean>;
|
|
|
43
52
|
/**
|
|
44
53
|
* Read the PID of a live bdg daemon from daemon.pid.
|
|
45
54
|
*
|
|
55
|
+
* @param dir - Session directory (defaults to the selected session's)
|
|
46
56
|
* @returns Daemon PID if the process is alive and is a bdg daemon, else null
|
|
47
57
|
*/
|
|
48
|
-
export declare function readLiveDaemonPid(): number | null;
|
|
58
|
+
export declare function readLiveDaemonPid(dir?: string): number | null;
|
|
49
59
|
//# sourceMappingURL=staleSession.d.ts.map
|
|
@@ -10,8 +10,8 @@ import { chromeSessionMarkerFlag } from '../../connection/launcher/flagsBuilder.
|
|
|
10
10
|
import { QueryCacheManager } from '../QueryCacheManager.js';
|
|
11
11
|
import { clearChromePid, readChromePid } from '../chrome.js';
|
|
12
12
|
import { probeDaemonSocket } from '../daemonSocket.js';
|
|
13
|
-
import { getSessionDir, getSessionFilePath } from '../paths.js';
|
|
14
|
-
import {
|
|
13
|
+
import { getSessionDir, getSessionFilePath, sessionFilePathIn } from '../paths.js';
|
|
14
|
+
import { readPidFromFile } from '../pid.js';
|
|
15
15
|
import { createLogger, logDebugError } from '../../ui/logging/index.js';
|
|
16
16
|
import { delay } from '../../utils/async.js';
|
|
17
17
|
import { safeRemoveFile } from '../../utils/file.js';
|
|
@@ -66,13 +66,23 @@ export function findOrphanedChrome() {
|
|
|
66
66
|
const chromePid = readChromePid();
|
|
67
67
|
if (!chromePid)
|
|
68
68
|
return null;
|
|
69
|
-
if (
|
|
69
|
+
if (isSessionChrome(chromePid, getSessionDir()))
|
|
70
70
|
return chromePid;
|
|
71
|
-
}
|
|
72
71
|
log.debug(`PID ${chromePid} is no longer a bdg Chrome; dropping chrome.pid`);
|
|
73
72
|
clearChromePid();
|
|
74
73
|
return null;
|
|
75
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Whether a process is the Chrome bdg launched for a session directory: its
|
|
77
|
+
* command line carries the directory's marker flag.
|
|
78
|
+
*
|
|
79
|
+
* @param pid - Process ID
|
|
80
|
+
* @param sessionDir - Session directory
|
|
81
|
+
* @returns True for that session's Chrome
|
|
82
|
+
*/
|
|
83
|
+
export function isSessionChrome(pid, sessionDir) {
|
|
84
|
+
return hasArgument(getProcessCommand(pid), chromeSessionMarkerFlag(sessionDir));
|
|
85
|
+
}
|
|
76
86
|
/**
|
|
77
87
|
* Kill the Chrome recorded in chrome.pid, if it is still the Chrome bdg launched
|
|
78
88
|
* for this session directory (verified by its marker flag).
|
|
@@ -113,10 +123,11 @@ export async function reapOrphanedChrome() {
|
|
|
113
123
|
/**
|
|
114
124
|
* Read the PID of a live bdg daemon from daemon.pid.
|
|
115
125
|
*
|
|
126
|
+
* @param dir - Session directory (defaults to the selected session's)
|
|
116
127
|
* @returns Daemon PID if the process is alive and is a bdg daemon, else null
|
|
117
128
|
*/
|
|
118
|
-
export function readLiveDaemonPid() {
|
|
119
|
-
const pid =
|
|
129
|
+
export function readLiveDaemonPid(dir = getSessionDir()) {
|
|
130
|
+
const pid = readPidFromFile(sessionFilePathIn(dir, 'DAEMON_PID'));
|
|
120
131
|
if (!pid || !isProcessAlive(pid))
|
|
121
132
|
return null;
|
|
122
133
|
return hasArgument(getProcessCommand(pid), DAEMON_SCRIPT_PATH) ? pid : null;
|
|
@@ -5,7 +5,7 @@ import * as fs from 'fs';
|
|
|
5
5
|
import { killOrphanedChrome, readLiveDaemonPid, removeStaleDaemonFiles, } from './staleSession.js';
|
|
6
6
|
import { isDaemonAlive } from '../daemonSocket.js';
|
|
7
7
|
import { clearLastSessionEnd } from '../lastSession.js';
|
|
8
|
-
import { getSessionFilePath } from '../paths.js';
|
|
8
|
+
import { SESSION_STATE_FILES, getSessionFilePath } from '../paths.js';
|
|
9
9
|
import { createLogger } from '../../ui/logging/index.js';
|
|
10
10
|
import { getErrorMessage } from '../../utils/errors.js';
|
|
11
11
|
const log = createLogger('cleanup');
|
|
@@ -39,15 +39,13 @@ export async function performSessionCleanup(options) {
|
|
|
39
39
|
warnings,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
/** Files a session leaves behind (stale ones are what cleanup removes) */
|
|
43
|
-
const SESSION_FILE_TYPES = ['DAEMON_PID', 'DAEMON_SOCKET', 'CHROME_PID', 'METADATA'];
|
|
44
42
|
/**
|
|
45
43
|
* How many session files exist.
|
|
46
44
|
*
|
|
47
45
|
* @returns Number of existing session files
|
|
48
46
|
*/
|
|
49
47
|
function countSessionFiles() {
|
|
50
|
-
return
|
|
48
|
+
return SESSION_STATE_FILES.filter((type) => fs.existsSync(getSessionFilePath(type))).length;
|
|
51
49
|
}
|
|
52
50
|
/**
|
|
53
51
|
* SIGKILL a live bdg daemon and wait briefly for its socket to go away.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles reading/writing session metadata (Chrome PID, CDP port, target info, etc).
|
|
5
5
|
* WHY: Metadata persistence enables `bdg status` and other commands to inspect active sessions.
|
|
6
6
|
*/
|
|
7
|
-
import type { TelemetryType } from '../types.js';
|
|
7
|
+
import type { ColorScheme, TelemetryType, ViewportSize } from '../types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Session metadata stored in ~/.bdg/session.meta.json
|
|
10
10
|
*/
|
|
@@ -18,6 +18,10 @@ export interface SessionMetadata {
|
|
|
18
18
|
activeTelemetry?: TelemetryType[] | undefined;
|
|
19
19
|
/** When `--timeout` stops the session (epoch ms) */
|
|
20
20
|
autoStopAt?: number | undefined;
|
|
21
|
+
/** Viewport the page is emulated at (`--viewport`) */
|
|
22
|
+
viewport?: ViewportSize | undefined;
|
|
23
|
+
/** `prefers-color-scheme` the page is emulated with (`--color-scheme`) */
|
|
24
|
+
colorScheme?: ColorScheme | undefined;
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
23
27
|
* Options for reading session metadata.
|
package/dist/session/metadata.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import { createLogger } from '../ui/logging/index.js';
|
|
9
|
+
import { sessionCommand } from '../ui/messages/sessionCommand.js';
|
|
9
10
|
import { AtomicFileWriter } from '../utils/atomicFile.js';
|
|
10
11
|
import { getErrorMessage } from '../utils/errors.js';
|
|
11
12
|
import { getSessionFilePath, ensureSessionDir } from './paths.js';
|
|
@@ -20,7 +21,7 @@ const log = createLogger('session');
|
|
|
20
21
|
function handleCorruptedMetadata(metaPath, error, options) {
|
|
21
22
|
if (options?.warnOnCorruption) {
|
|
22
23
|
log.info(`Session metadata corrupted (cannot read details): ${getErrorMessage(error)}`);
|
|
23
|
-
log.info(
|
|
24
|
+
log.info(`Troubleshooting: Run "${sessionCommand('bdg cleanup')}" to remove corrupted files`);
|
|
24
25
|
}
|
|
25
26
|
if (options?.selfHealOnCorruption) {
|
|
26
27
|
try {
|