chrome-devtools-mcp 0.5.1 → 0.6.1
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 +60 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Color.js +13 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ColorConverter.js +9 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Gzip.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/MapWithDefault.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ResourceType.js +0 -11
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ReturnToPanel.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/AidaClient.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/GdpClient.js +116 -59
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHost.js +3 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/Platform.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/UserMetrics.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/ArrayUtilities.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/StringUtilities.js +33 -31
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMetadata.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSModel.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParser.js +11 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParserMatchers.js +19 -13
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSRule.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSStartingStyle.js +21 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ChildTargetManager.js +30 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DOMModel.js +20 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/EventBreakpointsModel.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/HttpReasonPhraseStrings.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkManager.js +9 -41
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkRequest.js +0 -14
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PageResourceLoader.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PreloadingModel.js +7 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RehydratingConnection.js +6 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RemoteObject.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ResourceTreeModel.js +1 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ScreenCaptureModel.js +20 -18
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Target.js +7 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TraceObject.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/sdk.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.js +4 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +5 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.js +30 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIContext.js +18 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/CrUXManager.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/network_time_calculator/RequestTimeRanges.js +6 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/NamesResolver.js +7 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/LanternComputationData.js +1 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/TraceTree.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/FramesHandler.js +7 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/LayoutShiftsHandler.js +8 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/NetworkRequestsHandler.js +17 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/ScriptsHandler.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/helpers.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Timing.js +4 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Trace.js +8 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DocumentLatency.js +10 -10
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/INPBreakdown.js +12 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPBreakdown.js +11 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LegacyJavaScript.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/NetworkDependencyTree.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/types/TraceEvents.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/SourceMapsResolver.js +1 -1
- package/build/src/McpContext.js +28 -4
- package/build/src/McpResponse.js +25 -16
- package/build/src/Mutex.js +3 -6
- package/build/src/PageCollector.js +17 -6
- package/build/src/browser.js +21 -12
- package/build/src/cli.js +38 -1
- package/build/src/formatters/consoleFormatter.js +1 -1
- package/build/src/logger.js +2 -2
- package/build/src/main.js +18 -10
- package/build/src/tools/ToolDefinition.js +11 -0
- package/build/src/tools/input.js +1 -1
- package/build/src/tools/network.js +0 -1
- package/build/src/tools/pages.js +15 -5
- package/build/src/tools/performance.js +3 -3
- package/build/src/tools/screenshot.js +11 -3
- package/build/src/tools/snapshot.js +11 -5
- package/build/src/trace-processing/parse.js +1 -1
- package/package.json +5 -5
package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ScreenCaptureModel.js
CHANGED
|
@@ -3,24 +3,26 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
import { OverlayModel } from './OverlayModel.js';
|
|
5
5
|
import { SDKModel } from './SDKModel.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Manages concurrent screencast requests by queuing and prioritizing.
|
|
8
|
+
*
|
|
9
|
+
* When startScreencast is invoked:
|
|
10
|
+
* - If a screencast is currently active, the existing screencast's parameters and callbacks are
|
|
11
|
+
* saved in the #screencastOperations array.
|
|
12
|
+
* - The active screencast is then stopped.
|
|
13
|
+
* - A new screencast is initiated using the parameters and callbacks from the current startScreencast call.
|
|
14
|
+
*
|
|
15
|
+
* When stopScreencast is invoked:
|
|
16
|
+
* - The currently active screencast is stopped.
|
|
17
|
+
* - The #screencastOperations is checked for interrupted screencast operations.
|
|
18
|
+
* - If any operations are found, the latest one is started
|
|
19
|
+
* using its saved parameters and callbacks.
|
|
20
|
+
*
|
|
21
|
+
* This ensures that:
|
|
22
|
+
* - Only one screencast is active at a time.
|
|
23
|
+
* - Interrupted screencasts are resumed after the current screencast is stopped.
|
|
24
|
+
* This ensures animation previews, which use screencasting, don't disrupt ongoing remote debugging sessions. Without this mechanism, stopping a preview screencast would terminate the debugging screencast, freezing the ScreencastView.
|
|
25
|
+
**/
|
|
24
26
|
export class ScreenCaptureModel extends SDKModel {
|
|
25
27
|
#agent;
|
|
26
28
|
#nextScreencastOperationId = 1;
|
|
@@ -57,12 +57,15 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
|
|
|
57
57
|
this.#capabilitiesMask = 4 /* Capability.JS */ | 8 /* Capability.LOG */ | 16 /* Capability.NETWORK */ | 32 /* Capability.TARGET */ |
|
|
58
58
|
2048 /* Capability.INSPECTOR */ | 131072 /* Capability.IO */ | 524288 /* Capability.EVENT_BREAKPOINTS */;
|
|
59
59
|
if (parentTarget?.type() !== Type.FRAME) {
|
|
60
|
-
this.#capabilitiesMask |= 1 /* Capability.BROWSER */;
|
|
60
|
+
this.#capabilitiesMask |= 1 /* Capability.BROWSER */ | 8192 /* Capability.STORAGE */;
|
|
61
61
|
}
|
|
62
62
|
break;
|
|
63
63
|
case Type.SHARED_WORKER:
|
|
64
64
|
this.#capabilitiesMask = 4 /* Capability.JS */ | 8 /* Capability.LOG */ | 16 /* Capability.NETWORK */ | 32 /* Capability.TARGET */ |
|
|
65
65
|
131072 /* Capability.IO */ | 262144 /* Capability.MEDIA */ | 2048 /* Capability.INSPECTOR */ | 524288 /* Capability.EVENT_BREAKPOINTS */;
|
|
66
|
+
if (parentTarget?.type() !== Type.FRAME) {
|
|
67
|
+
this.#capabilitiesMask |= 8192 /* Capability.STORAGE */;
|
|
68
|
+
}
|
|
66
69
|
break;
|
|
67
70
|
case Type.SHARED_STORAGE_WORKLET:
|
|
68
71
|
this.#capabilitiesMask = 4 /* Capability.JS */ | 8 /* Capability.LOG */ | 2048 /* Capability.INSPECTOR */ | 524288 /* Capability.EVENT_BREAKPOINTS */;
|
|
@@ -70,6 +73,9 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
|
|
|
70
73
|
case Type.Worker:
|
|
71
74
|
this.#capabilitiesMask = 4 /* Capability.JS */ | 8 /* Capability.LOG */ | 16 /* Capability.NETWORK */ | 32 /* Capability.TARGET */ |
|
|
72
75
|
131072 /* Capability.IO */ | 262144 /* Capability.MEDIA */ | 256 /* Capability.EMULATION */ | 524288 /* Capability.EVENT_BREAKPOINTS */;
|
|
76
|
+
if (parentTarget?.type() !== Type.FRAME) {
|
|
77
|
+
this.#capabilitiesMask |= 8192 /* Capability.STORAGE */;
|
|
78
|
+
}
|
|
73
79
|
break;
|
|
74
80
|
case Type.WORKLET:
|
|
75
81
|
this.#capabilitiesMask = 4 /* Capability.JS */ | 8 /* Capability.LOG */ | 524288 /* Capability.EVENT_BREAKPOINTS */ | 16 /* Capability.NETWORK */;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
import * as Common from '../../core/common/common.js';
|
|
5
5
|
import { ResourceTreeModel } from './ResourceTreeModel.js';
|
|
6
|
-
|
|
6
|
+
/** A thin wrapper class, mostly to enable instanceof-based revealing of traces to open in Timeline. **/
|
|
7
7
|
export class TraceObject {
|
|
8
8
|
traceEvents;
|
|
9
9
|
metadata;
|
|
@@ -15,7 +15,7 @@ export class TraceObject {
|
|
|
15
15
|
this.metadata = metadata;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
/** Another thin wrapper class to enable revealing individual trace events (aka entries) in Timeline panel. **/
|
|
19
19
|
export class RevealableEvent {
|
|
20
20
|
event;
|
|
21
21
|
// Only Trace.Types.Events.Event are passed in, but we can't depend on that type from SDK
|
|
@@ -33,6 +33,7 @@ import * as CSSPropertyParserMatchers from './CSSPropertyParserMatchers.js';
|
|
|
33
33
|
import * as CSSQuery from './CSSQuery.js';
|
|
34
34
|
import * as CSSRule from './CSSRule.js';
|
|
35
35
|
import * as CSSScope from './CSSScope.js';
|
|
36
|
+
import * as CSSStartingStyle from './CSSStartingStyle.js';
|
|
36
37
|
import * as CSSStyleDeclaration from './CSSStyleDeclaration.js';
|
|
37
38
|
import * as CSSStyleSheetHeader from './CSSStyleSheetHeader.js';
|
|
38
39
|
import * as CSSSupports from './CSSSupports.js';
|
|
@@ -85,5 +86,5 @@ import * as Target from './Target.js';
|
|
|
85
86
|
import * as TargetManager from './TargetManager.js';
|
|
86
87
|
import * as TraceObject from './TraceObject.js';
|
|
87
88
|
import * as WebAuthnModel from './WebAuthnModel.js';
|
|
88
|
-
export { AccessibilityModel, AnimationModel, AutofillModel, CategorizedBreakpoint, ChildTargetManager, CompilerSourceMappingContentProvider, Connections, ConsoleModel, Cookie, CookieModel, CookieParser, CPUProfilerModel, CPUThrottlingManager, CSSContainerQuery, CSSFontFace, CSSLayer, CSSMatchedStyles, CSSMedia, CSSMetadata, CSSModel, CSSProperty, CSSPropertyParser, CSSPropertyParserMatchers, CSSQuery, CSSRule, CSSScope, CSSStyleDeclaration, CSSStyleSheetHeader, CSSSupports, DebuggerModel, DOMDebuggerModel, DOMModel, EmulationModel, EnhancedTracesParser, EventBreakpointsModel, FrameAssociated, FrameManager, HeapProfilerModel, IOModel, IsolateManager, IssuesModel, LayerTreeBase, LogModel, NetworkManager, NetworkRequest, OverlayColorGenerator, OverlayModel, OverlayPersistentHighlighter, PageLoad, PageResourceLoader, PaintProfiler, PerformanceMetricsModel, PreloadingModel, RehydratingConnection, // TODO(crbug.com/444191656): Exported for tests.
|
|
89
|
+
export { AccessibilityModel, AnimationModel, AutofillModel, CategorizedBreakpoint, ChildTargetManager, CompilerSourceMappingContentProvider, Connections, ConsoleModel, Cookie, CookieModel, CookieParser, CPUProfilerModel, CPUThrottlingManager, CSSContainerQuery, CSSFontFace, CSSLayer, CSSMatchedStyles, CSSMedia, CSSMetadata, CSSModel, CSSProperty, CSSPropertyParser, CSSPropertyParserMatchers, CSSQuery, CSSRule, CSSScope, CSSStartingStyle, CSSStyleDeclaration, CSSStyleSheetHeader, CSSSupports, DebuggerModel, DOMDebuggerModel, DOMModel, EmulationModel, EnhancedTracesParser, EventBreakpointsModel, FrameAssociated, FrameManager, HeapProfilerModel, IOModel, IsolateManager, IssuesModel, LayerTreeBase, LogModel, NetworkManager, NetworkRequest, OverlayColorGenerator, OverlayModel, OverlayPersistentHighlighter, PageLoad, PageResourceLoader, PaintProfiler, PerformanceMetricsModel, PreloadingModel, RehydratingConnection, // TODO(crbug.com/444191656): Exported for tests.
|
|
89
90
|
RemoteObject, Resource, ResourceTreeModel, RuntimeModel, ScreenCaptureModel, Script, SDKModel, SecurityOriginManager, ServerSentEventProtocol, ServerTiming, ServiceWorkerCacheModel, ServiceWorkerManager, SourceMap, SourceMapCache, SourceMapFunctionRanges, SourceMapManager, SourceMapScopeChainEntry, SourceMapScopesInfo, StorageBucketsModel, StorageKeyManager, Target, TargetManager, TraceObject, WebAuthnModel, };
|
|
@@ -55,15 +55,15 @@ export const UIStrings = {
|
|
|
55
55
|
/**
|
|
56
56
|
* @description Warning displayed to developers when the Geolocation API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is no longer supported.
|
|
57
57
|
*/
|
|
58
|
-
GeolocationInsecureOrigin: "`getCurrentPosition()` and `watchPosition()` no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://
|
|
58
|
+
GeolocationInsecureOrigin: "`getCurrentPosition()` and `watchPosition()` no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins/ for more details.",
|
|
59
59
|
/**
|
|
60
60
|
* @description Warning displayed to developers when the Geolocation API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is deprecated.
|
|
61
61
|
*/
|
|
62
|
-
GeolocationInsecureOriginDeprecatedNotRemoved: "`getCurrentPosition()` and `watchPosition()` are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://
|
|
62
|
+
GeolocationInsecureOriginDeprecatedNotRemoved: "`getCurrentPosition()` and `watchPosition()` are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins/ for more details.",
|
|
63
63
|
/**
|
|
64
64
|
* @description This warning occurs when the `getUserMedia()` API is invoked on an insecure (e.g., HTTP) site. This is only permitted on secure sites (e.g., HTTPS).
|
|
65
65
|
*/
|
|
66
|
-
GetUserMediaInsecureOrigin: "`getUserMedia()` no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://
|
|
66
|
+
GetUserMediaInsecureOrigin: "`getUserMedia()` no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins/ for more details.",
|
|
67
67
|
/**
|
|
68
68
|
* @description A deprecation warning shown to developers in the DevTools Issues tab when code tries to use the deprecated hostCandidate field, guiding developers to use the equivalent information in the .address and .port fields instead.
|
|
69
69
|
*/
|
|
@@ -103,7 +103,7 @@ export const UIStrings = {
|
|
|
103
103
|
/**
|
|
104
104
|
* @description Warning displayed to developers when the Notification API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is no longer supported.
|
|
105
105
|
*/
|
|
106
|
-
NotificationInsecureOrigin: "The Notification API may no longer be used from insecure origins. You should consider switching your application to a secure origin, such as HTTPS. See https://
|
|
106
|
+
NotificationInsecureOrigin: "The Notification API may no longer be used from insecure origins. You should consider switching your application to a secure origin, such as HTTPS. See https://www.chromium.org/Home/chromium-security/deprecating-powerful-features-on-insecure-origins/ for more details.",
|
|
107
107
|
/**
|
|
108
108
|
* @description Warning displayed to developers when permission to use notifications has been requested by a cross-origin iframe, to notify them that this use is no longer supported.
|
|
109
109
|
*/
|
package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js
CHANGED
|
@@ -205,7 +205,7 @@ export function registerCommands(inspectorBackend) {
|
|
|
205
205
|
inspectorBackend.registerEnum("Browser.DownloadProgressEventState", { InProgress: "inProgress", Completed: "completed", Canceled: "canceled" });
|
|
206
206
|
inspectorBackend.registerEvent("Browser.downloadProgress", ["guid", "totalBytes", "receivedBytes", "state", "filePath"]);
|
|
207
207
|
inspectorBackend.registerCommand("Browser.setPermission", [{ "name": "permission", "type": "object", "optional": false, "description": "Descriptor of permission to override.", "typeRef": "Browser.PermissionDescriptor" }, { "name": "setting", "type": "string", "optional": false, "description": "Setting of the permission.", "typeRef": "Browser.PermissionSetting" }, { "name": "origin", "type": "string", "optional": true, "description": "Requesting origin the permission applies to, all origins if not specified.", "typeRef": null }, { "name": "embeddingOrigin", "type": "string", "optional": true, "description": "Embedding origin the permission applies to. It is ignored unless the requesting origin is present and valid. If the requesting origin is provided but the embedding origin isn't, the requesting origin is used as the embedding origin.", "typeRef": null }, { "name": "browserContextId", "type": "string", "optional": true, "description": "Context to override. When omitted, default browser context is used.", "typeRef": "Browser.BrowserContextID" }], [], "Set permission settings for given requesting and embedding origins.");
|
|
208
|
-
inspectorBackend.registerCommand("Browser.grantPermissions", [{ "name": "permissions", "type": "array", "optional": false, "description": "", "typeRef": "Browser.PermissionType" }, { "name": "origin", "type": "string", "optional": true, "description": "Origin the permission applies to, all origins if not specified.", "typeRef": null }, { "name": "browserContextId", "type": "string", "optional": true, "description": "BrowserContext to override permissions. When omitted, default browser context is used.", "typeRef": "Browser.BrowserContextID" }], [], "Grant specific permissions to the given origin and reject all others.");
|
|
208
|
+
inspectorBackend.registerCommand("Browser.grantPermissions", [{ "name": "permissions", "type": "array", "optional": false, "description": "", "typeRef": "Browser.PermissionType" }, { "name": "origin", "type": "string", "optional": true, "description": "Origin the permission applies to, all origins if not specified.", "typeRef": null }, { "name": "browserContextId", "type": "string", "optional": true, "description": "BrowserContext to override permissions. When omitted, default browser context is used.", "typeRef": "Browser.BrowserContextID" }], [], "Grant specific permissions to the given origin and reject all others. Deprecated. Use setPermission instead.");
|
|
209
209
|
inspectorBackend.registerCommand("Browser.resetPermissions", [{ "name": "browserContextId", "type": "string", "optional": true, "description": "BrowserContext to reset permissions. When omitted, default browser context is used.", "typeRef": "Browser.BrowserContextID" }], [], "Reset all permission management for all origins.");
|
|
210
210
|
inspectorBackend.registerEnum("Browser.SetDownloadBehaviorRequestBehavior", { Deny: "deny", Allow: "allow", AllowAndName: "allowAndName", Default: "default" });
|
|
211
211
|
inspectorBackend.registerCommand("Browser.setDownloadBehavior", [{ "name": "behavior", "type": "string", "optional": false, "description": "Whether to allow all or deny all download requests, or use default Chrome behavior if available (otherwise deny). |allowAndName| allows download and names files according to their download guids.", "typeRef": "Browser.SetDownloadBehaviorRequestBehavior" }, { "name": "browserContextId", "type": "string", "optional": true, "description": "BrowserContext to set download behavior. When omitted, default browser context is used.", "typeRef": "Browser.BrowserContextID" }, { "name": "downloadPath", "type": "string", "optional": true, "description": "The default path to save downloaded files to. This is required if behavior is set to 'allow' or 'allowAndName'.", "typeRef": null }, { "name": "eventsEnabled", "type": "boolean", "optional": true, "description": "Whether to emit download events (defaults to false).", "typeRef": null }], [], "Set the behavior when downloading a file.");
|
|
@@ -286,7 +286,7 @@ export function registerCommands(inspectorBackend) {
|
|
|
286
286
|
inspectorBackend.registerType("CSS.Specificity", [{ "name": "a", "type": "number", "optional": false, "description": "The a component, which represents the number of ID selectors.", "typeRef": null }, { "name": "b", "type": "number", "optional": false, "description": "The b component, which represents the number of class selectors, attributes selectors, and pseudo-classes.", "typeRef": null }, { "name": "c", "type": "number", "optional": false, "description": "The c component, which represents the number of type selectors and pseudo-elements.", "typeRef": null }]);
|
|
287
287
|
inspectorBackend.registerType("CSS.SelectorList", [{ "name": "selectors", "type": "array", "optional": false, "description": "Selectors in the list.", "typeRef": "CSS.Value" }, { "name": "text", "type": "string", "optional": false, "description": "Rule selector text.", "typeRef": null }]);
|
|
288
288
|
inspectorBackend.registerType("CSS.CSSStyleSheetHeader", [{ "name": "styleSheetId", "type": "string", "optional": false, "description": "The stylesheet identifier.", "typeRef": "CSS.StyleSheetId" }, { "name": "frameId", "type": "string", "optional": false, "description": "Owner frame identifier.", "typeRef": "Page.FrameId" }, { "name": "sourceURL", "type": "string", "optional": false, "description": "Stylesheet resource URL. Empty if this is a constructed stylesheet created using new CSSStyleSheet() (but non-empty if this is a constructed stylesheet imported as a CSS module script).", "typeRef": null }, { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with the stylesheet (if any).", "typeRef": null }, { "name": "origin", "type": "string", "optional": false, "description": "Stylesheet origin.", "typeRef": "CSS.StyleSheetOrigin" }, { "name": "title", "type": "string", "optional": false, "description": "Stylesheet title.", "typeRef": null }, { "name": "ownerNode", "type": "number", "optional": true, "description": "The backend id for the owner node of the stylesheet.", "typeRef": "DOM.BackendNodeId" }, { "name": "disabled", "type": "boolean", "optional": false, "description": "Denotes whether the stylesheet is disabled.", "typeRef": null }, { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "Whether the sourceURL field value comes from the sourceURL comment.", "typeRef": null }, { "name": "isInline", "type": "boolean", "optional": false, "description": "Whether this stylesheet is created for STYLE tag by parser. This flag is not set for document.written STYLE tags.", "typeRef": null }, { "name": "isMutable", "type": "boolean", "optional": false, "description": "Whether this stylesheet is mutable. Inline stylesheets become mutable after they have been modified via CSSOM API. `<link>` element's stylesheets become mutable only if DevTools modifies them. Constructed stylesheets (new CSSStyleSheet()) are mutable immediately after creation.", "typeRef": null }, { "name": "isConstructed", "type": "boolean", "optional": false, "description": "True if this stylesheet is created through new CSSStyleSheet() or imported as a CSS module script.", "typeRef": null }, { "name": "startLine", "type": "number", "optional": false, "description": "Line offset of the stylesheet within the resource (zero based).", "typeRef": null }, { "name": "startColumn", "type": "number", "optional": false, "description": "Column offset of the stylesheet within the resource (zero based).", "typeRef": null }, { "name": "length", "type": "number", "optional": false, "description": "Size of the content (in characters).", "typeRef": null }, { "name": "endLine", "type": "number", "optional": false, "description": "Line offset of the end of the stylesheet within the resource (zero based).", "typeRef": null }, { "name": "endColumn", "type": "number", "optional": false, "description": "Column offset of the end of the stylesheet within the resource (zero based).", "typeRef": null }, { "name": "loadingFailed", "type": "boolean", "optional": true, "description": "If the style sheet was loaded from a network resource, this indicates when the resource failed to load", "typeRef": null }]);
|
|
289
|
-
inspectorBackend.registerType("CSS.CSSRule", [{ "name": "styleSheetId", "type": "string", "optional": true, "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.", "typeRef": "CSS.StyleSheetId" }, { "name": "selectorList", "type": "object", "optional": false, "description": "Rule selector data.", "typeRef": "CSS.SelectorList" }, { "name": "nestingSelectors", "type": "array", "optional": true, "description": "Array of selectors from ancestor style rules, sorted by distance from the current rule.", "typeRef": "string" }, { "name": "origin", "type": "string", "optional": false, "description": "Parent stylesheet's origin.", "typeRef": "CSS.StyleSheetOrigin" }, { "name": "style", "type": "object", "optional": false, "description": "Associated style declaration.", "typeRef": "CSS.CSSStyle" }, { "name": "media", "type": "array", "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards.", "typeRef": "CSS.CSSMedia" }, { "name": "containerQueries", "type": "array", "optional": true, "description": "Container query list array (for rules involving container queries). The array enumerates container queries starting with the innermost one, going outwards.", "typeRef": "CSS.CSSContainerQuery" }, { "name": "supports", "type": "array", "optional": true, "description": "@supports CSS at-rule array. The array enumerates @supports at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSSupports" }, { "name": "layers", "type": "array", "optional": true, "description": "Cascade layer array. Contains the layer hierarchy that this rule belongs to starting with the innermost layer and going outwards.", "typeRef": "CSS.CSSLayer" }, { "name": "scopes", "type": "array", "optional": true, "description": "@scope CSS at-rule array. The array enumerates @scope at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSScope" }, { "name": "ruleTypes", "type": "array", "optional": true, "description": "The array keeps the types of ancestor CSSRules from the innermost going outwards.", "typeRef": "CSS.CSSRuleType" }, { "name": "startingStyles", "type": "array", "optional": true, "description": "@starting-style CSS at-rule array. The array enumerates @starting-style at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSStartingStyle" }]);
|
|
289
|
+
inspectorBackend.registerType("CSS.CSSRule", [{ "name": "styleSheetId", "type": "string", "optional": true, "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.", "typeRef": "CSS.StyleSheetId" }, { "name": "selectorList", "type": "object", "optional": false, "description": "Rule selector data.", "typeRef": "CSS.SelectorList" }, { "name": "nestingSelectors", "type": "array", "optional": true, "description": "Array of selectors from ancestor style rules, sorted by distance from the current rule.", "typeRef": "string" }, { "name": "origin", "type": "string", "optional": false, "description": "Parent stylesheet's origin.", "typeRef": "CSS.StyleSheetOrigin" }, { "name": "style", "type": "object", "optional": false, "description": "Associated style declaration.", "typeRef": "CSS.CSSStyle" }, { "name": "originTreeScopeNodeId", "type": "number", "optional": true, "description": "The BackendNodeId of the DOM node that constitutes the origin tree scope of this rule.", "typeRef": "DOM.BackendNodeId" }, { "name": "media", "type": "array", "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards.", "typeRef": "CSS.CSSMedia" }, { "name": "containerQueries", "type": "array", "optional": true, "description": "Container query list array (for rules involving container queries). The array enumerates container queries starting with the innermost one, going outwards.", "typeRef": "CSS.CSSContainerQuery" }, { "name": "supports", "type": "array", "optional": true, "description": "@supports CSS at-rule array. The array enumerates @supports at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSSupports" }, { "name": "layers", "type": "array", "optional": true, "description": "Cascade layer array. Contains the layer hierarchy that this rule belongs to starting with the innermost layer and going outwards.", "typeRef": "CSS.CSSLayer" }, { "name": "scopes", "type": "array", "optional": true, "description": "@scope CSS at-rule array. The array enumerates @scope at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSScope" }, { "name": "ruleTypes", "type": "array", "optional": true, "description": "The array keeps the types of ancestor CSSRules from the innermost going outwards.", "typeRef": "CSS.CSSRuleType" }, { "name": "startingStyles", "type": "array", "optional": true, "description": "@starting-style CSS at-rule array. The array enumerates @starting-style at-rules starting with the innermost one, going outwards.", "typeRef": "CSS.CSSStartingStyle" }]);
|
|
290
290
|
inspectorBackend.registerType("CSS.RuleUsage", [{ "name": "styleSheetId", "type": "string", "optional": false, "description": "The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from.", "typeRef": "CSS.StyleSheetId" }, { "name": "startOffset", "type": "number", "optional": false, "description": "Offset of the start of the rule (including selector) from the beginning of the stylesheet.", "typeRef": null }, { "name": "endOffset", "type": "number", "optional": false, "description": "Offset of the end of the rule body from the beginning of the stylesheet.", "typeRef": null }, { "name": "used", "type": "boolean", "optional": false, "description": "Indicates whether the rule was actually used by some element in the page.", "typeRef": null }]);
|
|
291
291
|
inspectorBackend.registerType("CSS.SourceRange", [{ "name": "startLine", "type": "number", "optional": false, "description": "Start line of range.", "typeRef": null }, { "name": "startColumn", "type": "number", "optional": false, "description": "Start column of range (inclusive).", "typeRef": null }, { "name": "endLine", "type": "number", "optional": false, "description": "End line of range", "typeRef": null }, { "name": "endColumn", "type": "number", "optional": false, "description": "End column of range (exclusive).", "typeRef": null }]);
|
|
292
292
|
inspectorBackend.registerType("CSS.ShorthandEntry", [{ "name": "name", "type": "string", "optional": false, "description": "Shorthand name.", "typeRef": null }, { "name": "value", "type": "string", "optional": false, "description": "Shorthand value.", "typeRef": null }, { "name": "important", "type": "boolean", "optional": true, "description": "Whether the property has \\\"!important\\\" annotation (implies `false` if absent).", "typeRef": null }]);
|
|
@@ -835,7 +835,7 @@ export function registerCommands(inspectorBackend) {
|
|
|
835
835
|
inspectorBackend.registerCommand("Network.takeResponseBodyForInterceptionAsStream", [{ "name": "interceptionId", "type": "string", "optional": false, "description": "", "typeRef": "Network.InterceptionId" }], ["stream"], "Returns a handle to the stream representing the response body. Note that after this command, the intercepted request can't be continued as is -- you either need to cancel it or to provide the response body. The stream only supports sequential read, IO.read will fail if the position is specified.");
|
|
836
836
|
inspectorBackend.registerCommand("Network.replayXHR", [{ "name": "requestId", "type": "string", "optional": false, "description": "Identifier of XHR to replay.", "typeRef": "Network.RequestId" }], [], "This method sends a new XMLHttpRequest which is identical to the original one. The following parameters should be identical: method, url, async, request body, extra headers, withCredentials attribute, user, password.");
|
|
837
837
|
inspectorBackend.registerCommand("Network.searchInResponseBody", [{ "name": "requestId", "type": "string", "optional": false, "description": "Identifier of the network response to search.", "typeRef": "Network.RequestId" }, { "name": "query", "type": "string", "optional": false, "description": "String to search for.", "typeRef": null }, { "name": "caseSensitive", "type": "boolean", "optional": true, "description": "If true, search is case sensitive.", "typeRef": null }, { "name": "isRegex", "type": "boolean", "optional": true, "description": "If true, treats string parameter as regex.", "typeRef": null }], ["result"], "Searches for given string in response content.");
|
|
838
|
-
inspectorBackend.registerCommand("Network.setBlockedURLs", [{ "name": "urls", "type": "array", "optional":
|
|
838
|
+
inspectorBackend.registerCommand("Network.setBlockedURLs", [{ "name": "urlPatterns", "type": "array", "optional": true, "description": "URL patterns to block. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/). Example: `*://*:*/*.css`.", "typeRef": "string" }, { "name": "urls", "type": "array", "optional": true, "description": "URL patterns to block. Wildcards ('*') are allowed.", "typeRef": "string" }], [], "Blocks URLs from loading.");
|
|
839
839
|
inspectorBackend.registerCommand("Network.setBypassServiceWorker", [{ "name": "bypass", "type": "boolean", "optional": false, "description": "Bypass service worker and load from network.", "typeRef": null }], [], "Toggles ignoring of service worker for each request.");
|
|
840
840
|
inspectorBackend.registerCommand("Network.setCacheDisabled", [{ "name": "cacheDisabled", "type": "boolean", "optional": false, "description": "Cache disabled state.", "typeRef": null }], [], "Toggles ignoring cache for each request. If `true`, cache will not be used.");
|
|
841
841
|
inspectorBackend.registerCommand("Network.setCookie", [{ "name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null }, { "name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null }, { "name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, source port, and source scheme values of the created cookie.", "typeRef": null }, { "name": "domain", "type": "string", "optional": true, "description": "Cookie domain.", "typeRef": null }, { "name": "path", "type": "string", "optional": true, "description": "Cookie path.", "typeRef": null }, { "name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure.", "typeRef": null }, { "name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only.", "typeRef": null }, { "name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite" }, { "name": "expires", "type": "number", "optional": true, "description": "Cookie expiration date, session cookie if not set", "typeRef": "Network.TimeSinceEpoch" }, { "name": "priority", "type": "string", "optional": true, "description": "Cookie Priority type.", "typeRef": "Network.CookiePriority" }, { "name": "sameParty", "type": "boolean", "optional": true, "description": "True if cookie is SameParty.", "typeRef": null }, { "name": "sourceScheme", "type": "string", "optional": true, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme" }, { "name": "sourcePort", "type": "number", "optional": true, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null }, { "name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key. If not set, the cookie will be set as not partitioned.", "typeRef": "Network.CookiePartitionKey" }], ["success"], "Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.");
|
|
@@ -1221,7 +1221,8 @@ export function registerCommands(inspectorBackend) {
|
|
|
1221
1221
|
inspectorBackend.registerEvent("Storage.attributionReportingTriggerRegistered", ["registration", "eventLevel", "aggregatable"]);
|
|
1222
1222
|
inspectorBackend.registerEvent("Storage.attributionReportingReportSent", ["url", "body", "result", "netError", "netErrorName", "httpStatusCode"]);
|
|
1223
1223
|
inspectorBackend.registerEvent("Storage.attributionReportingVerboseDebugReportSent", ["url", "body", "netError", "netErrorName", "httpStatusCode"]);
|
|
1224
|
-
inspectorBackend.registerCommand("Storage.getStorageKeyForFrame", [{ "name": "frameId", "type": "string", "optional": false, "description": "", "typeRef": "Page.FrameId" }], ["storageKey"], "Returns a storage key given a frame id.");
|
|
1224
|
+
inspectorBackend.registerCommand("Storage.getStorageKeyForFrame", [{ "name": "frameId", "type": "string", "optional": false, "description": "", "typeRef": "Page.FrameId" }], ["storageKey"], "Returns a storage key given a frame id. Deprecated. Please use Storage.getStorageKey instead.");
|
|
1225
|
+
inspectorBackend.registerCommand("Storage.getStorageKey", [{ "name": "frameId", "type": "string", "optional": true, "description": "", "typeRef": "Page.FrameId" }], ["storageKey"], "Returns storage key for the given frame. If no frame ID is provided, the storage key of the target executing this command is returned.");
|
|
1225
1226
|
inspectorBackend.registerCommand("Storage.clearDataForOrigin", [{ "name": "origin", "type": "string", "optional": false, "description": "Security origin.", "typeRef": null }, { "name": "storageTypes", "type": "string", "optional": false, "description": "Comma separated list of StorageType to clear.", "typeRef": null }], [], "Clears storage for origin.");
|
|
1226
1227
|
inspectorBackend.registerCommand("Storage.clearDataForStorageKey", [{ "name": "storageKey", "type": "string", "optional": false, "description": "Storage key.", "typeRef": null }, { "name": "storageTypes", "type": "string", "optional": false, "description": "Comma separated list of StorageType to clear.", "typeRef": null }], [], "Clears storage for storage key.");
|
|
1227
1228
|
inspectorBackend.registerCommand("Storage.getCookies", [{ "name": "browserContextId", "type": "string", "optional": true, "description": "Browser context to use when called on the browser endpoint.", "typeRef": "Browser.BrowserContextID" }], ["cookies"], "Returns all browser cookies.");
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
var _a;
|
|
5
5
|
import * as Logs from '../../logs/logs.js';
|
|
6
6
|
import * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
|
|
7
|
+
import * as TextUtils from '../../text_utils/text_utils.js';
|
|
7
8
|
import { seconds } from './UnitFormatters.js';
|
|
8
9
|
const MAX_HEADERS_SIZE = 1000;
|
|
10
|
+
const MAX_BODY_SIZE = 10000;
|
|
9
11
|
/**
|
|
10
12
|
* Sanitizes the set of headers, removing values that are not on the allow-list and replacing them with '<redacted>'.
|
|
11
13
|
*/
|
|
@@ -19,6 +21,7 @@ function sanitizeHeaders(headers) {
|
|
|
19
21
|
}
|
|
20
22
|
export class NetworkRequestFormatter {
|
|
21
23
|
#calculator;
|
|
24
|
+
#request;
|
|
22
25
|
static allowHeader(headerName) {
|
|
23
26
|
return allowedHeaders.has(headerName.toLowerCase().trim());
|
|
24
27
|
}
|
|
@@ -28,6 +31,23 @@ export class NetworkRequestFormatter {
|
|
|
28
31
|
return prefix + header.name + ': ' + header.value + '\n';
|
|
29
32
|
}), MAX_HEADERS_SIZE);
|
|
30
33
|
}
|
|
34
|
+
static async formatBody(title, request, maxBodySize) {
|
|
35
|
+
const data = await request.requestContentData();
|
|
36
|
+
if (TextUtils.ContentData.ContentData.isError(data)) {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
if (data.isEmpty) {
|
|
40
|
+
return `${title}\n<empty response>`;
|
|
41
|
+
}
|
|
42
|
+
if (data.isTextContent) {
|
|
43
|
+
const dataAsText = data.text;
|
|
44
|
+
if (dataAsText.length > maxBodySize) {
|
|
45
|
+
return `${title}\n${dataAsText.substring(0, maxBodySize) + '... <truncated>'}`;
|
|
46
|
+
}
|
|
47
|
+
return `${title}\n${dataAsText}`;
|
|
48
|
+
}
|
|
49
|
+
return `${title}\n<binary data>`;
|
|
50
|
+
}
|
|
31
51
|
static formatInitiatorUrl(initiatorUrl, allowedOrigin) {
|
|
32
52
|
const initiatorOrigin = new URL(initiatorUrl).origin;
|
|
33
53
|
if (initiatorOrigin === allowedOrigin) {
|
|
@@ -35,7 +55,6 @@ export class NetworkRequestFormatter {
|
|
|
35
55
|
}
|
|
36
56
|
return '<redacted cross-origin initiator URL>';
|
|
37
57
|
}
|
|
38
|
-
#request;
|
|
39
58
|
constructor(request, calculator) {
|
|
40
59
|
this.#request = request;
|
|
41
60
|
this.#calculator = calculator;
|
|
@@ -46,16 +65,24 @@ export class NetworkRequestFormatter {
|
|
|
46
65
|
formatResponseHeaders() {
|
|
47
66
|
return _a.formatHeaders('Response headers:', this.#request.responseHeaders);
|
|
48
67
|
}
|
|
68
|
+
async formatResponseBody() {
|
|
69
|
+
return await _a.formatBody('Response body:', this.#request, MAX_BODY_SIZE);
|
|
70
|
+
}
|
|
49
71
|
/**
|
|
50
72
|
* Note: nothing here should include information from origins other than
|
|
51
73
|
* the request's origin.
|
|
52
74
|
*/
|
|
53
|
-
formatNetworkRequest() {
|
|
75
|
+
async formatNetworkRequest() {
|
|
76
|
+
let responseBody = await this.formatResponseBody();
|
|
77
|
+
if (responseBody) {
|
|
78
|
+
// if we have a response then we add 2 new line to follow same structure of the context
|
|
79
|
+
responseBody = `\n\n${responseBody}`;
|
|
80
|
+
}
|
|
54
81
|
return `Request: ${this.#request.url()}
|
|
55
82
|
|
|
56
83
|
${this.formatRequestHeaders()}
|
|
57
84
|
|
|
58
|
-
${this.formatResponseHeaders()}
|
|
85
|
+
${this.formatResponseHeaders()}${responseBody}
|
|
59
86
|
|
|
60
87
|
Response status: ${this.#request.statusCode} ${this.#request.statusText}
|
|
61
88
|
|
|
@@ -3,11 +3,25 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
import * as Trace from '../../../models/trace/trace.js';
|
|
5
5
|
import { AICallTree } from './AICallTree.js';
|
|
6
|
+
/**
|
|
7
|
+
* Gets the first, most relevant InsightSet to use, following the logic of:
|
|
8
|
+
* 1. If there is only one InsightSet, use that.
|
|
9
|
+
* 2. If there are more, prefer the first we find that has a navigation associated with it.
|
|
10
|
+
* 3. If none with a navigation are found, fallback to the first one.
|
|
11
|
+
* 4. Otherwise, return null.
|
|
12
|
+
*
|
|
13
|
+
* TODO(cjamcl): we should just give the agent the entire insight set, and give
|
|
14
|
+
* summary detail about all of them + the ability to query each.
|
|
15
|
+
*/
|
|
6
16
|
function getFirstInsightSet(insights) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
const insightSets = Array.from(insights.values());
|
|
18
|
+
if (insightSets.length === 0) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (insightSets.length === 1) {
|
|
22
|
+
return insightSets[0];
|
|
23
|
+
}
|
|
24
|
+
return insightSets.filter(set => set.navigation).at(0) ?? insightSets.at(0) ?? null;
|
|
11
25
|
}
|
|
12
26
|
export class AgentFocus {
|
|
13
27
|
static fromParsedTrace(parsedTrace) {
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/CrUXManager.js
CHANGED
|
@@ -19,7 +19,7 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
19
19
|
const CRUX_API_KEY = 'AIzaSyCCSOx25vrb5z0tbedCB3_JRzzbVW6Uwgw';
|
|
20
20
|
const DEFAULT_ENDPOINT = `https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=${CRUX_API_KEY}`;
|
|
21
21
|
let cruxManagerInstance;
|
|
22
|
-
|
|
22
|
+
/** TODO: Potentially support `TABLET`. Tablet field data will always be `null` until then. **/
|
|
23
23
|
export const DEVICE_SCOPE_LIST = ['ALL', 'DESKTOP', 'PHONE'];
|
|
24
24
|
const pageScopeList = ['origin', 'url'];
|
|
25
25
|
const metrics = [
|
|
@@ -36,10 +36,12 @@ export function calculateRequestTimeRanges(request, navigationStart) {
|
|
|
36
36
|
addRange(name, startTime + (start / 1000), startTime + (end / 1000));
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/**
|
|
40
|
+
* In some situations, argument `start` may come before `startTime` (`timing.requestStart`). This is especially true
|
|
41
|
+
* in cases such as SW static routing API where fields like `workerRouterEvaluationStart` or `workerCacheLookupStart`
|
|
42
|
+
* is set before setting `timing.requestStart`. If the `start` and `end` is known to be a valid value (i.e. not default
|
|
43
|
+
* invalid value -1 or undefined), we allow adding the range.
|
|
44
|
+
**/
|
|
43
45
|
function addMaybeNegativeOffsetRange(name, start, end) {
|
|
44
46
|
addRange(name, startTime + (start / 1000), startTime + (end / 1000));
|
|
45
47
|
}
|
|
@@ -182,7 +182,7 @@ const resolveScope = async (script, scopeChain) => {
|
|
|
182
182
|
return;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
/** If there is no entry with the name field, try to infer the name from the source positions. **/
|
|
186
186
|
async function resolvePosition() {
|
|
187
187
|
if (!sourceMap) {
|
|
188
188
|
return;
|
|
@@ -556,10 +556,12 @@ export class RemoteObject extends SDK.RemoteObject.RemoteObject {
|
|
|
556
556
|
return this.object.isNode();
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Resolve the frame's function name using the name associated with the opening
|
|
561
|
+
* paren that starts the scope. If there is no name associated with the scope
|
|
562
|
+
* start or if the function scope does not start with a left paren (e.g., arrow
|
|
563
|
+
* function with one parameter), the resolution returns null.
|
|
564
|
+
**/
|
|
563
565
|
async function getFunctionNameFromScopeStart(script, lineNumber, columnNumber) {
|
|
564
566
|
// To reduce the overhead of resolving function names,
|
|
565
567
|
// we check for source maps first and immediately leave
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/LanternComputationData.js
CHANGED
|
@@ -167,6 +167,7 @@ function createLanternRequest(parsedTrace, workerThreads, request) {
|
|
|
167
167
|
priority: request.args.data.priority,
|
|
168
168
|
frameId: request.args.data.frame,
|
|
169
169
|
fromWorker,
|
|
170
|
+
serverResponseTime: request.args.data.lrServerResponseTime ?? undefined,
|
|
170
171
|
// Set later.
|
|
171
172
|
redirects: undefined,
|
|
172
173
|
redirectSource: undefined,
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/TraceTree.js
CHANGED
|
@@ -573,7 +573,7 @@ export function eventStackFrame(event) {
|
|
|
573
573
|
}
|
|
574
574
|
return { ...topFrame, scriptId: String(topFrame.scriptId) };
|
|
575
575
|
}
|
|
576
|
-
|
|
576
|
+
/** TODO(paulirish): rename to generateNodeId **/
|
|
577
577
|
export function generateEventID(event) {
|
|
578
578
|
if (Types.Events.isProfileCall(event)) {
|
|
579
579
|
const name = SamplesIntegrator.isNativeRuntimeFrame(event.callFrame) ?
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/FramesHandler.js
CHANGED
|
@@ -410,7 +410,7 @@ export class PendingFrame {
|
|
|
410
410
|
this.triggerTime = triggerTime;
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
|
-
|
|
413
|
+
/** The parameters of an impl-side BeginFrame. **/
|
|
414
414
|
class BeginFrameInfo {
|
|
415
415
|
seqId;
|
|
416
416
|
startTime;
|
|
@@ -423,10 +423,12 @@ class BeginFrameInfo {
|
|
|
423
423
|
this.isPartial = isPartial;
|
|
424
424
|
}
|
|
425
425
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
426
|
+
/**
|
|
427
|
+
* A queue of BeginFrames pending visualization.
|
|
428
|
+
* BeginFrames are added into this queue as they occur; later when their
|
|
429
|
+
* corresponding DrawFrames occur (or lack thereof), the BeginFrames are removed
|
|
430
|
+
* from the queue and their timestamps are used for visualization.
|
|
431
|
+
**/
|
|
430
432
|
export class TimelineFrameBeginFrameQueue {
|
|
431
433
|
queueFrames = [];
|
|
432
434
|
// Maps frameSeqId to BeginFrameInfo.
|
|
@@ -6,11 +6,15 @@ import * as Helpers from '../helpers/helpers.js';
|
|
|
6
6
|
import * as Types from '../types/types.js';
|
|
7
7
|
import { data as metaHandlerData } from './MetaHandler.js';
|
|
8
8
|
import { data as screenshotsHandlerData } from './ScreenshotsHandler.js';
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* This represents the maximum #time we will allow a cluster to go before we
|
|
11
|
+
* reset it.
|
|
12
|
+
**/
|
|
11
13
|
export const MAX_CLUSTER_DURATION = Helpers.Timing.milliToMicro(Types.Timing.Milli(5000));
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* This represents the maximum #time we will allow between layout shift events
|
|
16
|
+
* before considering it to be the start of a new cluster.
|
|
17
|
+
**/
|
|
14
18
|
export const MAX_SHIFT_TIME_DELTA = Helpers.Timing.milliToMicro(Types.Timing.Milli(1000));
|
|
15
19
|
// Layout shifts are reported globally to the developer, irrespective of which
|
|
16
20
|
// frame they originated in. However, each process does have its own individual
|
|
@@ -221,6 +221,7 @@ export async function finalize() {
|
|
|
221
221
|
*
|
|
222
222
|
* See `_updateTimingsForLightrider` in Lighthouse for more detail.
|
|
223
223
|
*/
|
|
224
|
+
let lrServerResponseTime;
|
|
224
225
|
if (isLightrider && request.receiveResponse?.args.data.headers) {
|
|
225
226
|
timing = {
|
|
226
227
|
requestTime: Helpers.Timing.microToSeconds(request.sendRequests.at(0)?.ts ?? 0),
|
|
@@ -254,6 +255,13 @@ export async function finalize() {
|
|
|
254
255
|
timing.connectEnd = TCPMs;
|
|
255
256
|
timing.sslEnd = TCPMs;
|
|
256
257
|
}
|
|
258
|
+
// Lightrider does not have any equivalent for `sendEnd` timing values. The
|
|
259
|
+
// closest we can get to the server response time is from a header that
|
|
260
|
+
// Lightrider sets.
|
|
261
|
+
const ResponseMsHeader = request.receiveResponse.args.data.headers.find(h => h.name === 'X-ResponseMs');
|
|
262
|
+
if (ResponseMsHeader) {
|
|
263
|
+
lrServerResponseTime = Math.max(0, parseInt(ResponseMsHeader.value, 10));
|
|
264
|
+
}
|
|
257
265
|
}
|
|
258
266
|
// TODO: consider allowing chrome / about.
|
|
259
267
|
const allowedProtocols = [
|
|
@@ -346,6 +354,13 @@ export async function finalize() {
|
|
|
346
354
|
const waiting = timing ?
|
|
347
355
|
Types.Timing.Micro((timing.receiveHeadersEnd - timing.sendEnd) * MILLISECONDS_TO_MICROSECONDS) :
|
|
348
356
|
Types.Timing.Micro(0);
|
|
357
|
+
// Server Response Time
|
|
358
|
+
// =======================
|
|
359
|
+
// Time from when the send finished going to when the first byte of headers were received.
|
|
360
|
+
const serverResponseTime = timing ?
|
|
361
|
+
Types.Timing.Micro(((timing.receiveHeadersStart ?? timing.receiveHeadersEnd) - timing.sendEnd) *
|
|
362
|
+
MILLISECONDS_TO_MICROSECONDS) :
|
|
363
|
+
Types.Timing.Micro(0);
|
|
349
364
|
// Download
|
|
350
365
|
// =======================
|
|
351
366
|
// Time from receipt of headers to the finish time.
|
|
@@ -404,6 +419,7 @@ export async function finalize() {
|
|
|
404
419
|
stalled,
|
|
405
420
|
totalTime,
|
|
406
421
|
waiting,
|
|
422
|
+
serverResponseTime,
|
|
407
423
|
},
|
|
408
424
|
// All fields below are from TraceEventsForNetworkRequest.
|
|
409
425
|
decodedBodyLength,
|
|
@@ -428,6 +444,7 @@ export async function finalize() {
|
|
|
428
444
|
initiator: finalSendRequest.args.data.initiator,
|
|
429
445
|
stackTrace: finalSendRequest.args.data.stackTrace,
|
|
430
446
|
timing,
|
|
447
|
+
lrServerResponseTime,
|
|
431
448
|
url,
|
|
432
449
|
failed: request.resourceFinish?.args.data.didFail ?? false,
|
|
433
450
|
finished: Boolean(request.resourceFinish),
|
|
@@ -17,7 +17,7 @@ export function handleEvent(event) {
|
|
|
17
17
|
const getOrMakeScript = (isolate, scriptIdAsNumber) => {
|
|
18
18
|
const scriptId = String(scriptIdAsNumber);
|
|
19
19
|
const key = `${isolate}.${scriptId}`;
|
|
20
|
-
return Platform.MapUtilities.getWithDefault(scriptById, key, () => ({ isolate, scriptId, frame: '', ts:
|
|
20
|
+
return Platform.MapUtilities.getWithDefault(scriptById, key, () => ({ isolate, scriptId, frame: '', ts: event.ts }));
|
|
21
21
|
};
|
|
22
22
|
if (Types.Events.isRundownScriptCompiled(event) && event.args.data) {
|
|
23
23
|
const { isolate, scriptId, frame } = event.args.data;
|
|
@@ -30,6 +30,7 @@ export function handleEvent(event) {
|
|
|
30
30
|
const { isolate, scriptId, url, sourceUrl, sourceMapUrl, sourceMapUrlElided } = event.args.data;
|
|
31
31
|
const script = getOrMakeScript(isolate, scriptId);
|
|
32
32
|
script.url = url;
|
|
33
|
+
script.ts = event.ts;
|
|
33
34
|
if (sourceUrl) {
|
|
34
35
|
script.sourceUrl = sourceUrl;
|
|
35
36
|
}
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/helpers.js
CHANGED
|
@@ -142,7 +142,7 @@ export function addEventToEntityMapping(event, entityMappings) {
|
|
|
142
142
|
}
|
|
143
143
|
entityMappings.entityByEvent.set(event, entity);
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
/** A slight upgrade of addEventToEntityMapping to handle the sub-events of a network request. **/
|
|
146
146
|
export function addNetworkRequestToEntityMapping(networkRequest, entityMappings, requestTraceEvents) {
|
|
147
147
|
const entity = getEntityForEvent(networkRequest, entityMappings);
|
|
148
148
|
if (!entity) {
|
package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Timing.js
CHANGED
|
@@ -25,8 +25,10 @@ export function timeStampForEventAdjustedByClosestNavigation(event, traceBounds,
|
|
|
25
25
|
}
|
|
26
26
|
return Types.Timing.Micro(eventTimeStamp);
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Expands the trace window by a provided percentage or, if it the expanded window is smaller than 1 millisecond, expands it to 1 millisecond.
|
|
30
|
+
* If the expanded window is outside of the max trace window, cut the overflowing bound to the max trace window bound.
|
|
31
|
+
**/
|
|
30
32
|
export function expandWindowByPercentOrToOneMillisecond(annotationWindow, maxTraceWindow, percentage) {
|
|
31
33
|
// Expand min and max of the window by half of the provided percentage. That way, in total, the window will be expanded by the provided percentage.
|
|
32
34
|
let newMin = annotationWindow.min - annotationWindow.range * (percentage / 100) / 2;
|
|
@@ -70,8 +70,10 @@ export function extractOriginFromTrace(firstNavigationURL) {
|
|
|
70
70
|
}
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Each thread contains events. Events indicate the thread and process IDs, which are
|
|
75
|
+
* used to store the event in the correct process thread entry below.
|
|
76
|
+
**/
|
|
75
77
|
export function addEventToProcessThread(event, eventsInProcessThread) {
|
|
76
78
|
const { tid, pid } = event;
|
|
77
79
|
let eventsInThread = eventsInProcessThread.get(pid);
|
|
@@ -704,8 +706,10 @@ export function extractSampleTraceId(event) {
|
|
|
704
706
|
}
|
|
705
707
|
return event.args?.sampleTraceId ?? event.args?.data?.sampleTraceId ?? null;
|
|
706
708
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
+
/**
|
|
710
|
+
* This exactly matches Trace.Styles.visibleTypes. See the runtime verification in maybeInitStylesMap.
|
|
711
|
+
* TODO(crbug.com/410884528)
|
|
712
|
+
**/
|
|
709
713
|
export const VISIBLE_TRACE_EVENT_TYPES = new Set([
|
|
710
714
|
"AbortPostTaskCallback" /* Types.Events.Name.ABORT_POST_TASK_CALLBACK */,
|
|
711
715
|
"Animation" /* Types.Events.Name.ANIMATION */,
|