appium-remote-debugger 11.4.1 → 11.5.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/CHANGELOG.md +12 -0
- package/build/lib/mixins/connect.d.ts +53 -56
- package/build/lib/mixins/connect.d.ts.map +1 -1
- package/build/lib/mixins/connect.js +72 -96
- package/build/lib/mixins/connect.js.map +1 -1
- package/build/lib/mixins/cookies.d.ts +22 -0
- package/build/lib/mixins/cookies.d.ts.map +1 -0
- package/build/lib/mixins/cookies.js +48 -0
- package/build/lib/mixins/cookies.js.map +1 -0
- package/build/lib/mixins/events.d.ts +17 -2
- package/build/lib/mixins/events.d.ts.map +1 -1
- package/build/lib/mixins/events.js +29 -2
- package/build/lib/mixins/events.js.map +1 -1
- package/build/lib/mixins/execute.d.ts +5 -12
- package/build/lib/mixins/execute.d.ts.map +1 -1
- package/build/lib/mixins/execute.js +18 -30
- package/build/lib/mixins/execute.js.map +1 -1
- package/build/lib/mixins/message-handlers.d.ts +13 -23
- package/build/lib/mixins/message-handlers.d.ts.map +1 -1
- package/build/lib/mixins/message-handlers.js +56 -27
- package/build/lib/mixins/message-handlers.js.map +1 -1
- package/build/lib/mixins/misc.d.ts +51 -0
- package/build/lib/mixins/misc.d.ts.map +1 -0
- package/build/lib/mixins/misc.js +132 -0
- package/build/lib/mixins/misc.js.map +1 -0
- package/build/lib/mixins/navigate.d.ts +20 -29
- package/build/lib/mixins/navigate.d.ts.map +1 -1
- package/build/lib/mixins/navigate.js +25 -23
- package/build/lib/mixins/navigate.js.map +1 -1
- package/build/lib/mixins/screenshot.d.ts +13 -0
- package/build/lib/mixins/screenshot.d.ts.map +1 -0
- package/build/lib/mixins/screenshot.js +31 -0
- package/build/lib/mixins/screenshot.js.map +1 -0
- package/build/lib/remote-debugger-real-device.d.ts +16 -2
- package/build/lib/remote-debugger-real-device.d.ts.map +1 -1
- package/build/lib/remote-debugger-real-device.js +11 -1
- package/build/lib/remote-debugger-real-device.js.map +1 -1
- package/build/lib/remote-debugger.d.ts +155 -174
- package/build/lib/remote-debugger.d.ts.map +1 -1
- package/build/lib/remote-debugger.js +149 -210
- package/build/lib/remote-debugger.js.map +1 -1
- package/build/lib/rpc/rpc-client.d.ts +14 -13
- package/build/lib/rpc/rpc-client.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client.js +8 -6
- package/build/lib/rpc/rpc-client.js.map +1 -1
- package/build/lib/utils.d.ts +20 -16
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +33 -25
- package/build/lib/utils.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/mixins/connect.js +77 -111
- package/lib/mixins/cookies.js +45 -0
- package/lib/mixins/events.js +25 -1
- package/lib/mixins/execute.js +18 -39
- package/lib/mixins/message-handlers.js +67 -36
- package/lib/mixins/misc.js +128 -0
- package/lib/mixins/navigate.js +26 -30
- package/lib/mixins/screenshot.js +34 -0
- package/lib/remote-debugger-real-device.js +14 -1
- package/lib/remote-debugger.js +138 -302
- package/lib/rpc/rpc-client.js +9 -7
- package/lib/utils.js +42 -38
- package/package.json +1 -1
- package/build/lib/mixins/index.d.ts +0 -5
- package/build/lib/mixins/index.d.ts.map +0 -1
- package/build/lib/mixins/index.js +0 -16
- package/build/lib/mixins/index.js.map +0 -1
- package/lib/mixins/index.js +0 -14
package/lib/remote-debugger.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import
|
|
2
|
+
import defaultLog from './logger';
|
|
3
3
|
import { RpcClientSimulator } from './rpc';
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { getModuleProperties } from './utils';
|
|
5
|
+
import * as connectMixins from './mixins/connect';
|
|
6
|
+
import * as executeMixins from './mixins/execute';
|
|
7
|
+
import * as messageHandlerMixins from './mixins/message-handlers';
|
|
8
|
+
import * as navigationMixins from './mixins/navigate';
|
|
9
|
+
import * as cookieMixins from './mixins/cookies';
|
|
10
|
+
import * as screenshotMixins from './mixins/screenshot';
|
|
11
|
+
import * as eventMixins from './mixins/events';
|
|
12
|
+
import * as miscellaneousMixins from './mixins/misc';
|
|
6
13
|
import _ from 'lodash';
|
|
7
|
-
import B from 'bluebird';
|
|
8
|
-
import path from 'path';
|
|
9
14
|
import AsyncLock from 'async-lock';
|
|
10
15
|
|
|
11
|
-
const REMOTE_DEBUGGER_PORT = 27753;
|
|
12
|
-
const SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
|
|
13
|
-
|
|
16
|
+
export const REMOTE_DEBUGGER_PORT = 27753;
|
|
14
17
|
/* How many milliseconds to wait for webkit to return a response before timing out */
|
|
15
|
-
const RPC_RESPONSE_TIMEOUT_MS = 5000;
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
+
export const RPC_RESPONSE_TIMEOUT_MS = 5000;
|
|
19
|
+
const PAGE_READY_TIMEOUT_MS = 5000;
|
|
20
|
+
const { version: MODULE_VERSION } = getModuleProperties();
|
|
18
21
|
|
|
19
|
-
const GARBAGE_COLLECT_TIMEOUT = 5000;
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
class RemoteDebugger extends EventEmitter {
|
|
23
|
+
export class RemoteDebugger extends EventEmitter {
|
|
23
24
|
// properties
|
|
24
|
-
/** @type {
|
|
25
|
+
/** @type {string[]|undefined} */
|
|
25
26
|
_skippedApps;
|
|
26
27
|
/** @type {Record<string, any>} */
|
|
27
28
|
_clientEventListeners;
|
|
@@ -29,20 +30,24 @@ class RemoteDebugger extends EventEmitter {
|
|
|
29
30
|
appDict;
|
|
30
31
|
/** @type {string|null|undefined} */
|
|
31
32
|
appIdKey;
|
|
33
|
+
/** @type {string|number|null|undefined} */
|
|
34
|
+
pageIdKey;
|
|
32
35
|
/** @type {Record<string, any>[]|undefined} */
|
|
33
36
|
connectedDrivers;
|
|
34
37
|
/** @type {Record<string, any>[]|undefined} */
|
|
35
38
|
currentState;
|
|
36
39
|
/** @type {boolean|undefined} */
|
|
37
40
|
connected;
|
|
38
|
-
/** @type {
|
|
41
|
+
/** @type {import('bluebird')<void>} */
|
|
39
42
|
pageLoadDelay;
|
|
40
|
-
/** @type {
|
|
43
|
+
/** @type {import('bluebird')<void>} */
|
|
41
44
|
navigationDelay;
|
|
42
|
-
/** @type {import('./rpc/rpc-client').
|
|
45
|
+
/** @type {import('./rpc/rpc-client').RpcClient?} */
|
|
43
46
|
rpcClient;
|
|
44
47
|
/** @type {string|undefined} */
|
|
45
48
|
pageLoadStrategy;
|
|
49
|
+
/** @type {import('@appium/types').AppiumLogger} */
|
|
50
|
+
_log;
|
|
46
51
|
|
|
47
52
|
// events
|
|
48
53
|
/** @type {string} */
|
|
@@ -53,83 +58,46 @@ class RemoteDebugger extends EventEmitter {
|
|
|
53
58
|
static EVENT_FRAMES_DETACHED;
|
|
54
59
|
|
|
55
60
|
// methods
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
/** @type {(url: string) => Promise<void>} */
|
|
87
|
-
navToUrl;
|
|
61
|
+
setConnectionKey = connectMixins.setConnectionKey;
|
|
62
|
+
disconnect = connectMixins.disconnect;
|
|
63
|
+
searchForApp = connectMixins.searchForApp;
|
|
64
|
+
searchForPage = connectMixins.searchForPage;
|
|
65
|
+
checkPageIsReady = navigationMixins.checkPageIsReady;
|
|
66
|
+
cancelPageLoad = navigationMixins.cancelPageLoad;
|
|
67
|
+
waitForDom = navigationMixins.waitForDom;
|
|
68
|
+
execute = executeMixins.execute;
|
|
69
|
+
executeAtom = executeMixins.executeAtom;
|
|
70
|
+
executeAtomAsync = executeMixins.executeAtomAsync;
|
|
71
|
+
isPageLoadingCompleted = navigationMixins.isPageLoadingCompleted;
|
|
72
|
+
selectApp = connectMixins.selectApp;
|
|
73
|
+
connect = connectMixins.connect;
|
|
74
|
+
selectPage = connectMixins.selectPage;
|
|
75
|
+
navToUrl = navigationMixins.navToUrl;
|
|
76
|
+
getCookies = cookieMixins.getCookies;
|
|
77
|
+
setCookie = cookieMixins.setCookie;
|
|
78
|
+
deleteCookie = cookieMixins.deleteCookie;
|
|
79
|
+
captureScreenshot = screenshotMixins.captureScreenshot;
|
|
80
|
+
addClientEventListener = eventMixins.addClientEventListener;
|
|
81
|
+
removeClientEventListener = eventMixins.removeClientEventListener;
|
|
82
|
+
launchSafari = miscellaneousMixins.launchSafari;
|
|
83
|
+
startTimeline = miscellaneousMixins.startTimeline;
|
|
84
|
+
stopTimeline = miscellaneousMixins.stopTimeline;
|
|
85
|
+
startConsole = miscellaneousMixins.startConsole;
|
|
86
|
+
stopConsole = miscellaneousMixins.stopConsole;
|
|
87
|
+
startNetwork = miscellaneousMixins.startNetwork;
|
|
88
|
+
stopNetwork = miscellaneousMixins.stopNetwork;
|
|
89
|
+
overrideUserAgent = miscellaneousMixins.overrideUserAgent;
|
|
90
|
+
garbageCollect = miscellaneousMixins.garbageCollect;
|
|
88
91
|
|
|
89
92
|
// Callbacks
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
/** @type {(err: Error?, dict: Record<string, any>) => Promise<void>} */
|
|
99
|
-
onAppUpdate;
|
|
100
|
-
/** @type {(err: Error?, drivers: Record<string, any>) => void} */
|
|
101
|
-
onConnectedDriverList;
|
|
102
|
-
/** @type {(err: Error?, state: Record<string, any>) => void} */
|
|
103
|
-
onCurrentState;
|
|
104
|
-
/** @type {(err: Error?, state: Record<string, any>) => void} */
|
|
105
|
-
frameDetached;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @typedef {Object} RemoteDebuggerOptions
|
|
109
|
-
* @property {string} [bundleId] id of the app being connected to
|
|
110
|
-
* @property {string[]} [additionalBundleIds=[]] array of possible bundle
|
|
111
|
-
* ids that the inspector could return
|
|
112
|
-
* @property {string} [platformVersion] version of iOS
|
|
113
|
-
* @property {boolean} [isSafari=true]
|
|
114
|
-
* @property {boolean} [includeSafari=false]
|
|
115
|
-
* @property {boolean} [useNewSafari=false] for web inspector, whether this is a new Safari instance
|
|
116
|
-
* @property {number} [pageLoadMs] the time, in ms, that should be waited for page loading
|
|
117
|
-
* @property {string} [host] the remote debugger's host address
|
|
118
|
-
* @property {number} [port=REMOTE_DEBUGGER_PORT] the remote debugger port through which to communicate
|
|
119
|
-
* @property {string} [socketPath]
|
|
120
|
-
* @property {number} [pageReadyTimeout=PAGE_READY_TIMEOUT]
|
|
121
|
-
* @property {string} [remoteDebugProxy]
|
|
122
|
-
* @property {boolean} [garbageCollectOnExecute=false]
|
|
123
|
-
* @property {boolean} [logFullResponse=false]
|
|
124
|
-
* @property {boolean} [logAllCommunication=false] log plists sent and received from Web Inspector
|
|
125
|
-
* @property {boolean} [logAllCommunicationHexDump=false] log communication from Web Inspector as hex dump
|
|
126
|
-
* @property {number} [webInspectorMaxFrameLength] The maximum size in bytes of a single data
|
|
127
|
-
* frame in the device communication protocol
|
|
128
|
-
* @property {number} [socketChunkSize] size, in bytes, of chunks of data sent to
|
|
129
|
-
* Web Inspector (real device only)
|
|
130
|
-
* @property {boolean} [fullPageInitialization]
|
|
131
|
-
* @property {string} [pageLoadStrategy]
|
|
132
|
-
*/
|
|
93
|
+
onPageChange = messageHandlerMixins.onPageChange;
|
|
94
|
+
onConnectedApplicationList = messageHandlerMixins.onConnectedApplicationList;
|
|
95
|
+
onAppConnect = messageHandlerMixins.onAppConnect;
|
|
96
|
+
onAppDisconnect = messageHandlerMixins.onAppDisconnect;
|
|
97
|
+
onAppUpdate = messageHandlerMixins.onAppUpdate;
|
|
98
|
+
onConnectedDriverList = messageHandlerMixins.onConnectedDriverList;
|
|
99
|
+
onCurrentState = messageHandlerMixins.onCurrentState;
|
|
100
|
+
frameDetached = navigationMixins.frameDetached;
|
|
133
101
|
|
|
134
102
|
/**
|
|
135
103
|
* @param {RemoteDebuggerOptions} opts
|
|
@@ -137,8 +105,9 @@ class RemoteDebugger extends EventEmitter {
|
|
|
137
105
|
constructor (opts = {}) {
|
|
138
106
|
super();
|
|
139
107
|
|
|
140
|
-
//
|
|
141
|
-
|
|
108
|
+
// @ts-ignore This is OK
|
|
109
|
+
this._log = opts.log ?? defaultLog;
|
|
110
|
+
this.log.info(`Remote Debugger version ${MODULE_VERSION}`);
|
|
142
111
|
|
|
143
112
|
const {
|
|
144
113
|
bundleId,
|
|
@@ -151,7 +120,7 @@ class RemoteDebugger extends EventEmitter {
|
|
|
151
120
|
host,
|
|
152
121
|
port = REMOTE_DEBUGGER_PORT,
|
|
153
122
|
socketPath,
|
|
154
|
-
pageReadyTimeout =
|
|
123
|
+
pageReadyTimeout = PAGE_READY_TIMEOUT_MS,
|
|
155
124
|
remoteDebugProxy,
|
|
156
125
|
garbageCollectOnExecute = false,
|
|
157
126
|
logFullResponse = false,
|
|
@@ -160,7 +129,7 @@ class RemoteDebugger extends EventEmitter {
|
|
|
160
129
|
webInspectorMaxFrameLength,
|
|
161
130
|
socketChunkSize,
|
|
162
131
|
fullPageInitialization,
|
|
163
|
-
pageLoadStrategy
|
|
132
|
+
pageLoadStrategy,
|
|
164
133
|
} = opts;
|
|
165
134
|
|
|
166
135
|
this.bundleId = bundleId;
|
|
@@ -170,7 +139,7 @@ class RemoteDebugger extends EventEmitter {
|
|
|
170
139
|
this.includeSafari = includeSafari;
|
|
171
140
|
this.useNewSafari = useNewSafari;
|
|
172
141
|
this.pageLoadMs = pageLoadMs;
|
|
173
|
-
log.debug(`useNewSafari --> ${this.useNewSafari}`);
|
|
142
|
+
this.log.debug(`useNewSafari --> ${this.useNewSafari}`);
|
|
174
143
|
|
|
175
144
|
this.garbageCollectOnExecute = garbageCollectOnExecute;
|
|
176
145
|
|
|
@@ -195,6 +164,30 @@ class RemoteDebugger extends EventEmitter {
|
|
|
195
164
|
this._lock = new AsyncLock();
|
|
196
165
|
}
|
|
197
166
|
|
|
167
|
+
/**
|
|
168
|
+
* @returns {import('@appium/types').AppiumLogger}
|
|
169
|
+
*/
|
|
170
|
+
get log() {
|
|
171
|
+
return this._log;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @param {boolean} [checkConnected=false]
|
|
176
|
+
* @returns {import('./rpc/rpc-client').RpcClient}
|
|
177
|
+
*/
|
|
178
|
+
requireRpcClient(checkConnected = false) {
|
|
179
|
+
if (!this.rpcClient) {
|
|
180
|
+
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
181
|
+
}
|
|
182
|
+
if (checkConnected && !this.rpcClient.isConnected) {
|
|
183
|
+
throw new Error('Remote debugger is not connected');
|
|
184
|
+
}
|
|
185
|
+
return this.rpcClient;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @returns {void}
|
|
190
|
+
*/
|
|
198
191
|
setup () {
|
|
199
192
|
// app handling configuration
|
|
200
193
|
this.appDict = {};
|
|
@@ -208,8 +201,11 @@ class RemoteDebugger extends EventEmitter {
|
|
|
208
201
|
this._clientEventListeners = {};
|
|
209
202
|
}
|
|
210
203
|
|
|
204
|
+
/**
|
|
205
|
+
* @returns {void}
|
|
206
|
+
*/
|
|
211
207
|
teardown () {
|
|
212
|
-
log.debug('Cleaning up listeners');
|
|
208
|
+
this.log.debug('Cleaning up listeners');
|
|
213
209
|
|
|
214
210
|
this.appDict = {};
|
|
215
211
|
this.appIdKey = null;
|
|
@@ -222,6 +218,9 @@ class RemoteDebugger extends EventEmitter {
|
|
|
222
218
|
this.removeAllListeners(RemoteDebugger.EVENT_DISCONNECT);
|
|
223
219
|
}
|
|
224
220
|
|
|
221
|
+
/**
|
|
222
|
+
* @returns {void}
|
|
223
|
+
*/
|
|
225
224
|
initRpcClient () {
|
|
226
225
|
this.rpcClient = new RpcClientSimulator({
|
|
227
226
|
bundleId: this.bundleId,
|
|
@@ -238,228 +237,65 @@ class RemoteDebugger extends EventEmitter {
|
|
|
238
237
|
});
|
|
239
238
|
}
|
|
240
239
|
|
|
240
|
+
/**
|
|
241
|
+
* @returns {boolean}
|
|
242
|
+
*/
|
|
241
243
|
get isConnected () {
|
|
242
244
|
return !!this.rpcClient?.isConnected;
|
|
243
245
|
}
|
|
244
246
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
await this.rpcClient.send('launchApplication', {
|
|
251
|
-
bundleId: SAFARI_BUNDLE_ID
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
async startTimeline (fn) {
|
|
256
|
-
if (!this.rpcClient) {
|
|
257
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
log.debug('Starting to record the timeline');
|
|
261
|
-
this.rpcClient.on('Timeline.eventRecorded', fn);
|
|
262
|
-
return await this.rpcClient.send('Timeline.start', {
|
|
263
|
-
appIdKey: this.appIdKey,
|
|
264
|
-
pageIdKey: this.pageIdKey,
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
async stopTimeline () {
|
|
269
|
-
if (!this.rpcClient) {
|
|
270
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
log.debug('Stopping to record the timeline');
|
|
274
|
-
await this.rpcClient.send('Timeline.stop', {
|
|
275
|
-
appIdKey: this.appIdKey,
|
|
276
|
-
pageIdKey: this.pageIdKey,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/*
|
|
281
|
-
* Keep track of the client event listeners so they can be removed
|
|
247
|
+
/**
|
|
248
|
+
* @param {boolean} allow
|
|
282
249
|
*/
|
|
283
|
-
addClientEventListener (eventName, listener) {
|
|
284
|
-
if (!this.rpcClient) {
|
|
285
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
this._clientEventListeners[eventName] = this._clientEventListeners[eventName] || [];
|
|
289
|
-
this._clientEventListeners[eventName].push(listener);
|
|
290
|
-
this.rpcClient.on(eventName, listener);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
removeClientEventListener (eventName) {
|
|
294
|
-
if (!this.rpcClient) {
|
|
295
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
for (const listener of (this._clientEventListeners[eventName] || [])) {
|
|
299
|
-
this.rpcClient.off(eventName, listener);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
startConsole (listener) {
|
|
304
|
-
log.debug('Starting to listen for JavaScript console');
|
|
305
|
-
this.addClientEventListener('Console.messageAdded', listener);
|
|
306
|
-
this.addClientEventListener('Console.messageRepeatCountUpdated', listener);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
stopConsole () {
|
|
310
|
-
log.debug('Stopping to listen for JavaScript console');
|
|
311
|
-
this.removeClientEventListener('Console.messageAdded');
|
|
312
|
-
this.removeClientEventListener('Console.messageRepeatCountUpdated');
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
startNetwork (listener) {
|
|
316
|
-
log.debug('Starting to listen for network events');
|
|
317
|
-
this.addClientEventListener('NetworkEvent', listener);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
stopNetwork () {
|
|
321
|
-
log.debug('Stopping to listen for network events');
|
|
322
|
-
this.removeClientEventListener('NetworkEvent');
|
|
323
|
-
}
|
|
324
|
-
|
|
325
250
|
set allowNavigationWithoutReload (allow) {
|
|
326
251
|
this._allowNavigationWithoutReload = allow;
|
|
327
252
|
}
|
|
328
253
|
|
|
254
|
+
/**
|
|
255
|
+
* @returns {boolean}
|
|
256
|
+
*/
|
|
329
257
|
get allowNavigationWithoutReload () {
|
|
330
|
-
return this._allowNavigationWithoutReload;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Potentially this does not work for mobile safari
|
|
334
|
-
async overrideUserAgent (value) {
|
|
335
|
-
log.debug('Setting overrideUserAgent');
|
|
336
|
-
if (!this.rpcClient) {
|
|
337
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
return await this.rpcClient.send('Page.overrideUserAgent', {
|
|
341
|
-
appIdKey: this.appIdKey,
|
|
342
|
-
pageIdKey: this.pageIdKey,
|
|
343
|
-
value
|
|
344
|
-
});
|
|
258
|
+
return !!this._allowNavigationWithoutReload;
|
|
345
259
|
}
|
|
346
260
|
|
|
347
261
|
/**
|
|
348
|
-
*
|
|
349
|
-
* @param {{rect?: import('@appium/types').Rect|null, coordinateSystem?: "Viewport"|"Page"}} [opts={rect: null, coordinateSystem: 'Viewport'}]
|
|
350
|
-
* if rect is null capture the whole coordinate system else capture the rect in the given coordinateSystem
|
|
351
|
-
* @returns {Promise<string>} a base64 encoded string of the screenshot
|
|
262
|
+
* @returns {string[]}
|
|
352
263
|
*/
|
|
353
|
-
async captureScreenshot(opts) {
|
|
354
|
-
const {rect = null, coordinateSystem = 'Viewport'} = opts ?? {};
|
|
355
|
-
log.debug('Capturing screenshot');
|
|
356
|
-
if (!this.rpcClient) {
|
|
357
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
const arect = rect ?? /** @type {import('@appium/types').Rect} */ (await this.executeAtom(
|
|
361
|
-
'execute_script',
|
|
362
|
-
['return {x: 0, y: 0, width: window.innerWidth, height: window.innerHeight}', []]
|
|
363
|
-
));
|
|
364
|
-
const response = await this.rpcClient.send('Page.snapshotRect', {
|
|
365
|
-
...arect,
|
|
366
|
-
appIdKey: this.appIdKey,
|
|
367
|
-
pageIdKey: this.pageIdKey,
|
|
368
|
-
coordinateSystem,
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
if (response.error) {
|
|
372
|
-
throw new Error(response.error);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return response.dataURL.replace(/^data:image\/png;base64,/, '');
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
async getCookies () {
|
|
379
|
-
log.debug('Getting cookies');
|
|
380
|
-
if (!this.rpcClient) {
|
|
381
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
return await this.rpcClient.send('Page.getCookies', {
|
|
385
|
-
appIdKey: this.appIdKey,
|
|
386
|
-
pageIdKey: this.pageIdKey
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
async setCookie (cookie) {
|
|
391
|
-
log.debug('Setting cookie');
|
|
392
|
-
if (!this.rpcClient) {
|
|
393
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return await this.rpcClient.send('Page.setCookie', {
|
|
397
|
-
appIdKey: this.appIdKey,
|
|
398
|
-
pageIdKey: this.pageIdKey,
|
|
399
|
-
cookie
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
async deleteCookie (cookieName, url) {
|
|
404
|
-
log.debug(`Deleting cookie '${cookieName}' on '${url}'`);
|
|
405
|
-
if (!this.rpcClient) {
|
|
406
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return await this.rpcClient.send('Page.deleteCookie', {
|
|
410
|
-
appIdKey: this.appIdKey,
|
|
411
|
-
pageIdKey: this.pageIdKey,
|
|
412
|
-
cookieName,
|
|
413
|
-
url,
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
async garbageCollect (timeoutMs = GARBAGE_COLLECT_TIMEOUT) {
|
|
418
|
-
log.debug(`Garbage collecting with ${timeoutMs}ms timeout`);
|
|
419
|
-
if (!this.rpcClient) {
|
|
420
|
-
throw new Error(`rpcClient is undefined. Has 'initRpcClient' been called before?`);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
try {
|
|
424
|
-
checkParams({appIdKey: this.appIdKey, pageIdKey: this.pageIdKey});
|
|
425
|
-
} catch (err) {
|
|
426
|
-
log.debug(`Unable to collect garbage at this time`);
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
await B.resolve(this.rpcClient.send('Heap.gc', {
|
|
431
|
-
appIdKey: this.appIdKey,
|
|
432
|
-
pageIdKey: this.pageIdKey,
|
|
433
|
-
})).timeout(timeoutMs)
|
|
434
|
-
.then(function gcSuccess () { // eslint-disable-line promise/prefer-await-to-then
|
|
435
|
-
log.debug(`Garbage collection successful`);
|
|
436
|
-
}).catch(function gcError (err) { // eslint-disable-line promise/prefer-await-to-callbacks
|
|
437
|
-
if (err instanceof B.TimeoutError) {
|
|
438
|
-
log.debug(`Garbage collection timed out after ${timeoutMs}ms`);
|
|
439
|
-
} else {
|
|
440
|
-
log.debug(`Unable to collect garbage: ${err.message}`);
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
async useAppDictLock (fn) {
|
|
446
|
-
return await this._lock.acquire('appDict', fn);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
264
|
get skippedApps () {
|
|
450
|
-
return this._skippedApps
|
|
265
|
+
return this._skippedApps ?? [];
|
|
451
266
|
}
|
|
452
267
|
}
|
|
453
268
|
|
|
454
|
-
for (const [name,
|
|
455
|
-
RemoteDebugger.prototype[name] = fn;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
for (const [name, event] of _.toPairs(events)) {
|
|
269
|
+
for (const [name, event] of _.toPairs(eventMixins.events)) {
|
|
459
270
|
RemoteDebugger[name] = event;
|
|
460
271
|
}
|
|
461
272
|
|
|
462
273
|
export default RemoteDebugger;
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @typedef {Object} RemoteDebuggerOptions
|
|
277
|
+
* @property {string} [bundleId] id of the app being connected to
|
|
278
|
+
* @property {string[]} [additionalBundleIds=[]] array of possible bundle
|
|
279
|
+
* ids that the inspector could return
|
|
280
|
+
* @property {string} [platformVersion] version of iOS
|
|
281
|
+
* @property {boolean} [isSafari=true]
|
|
282
|
+
* @property {boolean} [includeSafari=false]
|
|
283
|
+
* @property {boolean} [useNewSafari=false] for web inspector, whether this is a new Safari instance
|
|
284
|
+
* @property {number} [pageLoadMs] the time, in ms, that should be waited for page loading
|
|
285
|
+
* @property {string} [host] the remote debugger's host address
|
|
286
|
+
* @property {number} [port=REMOTE_DEBUGGER_PORT] the remote debugger port through which to communicate
|
|
287
|
+
* @property {string} [socketPath]
|
|
288
|
+
* @property {number} [pageReadyTimeout=PAGE_READY_TIMEOUT]
|
|
289
|
+
* @property {string} [remoteDebugProxy]
|
|
290
|
+
* @property {boolean} [garbageCollectOnExecute=false]
|
|
291
|
+
* @property {boolean} [logFullResponse=false]
|
|
292
|
+
* @property {boolean} [logAllCommunication=false] log plists sent and received from Web Inspector
|
|
293
|
+
* @property {boolean} [logAllCommunicationHexDump=false] log communication from Web Inspector as hex dump
|
|
294
|
+
* @property {number} [webInspectorMaxFrameLength] The maximum size in bytes of a single data
|
|
295
|
+
* frame in the device communication protocol
|
|
296
|
+
* @property {number} [socketChunkSize] size, in bytes, of chunks of data sent to
|
|
297
|
+
* Web Inspector (real device only)
|
|
298
|
+
* @property {boolean} [fullPageInitialization]
|
|
299
|
+
* @property {string} [pageLoadStrategy]
|
|
300
|
+
* @property {import('@appium/types').AppiumLogger} [log]
|
|
301
|
+
*/
|
package/lib/rpc/rpc-client.js
CHANGED
|
@@ -29,7 +29,7 @@ function isTargetBased (isSafari, platformVersion) {
|
|
|
29
29
|
return isHighVersion;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export
|
|
32
|
+
export class RpcClient {
|
|
33
33
|
/** @type {RpcMessageHandler|undefined} */
|
|
34
34
|
messageHandler;
|
|
35
35
|
|
|
@@ -163,7 +163,7 @@ export default class RpcClient {
|
|
|
163
163
|
/**
|
|
164
164
|
*
|
|
165
165
|
* @param {string} appIdKey
|
|
166
|
-
* @param {string} pageIdKey
|
|
166
|
+
* @param {string|number} pageIdKey
|
|
167
167
|
* @param {boolean} [force]
|
|
168
168
|
* @returns {Promise<void>}
|
|
169
169
|
*/
|
|
@@ -471,7 +471,7 @@ export default class RpcClient {
|
|
|
471
471
|
|
|
472
472
|
/**
|
|
473
473
|
* @param {string} appIdKey
|
|
474
|
-
* @param {string} pageIdKey
|
|
474
|
+
* @param {string|number} pageIdKey
|
|
475
475
|
* @returns {any}
|
|
476
476
|
*/
|
|
477
477
|
getTarget (appIdKey, pageIdKey) {
|
|
@@ -480,11 +480,11 @@ export default class RpcClient {
|
|
|
480
480
|
|
|
481
481
|
/**
|
|
482
482
|
* @param {string} appIdKey
|
|
483
|
-
* @param {string} pageIdKey
|
|
483
|
+
* @param {string|number} pageIdKey
|
|
484
484
|
* @returns {Promise<void>}
|
|
485
485
|
*/
|
|
486
486
|
async selectPage (appIdKey, pageIdKey) {
|
|
487
|
-
/** @type {[string, string]} */
|
|
487
|
+
/** @type {[string, string|number]} */
|
|
488
488
|
this.pendingTargetNotification = [appIdKey, pageIdKey];
|
|
489
489
|
this.shouldCheckForTarget = false;
|
|
490
490
|
|
|
@@ -522,7 +522,7 @@ export default class RpcClient {
|
|
|
522
522
|
/**
|
|
523
523
|
* Perform the minimal initialization to get the Web Inspector working
|
|
524
524
|
* @param {string} appIdKey
|
|
525
|
-
* @param {string} pageIdKey
|
|
525
|
+
* @param {string|number} pageIdKey
|
|
526
526
|
* @returns {Promise<void>}
|
|
527
527
|
*/
|
|
528
528
|
async initializePage (appIdKey, pageIdKey) {
|
|
@@ -548,7 +548,7 @@ export default class RpcClient {
|
|
|
548
548
|
* Web Inspector session
|
|
549
549
|
*
|
|
550
550
|
* @param {string} appIdKey
|
|
551
|
-
* @param {string} pageIdKey
|
|
551
|
+
* @param {string|number} pageIdKey
|
|
552
552
|
* @returns {Promise<void>}
|
|
553
553
|
*/
|
|
554
554
|
async initializePageFull (appIdKey, pageIdKey) {
|
|
@@ -696,3 +696,5 @@ export default class RpcClient {
|
|
|
696
696
|
log.debug(`Script parsed: ${JSON.stringify(scriptInfo)}`);
|
|
697
697
|
}
|
|
698
698
|
}
|
|
699
|
+
|
|
700
|
+
export default RpcClient;
|