chrome-devtools-mcp 0.8.1 → 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 +69 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Console.js +1 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Gzip.js +8 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ParsedURL.js +10 -20
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/SegmentedRange.js +1 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Settings.js +4 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/StringOutputStream.js +1 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Worker.js +10 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/AidaClient.js +19 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/DispatchHttpRequestClient.js +54 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/GdpClient.js +6 -51
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHost.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHostAPI.js +32 -29
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/UserMetrics.js +15 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/host.js +2 -1
- 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/protocol_client/CDPConnection.js +17 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/ConnectionTransport.js +12 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/InspectorBackend.js +81 -213
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/protocol_client.js +3 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/AnimationModel.js +1 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMatchedStyles.js +45 -10
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSProperty.js +3 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParserMatchers.js +14 -10
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSRule.js +34 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSStyleDeclaration.js +4 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ChildTargetManager.js +8 -33
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Connections.js +10 -47
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DOMModel.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DebuggerModel.js +3 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/EnhancedTracesParser.js +17 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkManager.js +371 -53
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkRequest.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PreloadingModel.js +56 -13
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RehydratingConnection.js +133 -10
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ResourceTreeModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/{models/source_map_scopes → core/sdk}/ScopeTreeCache.js +9 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMap.js +50 -14
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapManager.js +8 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapScopesInfo.js +131 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TargetManager.js +0 -21
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TraceObject.js +9 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/sdk-meta.js +8 -1
- 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/ARIAProperties.js +1301 -174
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.js +7 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +9 -45
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/SupportedCSSProperties.js +74 -19
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.js +50 -34
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js +46 -45
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AICallTree.js +2 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIContext.js +10 -25
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CompilerScriptMapping.js +45 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerWorkspaceBinding.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/cpu_profile/ProfileTreeModel.js +6 -7
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/FormatterWorkerPool.js +14 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/NamesResolver.js +5 -11
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/source_map_scopes.js +1 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/Trie.js +8 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/ModelImpl.js +6 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/TraceTree.js +10 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/MetaHandler.js +4 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/NetworkRequestsHandler.js +12 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/UserTimingsHandler.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/CLSCulprits.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Cache.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DOMSize.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DocumentLatency.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DuplicatedJavaScript.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/FontDisplay.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ForcedReflow.js +3 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/INPBreakdown.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ImageDelivery.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPBreakdown.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPDiscovery.js +2 -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/ModernHTTP.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/NetworkDependencyTree.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/RenderBlocking.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/SlowCSSSelector.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/ThirdParties.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Viewport.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/types/TraceEvents.js +3 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/SourceMapsResolver.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/mcp/mcp.js +14 -0
- package/build/src/DevToolsConnectionAdapter.js +33 -0
- package/build/src/DevtoolsUtils.js +44 -0
- package/build/src/McpContext.js +182 -33
- package/build/src/McpResponse.js +169 -57
- package/build/src/PageCollector.js +123 -27
- package/build/src/WaitForHelper.js +5 -0
- package/build/src/browser.js +24 -12
- package/build/src/cli.js +87 -6
- package/build/src/formatters/consoleFormatter.js +29 -62
- package/build/src/formatters/networkFormatter.js +5 -6
- package/build/src/formatters/snapshotFormatter.js +28 -11
- package/build/src/logger.js +1 -1
- package/build/src/main.js +24 -6
- package/build/src/polyfill.js +2 -2
- package/build/src/third_party/THIRD_PARTY_NOTICES +1413 -0
- package/build/src/third_party/index.js +82791 -0
- package/build/src/tools/ToolDefinition.js +2 -2
- package/build/src/tools/categories.js +17 -9
- package/build/src/tools/console.js +71 -6
- package/build/src/tools/emulation.js +40 -48
- package/build/src/tools/input.js +57 -27
- package/build/src/tools/network.js +43 -13
- package/build/src/tools/pages.js +75 -49
- package/build/src/tools/performance.js +13 -10
- package/build/src/tools/screenshot.js +10 -9
- package/build/src/tools/script.js +29 -15
- package/build/src/tools/snapshot.js +27 -23
- package/build/src/trace-processing/parse.js +6 -16
- package/build/src/utils/keyboard.js +291 -0
- package/build/src/utils/types.js +6 -0
- package/package.json +16 -12
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
import * as AidaClient from './AidaClient.js';
|
|
5
|
+
import * as DispatchHttpRequestClient from './DispatchHttpRequestClient.js';
|
|
5
6
|
import * as GdpClient from './GdpClient.js';
|
|
6
7
|
import * as InspectorFrontendHost from './InspectorFrontendHost.js';
|
|
7
8
|
import * as InspectorFrontendHostAPI from './InspectorFrontendHostAPI.js';
|
|
8
9
|
import * as Platform from './Platform.js';
|
|
9
10
|
import * as ResourceLoader from './ResourceLoader.js';
|
|
10
11
|
import * as UserMetrics from './UserMetrics.js';
|
|
11
|
-
export { AidaClient, GdpClient, InspectorFrontendHost, InspectorFrontendHostAPI, Platform, ResourceLoader, UserMetrics, };
|
|
12
|
+
export { AidaClient, DispatchHttpRequestClient, GdpClient, InspectorFrontendHost, InspectorFrontendHostAPI, Platform, ResourceLoader, UserMetrics, };
|
|
12
13
|
export const userMetrics = new UserMetrics.UserMetrics();
|
package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/CDPConnection.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2025 The Chromium Authors
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
/**
|
|
5
|
+
* Keep this in sync with https://source.chromium.org/chromium/chromium/src/+/main:third_party/inspector_protocol/crdtp/dispatch.h.
|
|
6
|
+
*/
|
|
7
|
+
export var CDPErrorStatus;
|
|
8
|
+
(function (CDPErrorStatus) {
|
|
9
|
+
CDPErrorStatus[CDPErrorStatus["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
|
|
10
|
+
CDPErrorStatus[CDPErrorStatus["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
|
|
11
|
+
CDPErrorStatus[CDPErrorStatus["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
|
|
12
|
+
CDPErrorStatus[CDPErrorStatus["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
|
|
13
|
+
CDPErrorStatus[CDPErrorStatus["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
|
|
14
|
+
CDPErrorStatus[CDPErrorStatus["SERVER_ERROR"] = -32000] = "SERVER_ERROR";
|
|
15
|
+
CDPErrorStatus[CDPErrorStatus["SESSION_NOT_FOUND"] = -32001] = "SESSION_NOT_FOUND";
|
|
16
|
+
CDPErrorStatus[CDPErrorStatus["DEVTOOLS_STUB_ERROR"] = -32015] = "DEVTOOLS_STUB_ERROR";
|
|
17
|
+
})(CDPErrorStatus || (CDPErrorStatus = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2025 The Chromium Authors
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
let connectionFactory;
|
|
5
|
+
export class ConnectionTransport {
|
|
6
|
+
static setFactory(factory) {
|
|
7
|
+
connectionFactory = factory;
|
|
8
|
+
}
|
|
9
|
+
static getFactory() {
|
|
10
|
+
return connectionFactory;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// Copyright 2011 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
+
import * as InspectorBackendCommands from '../../generated/InspectorBackendCommands.js';
|
|
5
|
+
import { CDPErrorStatus } from './CDPConnection.js';
|
|
6
|
+
import { ConnectionTransport } from './ConnectionTransport.js';
|
|
4
7
|
import { NodeURL } from './NodeURL.js';
|
|
5
|
-
export const DevToolsStubErrorCode = -32015;
|
|
6
|
-
// TODO(dgozman): we are not reporting generic errors in tests, but we should
|
|
7
|
-
// instead report them and just have some expected errors in test expectations.
|
|
8
|
-
const GenericErrorCode = -32000;
|
|
9
|
-
const ConnectionClosedErrorCode = -32001;
|
|
10
8
|
export const splitQualifiedName = (string) => {
|
|
11
9
|
const [domain, eventName] = string.split('.');
|
|
12
10
|
return [domain, eventName];
|
|
@@ -16,10 +14,16 @@ export const qualifyName = (domain, name) => {
|
|
|
16
14
|
};
|
|
17
15
|
export class InspectorBackend {
|
|
18
16
|
agentPrototypes = new Map();
|
|
19
|
-
#initialized = false;
|
|
20
17
|
#eventParameterNamesForDomain = new Map();
|
|
21
18
|
typeMap = new Map();
|
|
22
19
|
enumMap = new Map();
|
|
20
|
+
constructor() {
|
|
21
|
+
// Create the global here because registering commands will involve putting
|
|
22
|
+
// items onto the global.
|
|
23
|
+
// @ts-expect-error Global namespace instantiation
|
|
24
|
+
globalThis.Protocol ||= {};
|
|
25
|
+
InspectorBackendCommands.registerCommands(this);
|
|
26
|
+
}
|
|
23
27
|
getOrCreateEventParameterNamesForDomain(domain) {
|
|
24
28
|
let map = this.#eventParameterNamesForDomain.get(domain);
|
|
25
29
|
if (!map) {
|
|
@@ -40,9 +44,6 @@ export class InspectorBackend {
|
|
|
40
44
|
static reportProtocolWarning(error, messageObject) {
|
|
41
45
|
console.warn(error + ': ' + JSON.stringify(messageObject));
|
|
42
46
|
}
|
|
43
|
-
isInitialized() {
|
|
44
|
-
return this.#initialized;
|
|
45
|
-
}
|
|
46
47
|
agentPrototype(domain) {
|
|
47
48
|
let prototype = this.agentPrototypes.get(domain);
|
|
48
49
|
if (!prototype) {
|
|
@@ -54,7 +55,6 @@ export class InspectorBackend {
|
|
|
54
55
|
registerCommand(method, parameters, replyArgs, description) {
|
|
55
56
|
const [domain, command] = splitQualifiedName(method);
|
|
56
57
|
this.agentPrototype(domain).registerCommand(command, parameters, replyArgs, description);
|
|
57
|
-
this.#initialized = true;
|
|
58
58
|
}
|
|
59
59
|
registerEnum(type, values) {
|
|
60
60
|
const [domain, name] = splitQualifiedName(type);
|
|
@@ -66,37 +66,14 @@ export class InspectorBackend {
|
|
|
66
66
|
// @ts-expect-error globalThis global namespace pollution
|
|
67
67
|
globalThis.Protocol[domain][name] = values;
|
|
68
68
|
this.enumMap.set(type, values);
|
|
69
|
-
this.#initialized = true;
|
|
70
69
|
}
|
|
71
70
|
registerType(method, parameters) {
|
|
72
71
|
this.typeMap.set(method, parameters);
|
|
73
|
-
this.#initialized = true;
|
|
74
72
|
}
|
|
75
73
|
registerEvent(eventName, params) {
|
|
76
74
|
const domain = eventName.split('.')[0];
|
|
77
75
|
const eventParameterNames = this.getOrCreateEventParameterNamesForDomain(domain);
|
|
78
76
|
eventParameterNames.set(eventName, params);
|
|
79
|
-
this.#initialized = true;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
let connectionFactory;
|
|
83
|
-
export class Connection {
|
|
84
|
-
// on message from browser
|
|
85
|
-
setOnMessage(_onMessage) {
|
|
86
|
-
}
|
|
87
|
-
setOnDisconnect(_onDisconnect) {
|
|
88
|
-
}
|
|
89
|
-
// send raw CDP message to browser
|
|
90
|
-
sendRawMessage(_message) {
|
|
91
|
-
}
|
|
92
|
-
disconnect() {
|
|
93
|
-
throw new Error('not implemented');
|
|
94
|
-
}
|
|
95
|
-
static setFactory(factory) {
|
|
96
|
-
connectionFactory = factory;
|
|
97
|
-
}
|
|
98
|
-
static getFactory() {
|
|
99
|
-
return connectionFactory;
|
|
100
77
|
}
|
|
101
78
|
}
|
|
102
79
|
export const test = {
|
|
@@ -136,6 +113,8 @@ export class SessionRouter {
|
|
|
136
113
|
#pendingLongPollingMessageIds = new Set();
|
|
137
114
|
#sessions = new Map();
|
|
138
115
|
#pendingScripts = [];
|
|
116
|
+
#callbacks = new Map();
|
|
117
|
+
#observers = new Set();
|
|
139
118
|
constructor(connection) {
|
|
140
119
|
this.#connection = connection;
|
|
141
120
|
test.deprecatedRunAfterPendingDispatches = this.deprecatedRunAfterPendingDispatches.bind(this);
|
|
@@ -146,45 +125,43 @@ export class SessionRouter {
|
|
|
146
125
|
if (session) {
|
|
147
126
|
session.target.dispose(reason);
|
|
148
127
|
}
|
|
128
|
+
this.#observers.forEach(observer => observer.onDisconnect(reason));
|
|
149
129
|
});
|
|
150
130
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
this.#sessions.set(sessionId, { target, callbacks: new Map(), proxyConnection });
|
|
131
|
+
observe(observer) {
|
|
132
|
+
this.#observers.add(observer);
|
|
133
|
+
}
|
|
134
|
+
unobserve(observer) {
|
|
135
|
+
this.#observers.delete(observer);
|
|
136
|
+
}
|
|
137
|
+
registerSession(target, sessionId) {
|
|
138
|
+
this.#sessions.set(sessionId, { target });
|
|
163
139
|
}
|
|
164
140
|
unregisterSession(sessionId) {
|
|
165
141
|
const session = this.#sessions.get(sessionId);
|
|
166
142
|
if (!session) {
|
|
167
143
|
return;
|
|
168
144
|
}
|
|
169
|
-
for (const
|
|
170
|
-
|
|
145
|
+
for (const { resolve, method, sessionId: callbackSessionId } of this.#callbacks.values()) {
|
|
146
|
+
if (sessionId !== callbackSessionId) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
resolve({
|
|
150
|
+
error: {
|
|
151
|
+
message: `Session is unregistering, can\'t dispatch pending call to ${method}`,
|
|
152
|
+
code: CDPErrorStatus.SESSION_NOT_FOUND,
|
|
153
|
+
}
|
|
154
|
+
});
|
|
171
155
|
}
|
|
172
156
|
this.#sessions.delete(sessionId);
|
|
173
157
|
}
|
|
174
|
-
getTargetBySessionId(sessionId) {
|
|
175
|
-
const session = this.#sessions.get(sessionId ? sessionId : '');
|
|
176
|
-
if (!session) {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
return session.target;
|
|
180
|
-
}
|
|
181
158
|
nextMessageId() {
|
|
182
159
|
return this.#lastMessageId++;
|
|
183
160
|
}
|
|
184
161
|
connection() {
|
|
185
162
|
return this.#connection;
|
|
186
163
|
}
|
|
187
|
-
|
|
164
|
+
send(method, params, sessionId) {
|
|
188
165
|
const messageId = this.nextMessageId();
|
|
189
166
|
const messageObject = {
|
|
190
167
|
id: messageId,
|
|
@@ -200,23 +177,28 @@ export class SessionRouter {
|
|
|
200
177
|
test.dumpProtocol('frontend: ' + JSON.stringify(messageObject));
|
|
201
178
|
}
|
|
202
179
|
if (test.onMessageSent) {
|
|
180
|
+
const domain = method.split('.')[0];
|
|
203
181
|
const paramsObject = JSON.parse(JSON.stringify(params || {}));
|
|
204
|
-
test.onMessageSent({ domain, method, params: paramsObject, id: messageId, sessionId }
|
|
182
|
+
test.onMessageSent({ domain, method, params: paramsObject, id: messageId, sessionId });
|
|
205
183
|
}
|
|
206
184
|
++this.#pendingResponsesCount;
|
|
207
185
|
if (LongPollingMethods.has(method)) {
|
|
208
186
|
this.#pendingLongPollingMessageIds.add(messageId);
|
|
209
187
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
session.callbacks.set(messageId, { callback, method });
|
|
215
|
-
this.#connection.sendRawMessage(JSON.stringify(messageObject));
|
|
188
|
+
return new Promise(resolve => {
|
|
189
|
+
this.#callbacks.set(messageId, { resolve, method, sessionId });
|
|
190
|
+
this.#connection.sendRawMessage(JSON.stringify(messageObject));
|
|
191
|
+
});
|
|
216
192
|
}
|
|
217
193
|
sendRawMessageForTesting(method, params, callback, sessionId = '') {
|
|
218
|
-
|
|
219
|
-
|
|
194
|
+
void this.send(method, params, sessionId).then(response => {
|
|
195
|
+
if ('error' in response && response.error) {
|
|
196
|
+
callback?.(response.error, null);
|
|
197
|
+
}
|
|
198
|
+
else if ('result' in response) {
|
|
199
|
+
callback?.(null, response.result);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
220
202
|
}
|
|
221
203
|
onMessage(message) {
|
|
222
204
|
if (test.dumpProtocol) {
|
|
@@ -224,65 +206,35 @@ export class SessionRouter {
|
|
|
224
206
|
}
|
|
225
207
|
if (test.onMessageReceived) {
|
|
226
208
|
const messageObjectCopy = JSON.parse((typeof message === 'string') ? message : JSON.stringify(message));
|
|
227
|
-
test.onMessageReceived(messageObjectCopy
|
|
209
|
+
test.onMessageReceived(messageObjectCopy);
|
|
228
210
|
}
|
|
229
211
|
const messageObject = ((typeof message === 'string') ? JSON.parse(message) : message);
|
|
230
|
-
// Send all messages to proxy connections.
|
|
231
|
-
let suppressUnknownMessageErrors = false;
|
|
232
|
-
for (const session of this.#sessions.values()) {
|
|
233
|
-
if (!session.proxyConnection) {
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (!session.proxyConnection.onMessage) {
|
|
237
|
-
InspectorBackend.reportProtocolError('Protocol Error: the session has a proxyConnection with no _onMessage', messageObject);
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
session.proxyConnection.onMessage(messageObject);
|
|
241
|
-
suppressUnknownMessageErrors = true;
|
|
242
|
-
}
|
|
243
212
|
const sessionId = messageObject.sessionId || '';
|
|
244
213
|
const session = this.#sessions.get(sessionId);
|
|
245
|
-
if (
|
|
246
|
-
if (!suppressUnknownMessageErrors) {
|
|
247
|
-
InspectorBackend.reportProtocolError('Protocol Error: the message with wrong session id', messageObject);
|
|
248
|
-
}
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
// If this message is directly for the target controlled by the proxy connection, don't handle it.
|
|
252
|
-
if (session.proxyConnection) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
if (session.target.getNeedsNodeJSPatching()) {
|
|
214
|
+
if (session?.target.getNeedsNodeJSPatching()) {
|
|
256
215
|
NodeURL.patch(messageObject);
|
|
257
216
|
}
|
|
258
|
-
if (messageObject.id !== undefined) { // just a response for some request
|
|
259
|
-
const callback =
|
|
260
|
-
|
|
217
|
+
if ('id' in messageObject && messageObject.id !== undefined) { // just a response for some request
|
|
218
|
+
const callback = this.#callbacks.get(messageObject.id);
|
|
219
|
+
this.#callbacks.delete(messageObject.id);
|
|
261
220
|
if (!callback) {
|
|
262
|
-
|
|
263
|
-
// Ignore the errors that are sent as responses after the session closes.
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
if (!suppressUnknownMessageErrors) {
|
|
267
|
-
InspectorBackend.reportProtocolError('Protocol Error: the message with wrong id', messageObject);
|
|
268
|
-
}
|
|
221
|
+
// Ignore messages with unknown IDs, we might see puppeteer proxied messages here.
|
|
269
222
|
return;
|
|
270
223
|
}
|
|
271
|
-
callback.
|
|
224
|
+
callback.resolve(messageObject);
|
|
272
225
|
--this.#pendingResponsesCount;
|
|
273
226
|
this.#pendingLongPollingMessageIds.delete(messageObject.id);
|
|
274
227
|
if (this.#pendingScripts.length && !this.hasOutstandingNonLongPollingRequests()) {
|
|
275
228
|
this.deprecatedRunAfterPendingDispatches();
|
|
276
229
|
}
|
|
277
230
|
}
|
|
278
|
-
else {
|
|
279
|
-
if (messageObject.method === undefined) {
|
|
280
|
-
InspectorBackend.reportProtocolError('Protocol Error: the message without method', messageObject);
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
231
|
+
else if ('method' in messageObject) {
|
|
283
232
|
// This cast is justified as we just checked for the presence of messageObject.method.
|
|
284
|
-
|
|
285
|
-
|
|
233
|
+
session?.target.dispatch(messageObject);
|
|
234
|
+
this.#observers.forEach(observer => observer.onEvent(messageObject));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
InspectorBackend.reportProtocolError('Protocol Error: the message without method', messageObject);
|
|
286
238
|
}
|
|
287
239
|
}
|
|
288
240
|
hasOutstandingNonLongPollingRequests() {
|
|
@@ -311,22 +263,6 @@ export class SessionRouter {
|
|
|
311
263
|
}
|
|
312
264
|
}
|
|
313
265
|
}
|
|
314
|
-
static dispatchConnectionError(callback, method) {
|
|
315
|
-
const error = {
|
|
316
|
-
message: `Connection is closed, can\'t dispatch pending call to ${method}`,
|
|
317
|
-
code: ConnectionClosedErrorCode,
|
|
318
|
-
data: null,
|
|
319
|
-
};
|
|
320
|
-
window.setTimeout(() => callback(error, null), 0);
|
|
321
|
-
}
|
|
322
|
-
static dispatchUnregisterSessionError({ callback, method }) {
|
|
323
|
-
const error = {
|
|
324
|
-
message: `Session is unregistering, can\'t dispatch pending call to ${method}`,
|
|
325
|
-
code: ConnectionClosedErrorCode,
|
|
326
|
-
data: null,
|
|
327
|
-
};
|
|
328
|
-
window.setTimeout(() => callback(error, null), 0);
|
|
329
|
-
}
|
|
330
266
|
}
|
|
331
267
|
export class TargetBase {
|
|
332
268
|
needsNodeJSPatching;
|
|
@@ -337,18 +273,18 @@ export class TargetBase {
|
|
|
337
273
|
constructor(needsNodeJSPatching, parentTarget, sessionId, connection) {
|
|
338
274
|
this.needsNodeJSPatching = needsNodeJSPatching;
|
|
339
275
|
this.sessionId = sessionId;
|
|
340
|
-
if (
|
|
341
|
-
throw new Error('
|
|
276
|
+
if (parentTarget && !sessionId) {
|
|
277
|
+
throw new Error('Specifying a parent target requires a session ID');
|
|
342
278
|
}
|
|
343
279
|
let router;
|
|
344
|
-
if (
|
|
280
|
+
if (parentTarget && parentTarget.#router) {
|
|
345
281
|
router = parentTarget.#router;
|
|
346
282
|
}
|
|
347
283
|
else if (connection) {
|
|
348
284
|
router = new SessionRouter(connection);
|
|
349
285
|
}
|
|
350
286
|
else {
|
|
351
|
-
router = new SessionRouter(
|
|
287
|
+
router = new SessionRouter(ConnectionTransport.getFactory()());
|
|
352
288
|
}
|
|
353
289
|
this.#router = router;
|
|
354
290
|
router.registerSession(this, this.sessionId);
|
|
@@ -638,6 +574,12 @@ export class TargetBase {
|
|
|
638
574
|
return this.needsNodeJSPatching;
|
|
639
575
|
}
|
|
640
576
|
}
|
|
577
|
+
/** These are not logged as console.error */
|
|
578
|
+
const IGNORED_ERRORS = new Set([
|
|
579
|
+
CDPErrorStatus.DEVTOOLS_STUB_ERROR,
|
|
580
|
+
CDPErrorStatus.SERVER_ERROR,
|
|
581
|
+
CDPErrorStatus.SESSION_NOT_FOUND,
|
|
582
|
+
]);
|
|
641
583
|
/**
|
|
642
584
|
* This is a class that serves as the prototype for a domains #agents (every target
|
|
643
585
|
* has it's own set of #agents). The InspectorBackend keeps an instance of this class
|
|
@@ -648,113 +590,39 @@ export class TargetBase {
|
|
|
648
590
|
* of the invoke_enable, etc. methods that the front-end uses.
|
|
649
591
|
*/
|
|
650
592
|
class AgentPrototype {
|
|
651
|
-
replyArgs;
|
|
652
593
|
description = '';
|
|
653
594
|
metadata;
|
|
654
595
|
domain;
|
|
655
596
|
target;
|
|
656
597
|
constructor(domain) {
|
|
657
|
-
this.replyArgs = {};
|
|
658
598
|
this.domain = domain;
|
|
659
599
|
this.metadata = {};
|
|
660
600
|
}
|
|
661
601
|
registerCommand(methodName, parameters, replyArgs, description) {
|
|
662
602
|
const domainAndMethod = qualifyName(this.domain, methodName);
|
|
663
|
-
function sendMessagePromise(...args) {
|
|
664
|
-
return AgentPrototype.prototype.sendMessageToBackendPromise.call(this, domainAndMethod, parameters, args);
|
|
665
|
-
}
|
|
666
|
-
// @ts-expect-error Method code generation
|
|
667
|
-
this[methodName] = sendMessagePromise;
|
|
668
603
|
this.metadata[domainAndMethod] = { parameters, description, replyArgs };
|
|
669
604
|
function invoke(request = {}) {
|
|
670
605
|
return this.invoke(domainAndMethod, request);
|
|
671
606
|
}
|
|
672
607
|
// @ts-expect-error Method code generation
|
|
673
608
|
this['invoke_' + methodName] = invoke;
|
|
674
|
-
this.replyArgs[domainAndMethod] = replyArgs;
|
|
675
|
-
}
|
|
676
|
-
prepareParameters(method, parameters, args, errorCallback) {
|
|
677
|
-
const params = {};
|
|
678
|
-
let hasParams = false;
|
|
679
|
-
for (const param of parameters) {
|
|
680
|
-
const paramName = param.name;
|
|
681
|
-
const typeName = param.type;
|
|
682
|
-
const optionalFlag = param.optional;
|
|
683
|
-
if (!args.length && !optionalFlag) {
|
|
684
|
-
errorCallback(`Protocol Error: Invalid number of arguments for method '${method}' call. ` +
|
|
685
|
-
`It must have the following arguments ${JSON.stringify(parameters)}'.`);
|
|
686
|
-
return null;
|
|
687
|
-
}
|
|
688
|
-
const value = args.shift();
|
|
689
|
-
if (optionalFlag && typeof value === 'undefined') {
|
|
690
|
-
continue;
|
|
691
|
-
}
|
|
692
|
-
const expectedJSType = typeName === 'array' ? 'object' : typeName;
|
|
693
|
-
if (typeof value !== expectedJSType) {
|
|
694
|
-
errorCallback(`Protocol Error: Invalid type of argument '${paramName}' for method '${method}' call. ` +
|
|
695
|
-
`It must be '${typeName}' but it is '${typeof value}'.`);
|
|
696
|
-
return null;
|
|
697
|
-
}
|
|
698
|
-
params[paramName] = value;
|
|
699
|
-
hasParams = true;
|
|
700
|
-
}
|
|
701
|
-
if (args.length) {
|
|
702
|
-
errorCallback(`Protocol Error: Extra ${args.length} arguments in a call to method '${method}'.`);
|
|
703
|
-
return null;
|
|
704
|
-
}
|
|
705
|
-
return hasParams ? params : null;
|
|
706
|
-
}
|
|
707
|
-
sendMessageToBackendPromise(method, parameters, args) {
|
|
708
|
-
let errorMessage;
|
|
709
|
-
function onError(message) {
|
|
710
|
-
console.error(message);
|
|
711
|
-
errorMessage = message;
|
|
712
|
-
}
|
|
713
|
-
const params = this.prepareParameters(method, parameters, args, onError);
|
|
714
|
-
if (errorMessage) {
|
|
715
|
-
return Promise.resolve(null);
|
|
716
|
-
}
|
|
717
|
-
return new Promise(resolve => {
|
|
718
|
-
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
719
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
720
|
-
const callback = (error, result) => {
|
|
721
|
-
if (error) {
|
|
722
|
-
if (!test.suppressRequestErrors && error.code !== DevToolsStubErrorCode && error.code !== GenericErrorCode &&
|
|
723
|
-
error.code !== ConnectionClosedErrorCode) {
|
|
724
|
-
console.error('Request ' + method + ' failed. ' + JSON.stringify(error));
|
|
725
|
-
}
|
|
726
|
-
resolve(null);
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
const args = this.replyArgs[method];
|
|
730
|
-
resolve(result && args.length ? result[args[0]] : undefined);
|
|
731
|
-
};
|
|
732
|
-
const router = this.target.router();
|
|
733
|
-
if (!router) {
|
|
734
|
-
SessionRouter.dispatchConnectionError(callback, method);
|
|
735
|
-
}
|
|
736
|
-
else {
|
|
737
|
-
router.sendMessage(this.target.sessionId, this.domain, method, params, callback);
|
|
738
|
-
}
|
|
739
|
-
});
|
|
740
609
|
}
|
|
741
610
|
invoke(method, request) {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
611
|
+
const router = this.target.router();
|
|
612
|
+
if (!router) {
|
|
613
|
+
return Promise.resolve({ result: null, getError: () => `Connection is closed, can\'t dispatch pending call to ${method}` });
|
|
614
|
+
}
|
|
615
|
+
return router.send(method, request, this.target.sessionId).then(response => {
|
|
616
|
+
if ('error' in response && response.error) {
|
|
617
|
+
if (!test.suppressRequestErrors && !IGNORED_ERRORS.has(response.error.code)) {
|
|
618
|
+
console.error('Request ' + method + ' failed. ' + JSON.stringify(response.error));
|
|
747
619
|
}
|
|
748
|
-
|
|
749
|
-
fulfill({ ...result, getError: () => errorMessage });
|
|
750
|
-
};
|
|
751
|
-
const router = this.target.router();
|
|
752
|
-
if (!router) {
|
|
753
|
-
SessionRouter.dispatchConnectionError(callback, method);
|
|
620
|
+
return { getError: () => response.error.message };
|
|
754
621
|
}
|
|
755
|
-
|
|
756
|
-
|
|
622
|
+
if ('result' in response) {
|
|
623
|
+
return { ...response.result, getError: () => undefined };
|
|
757
624
|
}
|
|
625
|
+
return { getError: () => undefined };
|
|
758
626
|
});
|
|
759
627
|
}
|
|
760
628
|
}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
// Copyright 2019 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
-
import * as
|
|
4
|
+
import * as CDPConnection from './CDPConnection.js';
|
|
5
|
+
import * as ConnectionTransport from './ConnectionTransport.js';
|
|
5
6
|
import * as InspectorBackend from './InspectorBackend.js';
|
|
6
7
|
import * as NodeURL from './NodeURL.js';
|
|
7
|
-
export { InspectorBackend, NodeURL, };
|
|
8
|
-
// Create the global here because registering commands will involve putting
|
|
9
|
-
// items onto the global.
|
|
10
|
-
// @ts-expect-error Global namespace instantiation
|
|
11
|
-
|
|
12
|
-
// FIXME: This instance of InspectorBackend should not be a side effect of importing this module.
|
|
13
|
-
|
|
8
|
+
export { CDPConnection, ConnectionTransport, InspectorBackend, NodeURL, };
|
|
@@ -678,12 +678,11 @@ export class AnimationGroup {
|
|
|
678
678
|
#id;
|
|
679
679
|
#scrollNode;
|
|
680
680
|
#animations;
|
|
681
|
-
#paused;
|
|
681
|
+
#paused = false;
|
|
682
682
|
constructor(animationModel, id, animations) {
|
|
683
683
|
this.#animationModel = animationModel;
|
|
684
684
|
this.#id = id;
|
|
685
685
|
this.#animations = animations;
|
|
686
|
-
this.#paused = false;
|
|
687
686
|
}
|
|
688
687
|
isScrollDriven() {
|
|
689
688
|
return Boolean(this.#animations[0]?.viewOrScrollTimeline());
|