@pyrokine/mcp-chrome 2.0.2 → 2.1.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 +77 -35
- package/dist/core/browser-driver.d.ts +118 -1
- package/dist/core/browser-driver.d.ts.map +1 -1
- package/dist/core/browser-driver.js +11 -0
- package/dist/core/browser-driver.js.map +1 -1
- package/dist/core/error-sanitizer.js +2 -2
- package/dist/core/error-sanitizer.js.map +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +17 -4
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/locator.d.ts.map +1 -1
- package/dist/core/locator.js +4 -3
- package/dist/core/locator.js.map +1 -1
- package/dist/core/session.d.ts +5 -2
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +107 -4
- package/dist/core/session.js.map +1 -1
- package/dist/core/types.d.ts +17 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +57 -4
- package/dist/core/types.js.map +1 -1
- package/dist/core/unified-session.d.ts +29 -9
- package/dist/core/unified-session.d.ts.map +1 -1
- package/dist/core/unified-session.js +226 -18
- package/dist/core/unified-session.js.map +1 -1
- package/dist/core/utils.d.ts +1 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +17 -2
- package/dist/core/utils.js.map +1 -1
- package/dist/extension/bridge.d.ts +37 -22
- package/dist/extension/bridge.d.ts.map +1 -1
- package/dist/extension/bridge.js +223 -63
- package/dist/extension/bridge.js.map +1 -1
- package/dist/extension/http-server.d.ts.map +1 -1
- package/dist/extension/http-server.js +39 -10
- package/dist/extension/http-server.js.map +1 -1
- package/dist/tools/browse.d.ts.map +1 -1
- package/dist/tools/browse.js +153 -54
- package/dist/tools/browse.js.map +1 -1
- package/dist/tools/cookies.d.ts.map +1 -1
- package/dist/tools/cookies.js +2 -4
- package/dist/tools/cookies.js.map +1 -1
- package/dist/tools/evaluate.d.ts.map +1 -1
- package/dist/tools/evaluate.js +37 -10
- package/dist/tools/evaluate.js.map +1 -1
- package/dist/tools/extract.d.ts +1 -0
- package/dist/tools/extract.d.ts.map +1 -1
- package/dist/tools/extract.js +466 -227
- package/dist/tools/extract.js.map +1 -1
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +781 -444
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/logs.d.ts.map +1 -1
- package/dist/tools/logs.js +75 -23
- package/dist/tools/logs.js.map +1 -1
- package/dist/tools/manage.d.ts +0 -3
- package/dist/tools/manage.d.ts.map +1 -1
- package/dist/tools/manage.js +339 -285
- package/dist/tools/manage.js.map +1 -1
- package/dist/tools/png.d.ts +16 -0
- package/dist/tools/png.d.ts.map +1 -0
- package/dist/tools/png.js +197 -0
- package/dist/tools/png.js.map +1 -0
- package/dist/tools/schema.d.ts +14 -112
- package/dist/tools/schema.d.ts.map +1 -1
- package/dist/tools/schema.js +21 -12
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/wait.d.ts.map +1 -1
- package/dist/tools/wait.js +73 -13
- package/dist/tools/wait.js.map +1 -1
- package/package.json +11 -11
package/dist/extension/bridge.js
CHANGED
|
@@ -54,24 +54,25 @@ export class ExtensionBridge {
|
|
|
54
54
|
const result = await this.httpServer.sendCommand('tabs_list', {});
|
|
55
55
|
return result;
|
|
56
56
|
}
|
|
57
|
+
async listWindows() {
|
|
58
|
+
const result = await this.httpServer.sendCommand('tabs_topology', {});
|
|
59
|
+
const topology = result;
|
|
60
|
+
return {
|
|
61
|
+
...topology,
|
|
62
|
+
windows: topology.windows.map((window) => ({
|
|
63
|
+
...window,
|
|
64
|
+
tabs: window.tabs.map((tab) => ({
|
|
65
|
+
...tab,
|
|
66
|
+
targetId: String(tab.id),
|
|
67
|
+
type: tab.type ?? 'page',
|
|
68
|
+
})),
|
|
69
|
+
})),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
57
72
|
/** IBrowserDriver 接口:列出所有 tab,统一为 ListedTarget 形式(id 字符串化以保持跨 driver 兼容) */
|
|
58
73
|
async listTargets() {
|
|
59
74
|
const tabs = await this.listTabs();
|
|
60
|
-
return tabs.map((tab) => (
|
|
61
|
-
id: tab.id,
|
|
62
|
-
targetId: String(tab.id),
|
|
63
|
-
url: tab.url,
|
|
64
|
-
title: tab.title,
|
|
65
|
-
type: 'page',
|
|
66
|
-
active: tab.active,
|
|
67
|
-
windowId: tab.windowId,
|
|
68
|
-
index: tab.index,
|
|
69
|
-
groupId: tab.groupId,
|
|
70
|
-
pinned: tab.pinned,
|
|
71
|
-
incognito: tab.incognito,
|
|
72
|
-
managed: tab.managed,
|
|
73
|
-
status: tab.status,
|
|
74
|
-
}));
|
|
75
|
+
return tabs.map((tab) => this.tabToTarget(tab));
|
|
75
76
|
}
|
|
76
77
|
async createTab(url, timeout) {
|
|
77
78
|
const rpcTimeout = timeout !== undefined ? timeout + RPC_MARGIN : undefined;
|
|
@@ -84,7 +85,7 @@ export class ExtensionBridge {
|
|
|
84
85
|
const tab = result;
|
|
85
86
|
// 自动切换到新创建的 tab,后续操作立即生效
|
|
86
87
|
this.currentTabId = tab.id;
|
|
87
|
-
this.updateState(tab
|
|
88
|
+
this.updateState(tab);
|
|
88
89
|
return tab;
|
|
89
90
|
}
|
|
90
91
|
/** IBrowserDriver 接口:新建页面(targetId 为字符串化的 chrome tab id) */
|
|
@@ -95,14 +96,16 @@ export class ExtensionBridge {
|
|
|
95
96
|
url: tab.url,
|
|
96
97
|
title: tab.title,
|
|
97
98
|
type: 'page',
|
|
99
|
+
managed: tab.managed,
|
|
98
100
|
};
|
|
99
101
|
}
|
|
100
102
|
async closeTab(tabId) {
|
|
101
|
-
await this.httpServer.sendCommand('tabs_close', { tabId });
|
|
103
|
+
const result = (await this.httpServer.sendCommand('tabs_close', { tabId }));
|
|
102
104
|
if (this.currentTabId === tabId) {
|
|
103
105
|
this.currentTabId = null;
|
|
104
106
|
this.state = null;
|
|
105
107
|
}
|
|
108
|
+
return this.normalizePageChange(result);
|
|
106
109
|
}
|
|
107
110
|
/** IBrowserDriver 接口:关闭页面(targetId 是 chrome tab id 的字符串形式,省略时关闭当前 tab) */
|
|
108
111
|
async closePage(targetId) {
|
|
@@ -110,13 +113,104 @@ export class ExtensionBridge {
|
|
|
110
113
|
if (tabId === null) {
|
|
111
114
|
throw new DriverCapabilityError('没有可关闭的页面,请指定 targetId');
|
|
112
115
|
}
|
|
113
|
-
|
|
116
|
+
return this.closeTab(tabId);
|
|
117
|
+
}
|
|
118
|
+
async adoptPage(targetId) {
|
|
119
|
+
const tabId = this.parseTargetId(targetId);
|
|
120
|
+
const result = (await this.httpServer.sendCommand('tabs_adopt', { tabId }));
|
|
121
|
+
this.currentTabId = result.tab.id;
|
|
122
|
+
this.updateState(result.tab);
|
|
123
|
+
return {
|
|
124
|
+
target: this.tabToTarget(result.tab),
|
|
125
|
+
managedBefore: result.managedBefore,
|
|
126
|
+
managedAfter: result.managedAfter,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
async releasePage(targetId) {
|
|
130
|
+
const tabId = this.parseTargetId(targetId);
|
|
131
|
+
const result = (await this.httpServer.sendCommand('tabs_release', { tabId }));
|
|
132
|
+
if (this.currentTabId === result.tab.id) {
|
|
133
|
+
this.currentTabId = null;
|
|
134
|
+
this.state = null;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
target: this.tabToTarget(result.tab),
|
|
138
|
+
managedBefore: result.managedBefore,
|
|
139
|
+
managedAfter: result.managedAfter,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async movePage(targetId, options) {
|
|
143
|
+
const tabId = this.parseTargetId(targetId);
|
|
144
|
+
const result = (await this.httpServer.sendCommand('tabs_move', {
|
|
145
|
+
tabId,
|
|
146
|
+
windowId: options.windowId,
|
|
147
|
+
index: options.index,
|
|
148
|
+
active: options.activate,
|
|
149
|
+
}));
|
|
150
|
+
return this.normalizePageChange(result);
|
|
151
|
+
}
|
|
152
|
+
async reorderPage(targetId, index) {
|
|
153
|
+
const tabId = this.parseTargetId(targetId);
|
|
154
|
+
const result = (await this.httpServer.sendCommand('tabs_reorder', {
|
|
155
|
+
tabId,
|
|
156
|
+
index,
|
|
157
|
+
}));
|
|
158
|
+
return this.normalizePageChange(result);
|
|
159
|
+
}
|
|
160
|
+
async pinPage(targetId, pinned) {
|
|
161
|
+
const tabId = this.parseTargetId(targetId);
|
|
162
|
+
const result = (await this.httpServer.sendCommand('tabs_pin', { tabId, pinned }));
|
|
163
|
+
return this.normalizePageChange(result);
|
|
164
|
+
}
|
|
165
|
+
async focusWindow(windowId) {
|
|
166
|
+
const result = (await this.httpServer.sendCommand('window_focus', { windowId }));
|
|
167
|
+
return this.normalizePageChange(result);
|
|
168
|
+
}
|
|
169
|
+
async resizeWindow(windowId, options) {
|
|
170
|
+
const result = (await this.httpServer.sendCommand('window_resize', {
|
|
171
|
+
windowId,
|
|
172
|
+
...options,
|
|
173
|
+
}));
|
|
174
|
+
return this.normalizePageChange(result);
|
|
175
|
+
}
|
|
176
|
+
async newWindow(options) {
|
|
177
|
+
const result = (await this.httpServer.sendCommand('window_create', options));
|
|
178
|
+
if (result.targetId) {
|
|
179
|
+
this.currentTabId = this.parseTargetId(result.targetId);
|
|
180
|
+
const after = result.after;
|
|
181
|
+
const tab = after?.tabs.find((item) => String(item.id) === result.targetId);
|
|
182
|
+
if (tab) {
|
|
183
|
+
this.updateState(tab);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return this.normalizePageChange(result);
|
|
187
|
+
}
|
|
188
|
+
async closeWindow(windowId) {
|
|
189
|
+
const result = (await this.httpServer.sendCommand('window_close', { windowId }));
|
|
190
|
+
const before = result.before;
|
|
191
|
+
if (before?.tabs.some((tab) => tab.id === this.currentTabId)) {
|
|
192
|
+
this.currentTabId = null;
|
|
193
|
+
this.state = null;
|
|
194
|
+
}
|
|
195
|
+
return this.normalizePageChange(result);
|
|
196
|
+
}
|
|
197
|
+
async activatePageWithAffected(targetId) {
|
|
198
|
+
const tabId = this.parseTargetId(targetId);
|
|
199
|
+
const result = (await this.httpServer.sendCommand('tabs_activate_managed', {
|
|
200
|
+
tabId,
|
|
201
|
+
}));
|
|
202
|
+
this.currentTabId = tabId;
|
|
203
|
+
const after = result.after;
|
|
204
|
+
if (after) {
|
|
205
|
+
this.updateState(after);
|
|
206
|
+
}
|
|
207
|
+
return this.normalizePageChange(result);
|
|
114
208
|
}
|
|
115
209
|
async activateTab(tabId) {
|
|
116
210
|
const result = await this.httpServer.sendCommand('tabs_activate', { tabId });
|
|
117
211
|
const tab = result;
|
|
118
212
|
this.currentTabId = tab.id;
|
|
119
|
-
this.updateState(tab
|
|
213
|
+
this.updateState(tab);
|
|
120
214
|
}
|
|
121
215
|
/** IBrowserDriver 接口:激活页面(切到前台) */
|
|
122
216
|
async activatePage(targetId) {
|
|
@@ -125,7 +219,14 @@ export class ExtensionBridge {
|
|
|
125
219
|
}
|
|
126
220
|
/** IBrowserDriver 接口:选择操作目标 tab(不切换前台,只设置当前 currentTabId) */
|
|
127
221
|
async selectPage(targetId) {
|
|
128
|
-
|
|
222
|
+
const tabId = this.parseTargetId(targetId);
|
|
223
|
+
const tabs = await this.listTabs();
|
|
224
|
+
const tab = tabs.find((item) => item.id === tabId);
|
|
225
|
+
if (!tab) {
|
|
226
|
+
throw new DriverCapabilityError(`Tab ${targetId} 不存在,请先 browse(action="list") 查看可用页面`);
|
|
227
|
+
}
|
|
228
|
+
this.currentTabId = tab.id;
|
|
229
|
+
this.updateState(tab);
|
|
129
230
|
}
|
|
130
231
|
/** IBrowserDriver 接口:获取当前操作目标 ID(chrome tab id 的字符串形式) */
|
|
131
232
|
getCurrentTargetId() {
|
|
@@ -134,6 +235,9 @@ export class ExtensionBridge {
|
|
|
134
235
|
/** IBrowserDriver 接口:设置当前操作目标 ID */
|
|
135
236
|
setCurrentTargetId(targetId) {
|
|
136
237
|
this.currentTabId = targetId !== null ? this.parseTargetId(targetId) : null;
|
|
238
|
+
if (targetId === null) {
|
|
239
|
+
this.state = null;
|
|
240
|
+
}
|
|
137
241
|
}
|
|
138
242
|
async navigate(url, options) {
|
|
139
243
|
if (this.currentTabId === null) {
|
|
@@ -141,7 +245,7 @@ export class ExtensionBridge {
|
|
|
141
245
|
}
|
|
142
246
|
const rpcTimeout = options?.timeout !== undefined ? options.timeout + RPC_MARGIN : undefined;
|
|
143
247
|
const params = {
|
|
144
|
-
tabId: this.
|
|
248
|
+
tabId: this.requireCurrentTabId(),
|
|
145
249
|
url,
|
|
146
250
|
waitUntil: options?.wait ?? 'load',
|
|
147
251
|
timeout: options?.timeout,
|
|
@@ -149,7 +253,7 @@ export class ExtensionBridge {
|
|
|
149
253
|
const result = await this.httpServer.sendCommand('navigate', params, rpcTimeout);
|
|
150
254
|
const tab = result;
|
|
151
255
|
this.currentTabId = tab.id;
|
|
152
|
-
this.updateState(tab
|
|
256
|
+
this.updateState(tab);
|
|
153
257
|
}
|
|
154
258
|
// ==================== 导航操作 ====================
|
|
155
259
|
async goBack(timeout) {
|
|
@@ -160,12 +264,12 @@ export class ExtensionBridge {
|
|
|
160
264
|
// 调用方传 timeout 时:timeout 即导航超时 + 信号窗口 + 传输余量
|
|
161
265
|
const rpcTimeout = timeout !== undefined ? timeout + NAV_SIGNAL_WINDOW + RPC_MARGIN : 30000 + NAV_SIGNAL_WINDOW + RPC_MARGIN;
|
|
162
266
|
const params = {
|
|
163
|
-
tabId: this.
|
|
267
|
+
tabId: this.requireCurrentTabId(),
|
|
164
268
|
waitUntil: 'load',
|
|
165
269
|
timeout,
|
|
166
270
|
};
|
|
167
271
|
const result = (await this.httpServer.sendCommand('go_back', params, rpcTimeout));
|
|
168
|
-
this.updateState(result
|
|
272
|
+
this.updateState(result);
|
|
169
273
|
return result;
|
|
170
274
|
}
|
|
171
275
|
async goForward(timeout) {
|
|
@@ -176,12 +280,12 @@ export class ExtensionBridge {
|
|
|
176
280
|
// 调用方传 timeout 时:timeout 即导航超时 + 信号窗口 + 传输余量
|
|
177
281
|
const rpcTimeout = timeout !== undefined ? timeout + NAV_SIGNAL_WINDOW + RPC_MARGIN : 30000 + NAV_SIGNAL_WINDOW + RPC_MARGIN;
|
|
178
282
|
const params = {
|
|
179
|
-
tabId: this.
|
|
283
|
+
tabId: this.requireCurrentTabId(),
|
|
180
284
|
waitUntil: 'load',
|
|
181
285
|
timeout,
|
|
182
286
|
};
|
|
183
287
|
const result = (await this.httpServer.sendCommand('go_forward', params, rpcTimeout));
|
|
184
|
-
this.updateState(result
|
|
288
|
+
this.updateState(result);
|
|
185
289
|
return result;
|
|
186
290
|
}
|
|
187
291
|
async reload(ignoreCache = false, waitUntil, timeout) {
|
|
@@ -190,18 +294,18 @@ export class ExtensionBridge {
|
|
|
190
294
|
}
|
|
191
295
|
const rpcTimeout = timeout !== undefined ? timeout + RPC_MARGIN : undefined;
|
|
192
296
|
const params = {
|
|
193
|
-
tabId: this.
|
|
297
|
+
tabId: this.requireCurrentTabId(),
|
|
194
298
|
ignoreCache,
|
|
195
299
|
waitUntil: waitUntil ?? 'load',
|
|
196
300
|
timeout,
|
|
197
301
|
};
|
|
198
302
|
const result = await this.httpServer.sendCommand('reload', params, rpcTimeout);
|
|
199
303
|
const tab = result;
|
|
200
|
-
this.updateState(tab
|
|
304
|
+
this.updateState(tab);
|
|
201
305
|
}
|
|
202
306
|
async readPage(options) {
|
|
203
307
|
return (await this.httpServer.sendCommand('read_page', {
|
|
204
|
-
tabId: this.
|
|
308
|
+
tabId: this.requireCurrentTabId(),
|
|
205
309
|
frameId: this.currentFrameId || undefined,
|
|
206
310
|
...options,
|
|
207
311
|
}));
|
|
@@ -209,7 +313,7 @@ export class ExtensionBridge {
|
|
|
209
313
|
// ==================== 页面内容 ====================
|
|
210
314
|
async click(refId) {
|
|
211
315
|
const result = (await this.httpServer.sendCommand('click', {
|
|
212
|
-
tabId: this.
|
|
316
|
+
tabId: this.requireCurrentTabId(),
|
|
213
317
|
frameId: this.currentFrameId || undefined,
|
|
214
318
|
refId,
|
|
215
319
|
}));
|
|
@@ -220,15 +324,23 @@ export class ExtensionBridge {
|
|
|
220
324
|
// ==================== DOM 操作 ====================
|
|
221
325
|
async actionableClick(refId, force) {
|
|
222
326
|
return (await this.httpServer.sendCommand('actionable_click', {
|
|
223
|
-
tabId: this.
|
|
327
|
+
tabId: this.requireCurrentTabId(),
|
|
224
328
|
frameId: this.currentFrameId || undefined,
|
|
225
329
|
refId,
|
|
226
330
|
force: force ?? false,
|
|
227
331
|
}));
|
|
228
332
|
}
|
|
333
|
+
async checkActionability(refId) {
|
|
334
|
+
const result = (await this.httpServer.sendCommand('check_actionability', {
|
|
335
|
+
tabId: this.requireCurrentTabId(),
|
|
336
|
+
frameId: this.currentFrameId || undefined,
|
|
337
|
+
refId,
|
|
338
|
+
}));
|
|
339
|
+
return { ...result, success: result.success ?? result.actionable === true };
|
|
340
|
+
}
|
|
229
341
|
async dispatchInput(refId, text) {
|
|
230
342
|
return (await this.httpServer.sendCommand('dispatch_input', {
|
|
231
|
-
tabId: this.
|
|
343
|
+
tabId: this.requireCurrentTabId(),
|
|
232
344
|
frameId: this.currentFrameId || undefined,
|
|
233
345
|
refId,
|
|
234
346
|
text,
|
|
@@ -236,7 +348,7 @@ export class ExtensionBridge {
|
|
|
236
348
|
}
|
|
237
349
|
async dragAndDrop(srcRefId, dstRefId) {
|
|
238
350
|
return (await this.httpServer.sendCommand('drag_and_drop', {
|
|
239
|
-
tabId: this.
|
|
351
|
+
tabId: this.requireCurrentTabId(),
|
|
240
352
|
frameId: this.currentFrameId || undefined,
|
|
241
353
|
srcRefId,
|
|
242
354
|
dstRefId,
|
|
@@ -244,7 +356,7 @@ export class ExtensionBridge {
|
|
|
244
356
|
}
|
|
245
357
|
async getComputedStyle(refId, prop) {
|
|
246
358
|
return (await this.httpServer.sendCommand('get_computed_style', {
|
|
247
|
-
tabId: this.
|
|
359
|
+
tabId: this.requireCurrentTabId(),
|
|
248
360
|
frameId: this.currentFrameId || undefined,
|
|
249
361
|
refId,
|
|
250
362
|
prop,
|
|
@@ -252,7 +364,7 @@ export class ExtensionBridge {
|
|
|
252
364
|
}
|
|
253
365
|
async type(refId, text, clear = false) {
|
|
254
366
|
const result = (await this.httpServer.sendCommand('type', {
|
|
255
|
-
tabId: this.
|
|
367
|
+
tabId: this.requireCurrentTabId(),
|
|
256
368
|
frameId: this.currentFrameId || undefined,
|
|
257
369
|
refId,
|
|
258
370
|
text,
|
|
@@ -268,7 +380,7 @@ export class ExtensionBridge {
|
|
|
268
380
|
}
|
|
269
381
|
async scroll(x, y, refId) {
|
|
270
382
|
await this.httpServer.sendCommand('scroll', {
|
|
271
|
-
tabId: this.
|
|
383
|
+
tabId: this.requireCurrentTabId(),
|
|
272
384
|
frameId: this.currentFrameId || undefined,
|
|
273
385
|
x,
|
|
274
386
|
y,
|
|
@@ -283,7 +395,7 @@ export class ExtensionBridge {
|
|
|
283
395
|
// _args 参数仅满足 IBrowserDriver 接口签名;ExtensionBridge 不消费 args(stealth 路径上层已字符串拼接)
|
|
284
396
|
const rpcTimeout = timeout !== undefined ? timeout + RPC_MARGIN : undefined;
|
|
285
397
|
const result = (await this.httpServer.sendCommand('evaluate', {
|
|
286
|
-
tabId: this.
|
|
398
|
+
tabId: this.requireCurrentTabId(),
|
|
287
399
|
frameId: this.currentFrameId || undefined,
|
|
288
400
|
code,
|
|
289
401
|
timeout,
|
|
@@ -298,12 +410,12 @@ export class ExtensionBridge {
|
|
|
298
410
|
return JSON.parse(result.result);
|
|
299
411
|
}
|
|
300
412
|
catch (err) {
|
|
301
|
-
throw new Error(`evaluate 结果 JSON 解析失败: ${err}
|
|
413
|
+
throw new Error(`evaluate 结果 JSON 解析失败: ${err}`, { cause: err });
|
|
302
414
|
}
|
|
303
415
|
}
|
|
304
416
|
async find(selector, text, xpath, timeout) {
|
|
305
417
|
return (await this.httpServer.sendCommand('find', {
|
|
306
|
-
tabId: this.
|
|
418
|
+
tabId: this.requireCurrentTabId(),
|
|
307
419
|
frameId: this.currentFrameId || undefined,
|
|
308
420
|
selector,
|
|
309
421
|
text,
|
|
@@ -312,7 +424,7 @@ export class ExtensionBridge {
|
|
|
312
424
|
}
|
|
313
425
|
async getText(selector) {
|
|
314
426
|
const result = (await this.httpServer.sendCommand('get_text', {
|
|
315
|
-
tabId: this.
|
|
427
|
+
tabId: this.requireCurrentTabId(),
|
|
316
428
|
frameId: this.currentFrameId || undefined,
|
|
317
429
|
selector,
|
|
318
430
|
}));
|
|
@@ -320,7 +432,7 @@ export class ExtensionBridge {
|
|
|
320
432
|
}
|
|
321
433
|
async getHtml(selector, outer = true) {
|
|
322
434
|
const result = (await this.httpServer.sendCommand('get_html', {
|
|
323
|
-
tabId: this.
|
|
435
|
+
tabId: this.requireCurrentTabId(),
|
|
324
436
|
frameId: this.currentFrameId || undefined,
|
|
325
437
|
selector,
|
|
326
438
|
outer,
|
|
@@ -343,13 +455,13 @@ export class ExtensionBridge {
|
|
|
343
455
|
}
|
|
344
456
|
async screenshot(options) {
|
|
345
457
|
return (await this.httpServer.sendCommand('screenshot', {
|
|
346
|
-
tabId: this.
|
|
458
|
+
tabId: this.requireCurrentTabId(),
|
|
347
459
|
...options,
|
|
348
460
|
}));
|
|
349
461
|
}
|
|
350
462
|
async getHtmlWithImages(selector, outer = true) {
|
|
351
463
|
return (await this.httpServer.sendCommand('get_html_with_images', {
|
|
352
|
-
tabId: this.
|
|
464
|
+
tabId: this.requireCurrentTabId(),
|
|
353
465
|
frameId: this.currentFrameId || undefined,
|
|
354
466
|
selector,
|
|
355
467
|
outer,
|
|
@@ -357,7 +469,7 @@ export class ExtensionBridge {
|
|
|
357
469
|
}
|
|
358
470
|
async getAttribute(selector, refId, attribute) {
|
|
359
471
|
const result = (await this.httpServer.sendCommand('get_attribute', {
|
|
360
|
-
tabId: this.
|
|
472
|
+
tabId: this.requireCurrentTabId(),
|
|
361
473
|
frameId: this.currentFrameId || undefined,
|
|
362
474
|
selector,
|
|
363
475
|
refId,
|
|
@@ -367,10 +479,15 @@ export class ExtensionBridge {
|
|
|
367
479
|
}
|
|
368
480
|
async getMetadata() {
|
|
369
481
|
return (await this.httpServer.sendCommand('get_metadata', {
|
|
370
|
-
tabId: this.
|
|
482
|
+
tabId: this.requireCurrentTabId(),
|
|
371
483
|
frameId: this.currentFrameId || undefined,
|
|
372
484
|
}));
|
|
373
485
|
}
|
|
486
|
+
async getFrames() {
|
|
487
|
+
return (await this.httpServer.sendCommand('get_all_frames', {
|
|
488
|
+
tabId: this.requireCurrentTabId(),
|
|
489
|
+
}));
|
|
490
|
+
}
|
|
374
491
|
async getCookies(filter) {
|
|
375
492
|
return (await this.httpServer.sendCommand('cookies_get', filter ?? {}));
|
|
376
493
|
}
|
|
@@ -393,7 +510,7 @@ export class ExtensionBridge {
|
|
|
393
510
|
}
|
|
394
511
|
async debuggerSend(method, params, tabId, timeout) {
|
|
395
512
|
return await this.httpServer.sendCommand('debugger_send', {
|
|
396
|
-
tabId: tabId ?? this.
|
|
513
|
+
tabId: tabId ?? this.requireCurrentTabId(),
|
|
397
514
|
method,
|
|
398
515
|
params,
|
|
399
516
|
}, timeout);
|
|
@@ -401,7 +518,7 @@ export class ExtensionBridge {
|
|
|
401
518
|
// ==================== Debugger (CDP via Extension) ====================
|
|
402
519
|
async inputKey(type, options = {}) {
|
|
403
520
|
await this.httpServer.sendCommand('input_key', {
|
|
404
|
-
tabId: this.
|
|
521
|
+
tabId: this.requireCurrentTabId(),
|
|
405
522
|
type,
|
|
406
523
|
...options,
|
|
407
524
|
});
|
|
@@ -409,7 +526,7 @@ export class ExtensionBridge {
|
|
|
409
526
|
// ==================== 输入事件(通过 CDP)====================
|
|
410
527
|
async inputMouse(type, x, y, options = {}) {
|
|
411
528
|
await this.httpServer.sendCommand('input_mouse', {
|
|
412
|
-
tabId: this.
|
|
529
|
+
tabId: this.requireCurrentTabId(),
|
|
413
530
|
type,
|
|
414
531
|
x,
|
|
415
532
|
y,
|
|
@@ -418,40 +535,40 @@ export class ExtensionBridge {
|
|
|
418
535
|
}
|
|
419
536
|
async inputTouch(type, touchPoints) {
|
|
420
537
|
await this.httpServer.sendCommand('input_touch', {
|
|
421
|
-
tabId: this.
|
|
538
|
+
tabId: this.requireCurrentTabId(),
|
|
422
539
|
type,
|
|
423
540
|
touchPoints,
|
|
424
541
|
});
|
|
425
542
|
}
|
|
426
543
|
async inputType(text, delay = 0) {
|
|
427
544
|
await this.httpServer.sendCommand('input_type', {
|
|
428
|
-
tabId: this.
|
|
545
|
+
tabId: this.requireCurrentTabId(),
|
|
429
546
|
text,
|
|
430
547
|
delay,
|
|
431
548
|
});
|
|
432
549
|
}
|
|
433
550
|
async consoleEnable() {
|
|
434
551
|
await this.httpServer.sendCommand('console_enable', {
|
|
435
|
-
tabId: this.
|
|
552
|
+
tabId: this.requireCurrentTabId(),
|
|
436
553
|
});
|
|
437
554
|
}
|
|
438
555
|
// ==================== 控制台日志 ====================
|
|
439
556
|
async consoleGet(options = {}) {
|
|
440
557
|
const result = (await this.httpServer.sendCommand('console_get', {
|
|
441
|
-
tabId: this.
|
|
558
|
+
tabId: this.requireCurrentTabId(),
|
|
442
559
|
...options,
|
|
443
560
|
}));
|
|
444
561
|
return result.messages;
|
|
445
562
|
}
|
|
446
563
|
async networkEnable() {
|
|
447
564
|
await this.httpServer.sendCommand('network_enable', {
|
|
448
|
-
tabId: this.
|
|
565
|
+
tabId: this.requireCurrentTabId(),
|
|
449
566
|
});
|
|
450
567
|
}
|
|
451
568
|
// ==================== 网络日志 ====================
|
|
452
569
|
async networkGet(options = {}) {
|
|
453
570
|
const result = (await this.httpServer.sendCommand('network_get', {
|
|
454
|
-
tabId: this.
|
|
571
|
+
tabId: this.requireCurrentTabId(),
|
|
455
572
|
...options,
|
|
456
573
|
}));
|
|
457
574
|
return result.requests;
|
|
@@ -461,7 +578,7 @@ export class ExtensionBridge {
|
|
|
461
578
|
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
462
579
|
}
|
|
463
580
|
const params = {
|
|
464
|
-
tabId: this.
|
|
581
|
+
tabId: this.requireCurrentTabId(),
|
|
465
582
|
frameId: this.currentFrameId !== null ? this.currentFrameId : undefined,
|
|
466
583
|
text,
|
|
467
584
|
delay,
|
|
@@ -474,7 +591,7 @@ export class ExtensionBridge {
|
|
|
474
591
|
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
475
592
|
}
|
|
476
593
|
const params = {
|
|
477
|
-
tabId: this.
|
|
594
|
+
tabId: this.requireCurrentTabId(),
|
|
478
595
|
frameId: this.currentFrameId !== null ? this.currentFrameId : undefined,
|
|
479
596
|
key,
|
|
480
597
|
type,
|
|
@@ -487,7 +604,7 @@ export class ExtensionBridge {
|
|
|
487
604
|
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
488
605
|
}
|
|
489
606
|
const params = {
|
|
490
|
-
tabId: this.
|
|
607
|
+
tabId: this.requireCurrentTabId(),
|
|
491
608
|
frameId: this.currentFrameId !== null ? this.currentFrameId : undefined,
|
|
492
609
|
x,
|
|
493
610
|
y,
|
|
@@ -504,7 +621,7 @@ export class ExtensionBridge {
|
|
|
504
621
|
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
505
622
|
}
|
|
506
623
|
const params = {
|
|
507
|
-
tabId: this.
|
|
624
|
+
tabId: this.requireCurrentTabId(),
|
|
508
625
|
frameId: this.currentFrameId !== null ? this.currentFrameId : undefined,
|
|
509
626
|
type,
|
|
510
627
|
x,
|
|
@@ -518,7 +635,7 @@ export class ExtensionBridge {
|
|
|
518
635
|
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
519
636
|
}
|
|
520
637
|
const params = {
|
|
521
|
-
tabId: this.
|
|
638
|
+
tabId: this.requireCurrentTabId(),
|
|
522
639
|
frameId: this.currentFrameId !== null ? this.currentFrameId : undefined,
|
|
523
640
|
};
|
|
524
641
|
await this.httpServer.sendCommand('stealth_inject', params);
|
|
@@ -538,7 +655,7 @@ export class ExtensionBridge {
|
|
|
538
655
|
*/
|
|
539
656
|
async evaluateInFrame(frameId, expression, timeout) {
|
|
540
657
|
return (await this.httpServer.sendCommand('evaluate_in_frame', {
|
|
541
|
-
tabId: this.
|
|
658
|
+
tabId: this.requireCurrentTabId(),
|
|
542
659
|
frameId,
|
|
543
660
|
expression,
|
|
544
661
|
returnByValue: true,
|
|
@@ -551,10 +668,36 @@ export class ExtensionBridge {
|
|
|
551
668
|
*/
|
|
552
669
|
async resolveFrame(frame) {
|
|
553
670
|
return (await this.httpServer.sendCommand('resolve_frame', {
|
|
554
|
-
tabId: this.
|
|
671
|
+
tabId: this.requireCurrentTabId(),
|
|
555
672
|
frame,
|
|
556
673
|
}));
|
|
557
674
|
}
|
|
675
|
+
requireCurrentTabId() {
|
|
676
|
+
if (this.currentTabId === null) {
|
|
677
|
+
throw new DriverCapabilityError('没有当前页面,请先 browse attach 或先 browse open 创建受控页面');
|
|
678
|
+
}
|
|
679
|
+
return this.currentTabId;
|
|
680
|
+
}
|
|
681
|
+
normalizePageChange(result) {
|
|
682
|
+
return {
|
|
683
|
+
targetId: result.targetId,
|
|
684
|
+
windowId: result.windowId,
|
|
685
|
+
before: this.normalizeAffected(result.before),
|
|
686
|
+
after: this.normalizeAffected(result.after),
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
normalizeAffected(value) {
|
|
690
|
+
if (!value) {
|
|
691
|
+
return value;
|
|
692
|
+
}
|
|
693
|
+
if ('url' in value) {
|
|
694
|
+
return this.tabToTarget(value);
|
|
695
|
+
}
|
|
696
|
+
return {
|
|
697
|
+
...value,
|
|
698
|
+
tabs: value.tabs.map((tab) => this.tabToTarget(tab)),
|
|
699
|
+
};
|
|
700
|
+
}
|
|
558
701
|
parseTargetId(targetId) {
|
|
559
702
|
const parsed = parseInt(targetId, 10);
|
|
560
703
|
if (isNaN(parsed)) {
|
|
@@ -562,8 +705,25 @@ export class ExtensionBridge {
|
|
|
562
705
|
}
|
|
563
706
|
return parsed;
|
|
564
707
|
}
|
|
565
|
-
|
|
566
|
-
|
|
708
|
+
tabToTarget(tab) {
|
|
709
|
+
return {
|
|
710
|
+
id: tab.id,
|
|
711
|
+
targetId: String(tab.id),
|
|
712
|
+
url: tab.url,
|
|
713
|
+
title: tab.title,
|
|
714
|
+
type: 'page',
|
|
715
|
+
active: tab.active,
|
|
716
|
+
windowId: tab.windowId,
|
|
717
|
+
index: tab.index,
|
|
718
|
+
groupId: tab.groupId,
|
|
719
|
+
pinned: tab.pinned,
|
|
720
|
+
incognito: tab.incognito,
|
|
721
|
+
managed: tab.managed,
|
|
722
|
+
status: tab.status,
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
updateState(page) {
|
|
726
|
+
this.state = { url: page.url, title: page.title, managed: page.managed };
|
|
567
727
|
}
|
|
568
728
|
}
|
|
569
729
|
//# sourceMappingURL=bridge.js.map
|