cdp-tunnel 2.7.3 → 2.7.5
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.
|
@@ -141,8 +141,11 @@ var SpecialHandler = (function() {
|
|
|
141
141
|
|
|
142
142
|
function groupTabSilently(tabId, clientId) {
|
|
143
143
|
return new Promise(function(resolve) {
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
try {
|
|
145
|
+
addTabToAutomationGroup(tabId, clientId);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
Logger.error('[TabGroup] addTabToAutomationGroup threw:', e.message || e);
|
|
148
|
+
}
|
|
146
149
|
setTimeout(resolve, 100);
|
|
147
150
|
});
|
|
148
151
|
}
|
|
@@ -165,7 +168,11 @@ var SpecialHandler = (function() {
|
|
|
165
168
|
WebSocketManager.send({ type: 'tabgroup-debug', tabId: tabId, clientId: clientId, phase: 'start' });
|
|
166
169
|
|
|
167
170
|
setTimeout(function() {
|
|
168
|
-
|
|
171
|
+
try {
|
|
172
|
+
muteTabIfNeeded(tabId);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
Logger.error('[TabGroup] muteTabIfNeeded threw:', e.message || e);
|
|
175
|
+
}
|
|
169
176
|
}, 200);
|
|
170
177
|
|
|
171
178
|
var groupClientId = clientId;
|
|
@@ -188,6 +195,11 @@ var SpecialHandler = (function() {
|
|
|
188
195
|
function doGroup(tabId, clientId, baseName, retries) {
|
|
189
196
|
retries = retries || 0;
|
|
190
197
|
Logger.info('[TabGroup] doGroup: tabId=' + tabId + ' clientId=' + (clientId || 'none') + ' baseName=' + baseName + ' retry=' + retries);
|
|
198
|
+
if (!chrome.tabGroups) {
|
|
199
|
+
Logger.warn('[TabGroup] chrome.tabGroups API not available (headless mode?), skipping grouping for tab:', tabId);
|
|
200
|
+
EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'skip', reason: 'tabGroups-unavailable', tabId: tabId });
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
191
203
|
chrome.tabGroups.query({}, function(allGroups) {
|
|
192
204
|
if (chrome.runtime.lastError) {
|
|
193
205
|
Logger.error('[TabGroup] tabGroups.query failed:', chrome.runtime.lastError.message);
|
|
@@ -223,21 +235,26 @@ var SpecialHandler = (function() {
|
|
|
223
235
|
}
|
|
224
236
|
Logger.info('[TabGroup] chrome.tabs.group returned groupId:', groupId);
|
|
225
237
|
EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'groupCreated', tabId: tabId, groupId: groupId });
|
|
226
|
-
|
|
227
|
-
chrome.tabGroups
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
if (groupId) {
|
|
239
|
+
if (chrome.tabGroups) {
|
|
240
|
+
chrome.tabGroups.update(groupId, {
|
|
241
|
+
title: baseName,
|
|
242
|
+
color: CDPUtils.getGroupColorForClient(clientId),
|
|
243
|
+
collapsed: true
|
|
244
|
+
}, function() {
|
|
245
|
+
if (chrome.runtime.lastError) {
|
|
246
|
+
Logger.error('[TabGroup] Failed to update group:', chrome.runtime.lastError.message);
|
|
247
|
+
EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'updateGroup', error: chrome.runtime.lastError.message, groupId: groupId });
|
|
248
|
+
} else {
|
|
249
|
+
State.setGroupIdForClient(clientId, groupId);
|
|
250
|
+
updateTabGroupName(clientId);
|
|
251
|
+
Logger.info('[TabGroup] Group updated:', groupId, baseName);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
} else {
|
|
255
|
+
State.setGroupIdForClient(clientId, groupId);
|
|
256
|
+
Logger.info('[TabGroup] Group created but tabGroups.update unavailable (headless):', groupId);
|
|
257
|
+
}
|
|
241
258
|
} else {
|
|
242
259
|
Logger.error('[TabGroup] chrome.tabs.group returned null groupId');
|
|
243
260
|
}
|
package/package.json
CHANGED
package/server/proxy-server.js
CHANGED
|
@@ -788,24 +788,16 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
788
788
|
} else if (targetId && (parsed.method === 'Target.targetCreated' || parsed.method === 'Target.attachedToTarget')) {
|
|
789
789
|
const pendingMap = parsed.method === 'Target.targetCreated' ? ns.pendingTargetCreatedEvents : ns.pendingAttachedEvents;
|
|
790
790
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const discWs = clientById.get(discClientId);
|
|
796
|
-
if (discWs && discWs.readyState === WebSocket.OPEN) {
|
|
797
|
-
discWs.send(cdpData);
|
|
798
|
-
routedToDiscoverer = true;
|
|
799
|
-
}
|
|
800
|
-
} else {
|
|
801
|
-
ns.discoveringClientIds.delete(discClientId);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
}
|
|
791
|
+
// Check if there's a pending Target.createTarget from any client.
|
|
792
|
+
// If so, cache this event — createTarget response will deliver it to the right client.
|
|
793
|
+
// If not, broadcast to discovering clients (for emitAutoAttachForExistingTargets etc.)
|
|
794
|
+
const hasPendingCreateTarget = Array.from(globalRequestIdMap.values()).some(m => m.isCreateTarget);
|
|
805
795
|
|
|
806
|
-
if (
|
|
796
|
+
if (hasPendingCreateTarget) {
|
|
807
797
|
pendingMap.set(targetId, { parsed: JSON.parse(JSON.stringify(parsed)), cdpData });
|
|
808
|
-
console.log(`[TARGET EVENT PENDING] ${parsed.method} targetId=${targetId?.substring(0,8)} (cached, waiting for createTarget response)`);
|
|
798
|
+
console.log(`[TARGET EVENT PENDING] ${parsed.method} targetId=${targetId?.substring(0,8) || 'none'} (cached, waiting for createTarget response)`);
|
|
799
|
+
} else {
|
|
800
|
+
console.log(`[TARGET EVENT DROPPED] ${parsed.method} targetId=${targetId?.substring(0,8) || 'none'} (no owner, dropped for isolation)`);
|
|
809
801
|
}
|
|
810
802
|
} else {
|
|
811
803
|
console.log(`[TARGET EVENT DROPPED] ${parsed.method} targetId=${targetId?.substring(0,8) || 'none'} (no owner, dropped for isolation)`);
|
|
@@ -818,7 +810,7 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
818
810
|
const sessionId = parsed.params?.sessionId;
|
|
819
811
|
|
|
820
812
|
if (targetId && sessionId) {
|
|
821
|
-
const clientId = ws.pairedClientId;
|
|
813
|
+
const clientId = ns.targetIdToClientId.get(targetId) || ws.pairedClientId;
|
|
822
814
|
if (clientId) {
|
|
823
815
|
ns.sessionToClientId.set(sessionId, clientId);
|
|
824
816
|
console.log(`[SESSION MAPPED] sessionId=${sessionId?.substring(0,8) || 'none'} -> clientId=${clientId?.substring(0,8) || 'none'}`);
|
|
@@ -938,15 +930,33 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
938
930
|
invalidateTargetsCache(ws);
|
|
939
931
|
}
|
|
940
932
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
933
|
+
if (mapping.isAutoDefaultPage) {
|
|
934
|
+
console.log(`[AUTO DEFAULT PAGE] createTarget response received for client=${mapping.clientId}, targetId=${parsed.result?.targetId?.substring(0,8) || 'none'} — skipping response send to client`);
|
|
935
|
+
|
|
936
|
+
if (mapping.pendingSetAutoAttach) {
|
|
937
|
+
const pending = mapping.pendingSetAutoAttach;
|
|
938
|
+
const pendingParsed = pending.parsed;
|
|
939
|
+
const pendingClientId = pending.clientId;
|
|
940
|
+
|
|
941
|
+
console.log(`[AUTO DEFAULT PAGE] Now forwarding pending setAutoAttach for client=${pendingClientId}`);
|
|
942
|
+
|
|
943
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
944
|
+
const forwardMsg = { ...pendingParsed, __clientId: pendingClientId };
|
|
945
|
+
ws.send(JSON.stringify(forwardMsg));
|
|
946
|
+
console.log(`[SEND TO PLUGIN] Forwarding setAutoAttach for client=${pendingClientId}`);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
} else {
|
|
950
|
+
const originalId = mapping.originalId;
|
|
951
|
+
parsed.id = originalId;
|
|
952
|
+
if (mapping.sessionId && !parsed.sessionId) {
|
|
953
|
+
parsed.sessionId = mapping.sessionId;
|
|
954
|
+
}
|
|
955
|
+
const responseStr = JSON.stringify(parsed);
|
|
956
|
+
console.log(`[SEND TO CLIENT] ${responseStr.substring(0, 300)}`);
|
|
957
|
+
clientWs.send(responseStr);
|
|
958
|
+
console.log(`[ROUTE] Response global=${globalId} -> original=${originalId} -> client=${mapping.clientId} sessionId=${parsed.sessionId?.substring(0,8) || 'none'}`);
|
|
945
959
|
}
|
|
946
|
-
const responseStr = JSON.stringify(parsed);
|
|
947
|
-
console.log(`[SEND TO CLIENT] ${responseStr.substring(0, 300)}`);
|
|
948
|
-
clientWs.send(responseStr);
|
|
949
|
-
console.log(`[ROUTE] Response global=${globalId} -> original=${originalId} -> client=${mapping.clientId} sessionId=${parsed.sessionId?.substring(0,8) || 'none'}`);
|
|
950
960
|
}
|
|
951
961
|
globalRequestIdMap.delete(globalId);
|
|
952
962
|
} else {
|
|
@@ -1042,6 +1052,52 @@ function handlePluginConnection(ws, clientInfo, request) {
|
|
|
1042
1052
|
}));
|
|
1043
1053
|
}
|
|
1044
1054
|
|
|
1055
|
+
function autoCreateDefaultPageAndForward(clientWs, setAutoAttachParsed, originalData, clientId, originalRequestId) {
|
|
1056
|
+
const pluginWs = clientWs.pairedPlugin;
|
|
1057
|
+
if (!pluginWs || pluginWs.readyState !== WebSocket.OPEN) {
|
|
1058
|
+
forwardToPlugin(clientWs, originalData, clientId);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
globalRequestIdCounter++;
|
|
1063
|
+
const createGlobalId = globalRequestIdCounter;
|
|
1064
|
+
|
|
1065
|
+
globalRequestIdMap.set(createGlobalId, {
|
|
1066
|
+
clientId: clientId,
|
|
1067
|
+
originalId: -1,
|
|
1068
|
+
sessionId: null,
|
|
1069
|
+
method: 'Target.createTarget',
|
|
1070
|
+
isCreateTarget: true,
|
|
1071
|
+
isAutoDefaultPage: true,
|
|
1072
|
+
pendingSetAutoAttach: {
|
|
1073
|
+
parsed: setAutoAttachParsed,
|
|
1074
|
+
data: originalData,
|
|
1075
|
+
clientId: clientId,
|
|
1076
|
+
originalRequestId: originalRequestId
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
const request = {
|
|
1081
|
+
id: createGlobalId,
|
|
1082
|
+
method: 'Target.createTarget',
|
|
1083
|
+
params: { url: 'about:blank' },
|
|
1084
|
+
__clientId: clientId
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
console.log(`[AUTO DEFAULT PAGE] Sending Target.createTarget for client=${clientId} globalId=${createGlobalId}, will forward setAutoAttach after`);
|
|
1088
|
+
pluginWs.send(JSON.stringify(request));
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
function forwardToPlugin(clientWs, data, clientId) {
|
|
1092
|
+
const pluginWs = clientWs.pairedPlugin;
|
|
1093
|
+
if (pluginWs && pluginWs.readyState === WebSocket.OPEN) {
|
|
1094
|
+
console.log(`[SEND TO PLUGIN] method=Target.setAutoAttach clientId=${clientId}`);
|
|
1095
|
+
pluginWs.send(data);
|
|
1096
|
+
} else {
|
|
1097
|
+
broadcastToPlugins(data, clientWs);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1045
1101
|
/**
|
|
1046
1102
|
* 处理 CDP 客户端连接 (Playwright/Puppeteer)
|
|
1047
1103
|
*/
|
|
@@ -1244,6 +1300,12 @@ function handleClientConnection(ws, clientInfo, customClientId = null, targetPlu
|
|
|
1244
1300
|
}
|
|
1245
1301
|
}
|
|
1246
1302
|
|
|
1303
|
+
if (parsed && parsed.method === 'Target.setAutoAttach' && parsed.params?.autoAttach && !ws._autoDefaultPageSent) {
|
|
1304
|
+
ws._autoDefaultPageSent = true;
|
|
1305
|
+
autoCreateDefaultPageAndForward(ws, parsed, modifiedData, id, originalId);
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1247
1309
|
if (parsed && parsed.method === 'Browser.close') {
|
|
1248
1310
|
if (shouldLog('info')) {
|
|
1249
1311
|
console.log(`\n[BROWSER CLOSE] Client ${id} requested Browser.close, forwarding to plugin`);
|