appium-remote-debugger 11.5.3 → 11.5.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/mixins/connect.d.ts +15 -41
  3. package/build/lib/mixins/connect.d.ts.map +1 -1
  4. package/build/lib/mixins/connect.js +80 -95
  5. package/build/lib/mixins/connect.js.map +1 -1
  6. package/build/lib/mixins/message-handlers.d.ts +4 -4
  7. package/build/lib/mixins/message-handlers.d.ts.map +1 -1
  8. package/build/lib/mixins/message-handlers.js +25 -67
  9. package/build/lib/mixins/message-handlers.js.map +1 -1
  10. package/build/lib/remote-debugger-real-device.d.ts.map +1 -1
  11. package/build/lib/remote-debugger-real-device.js +1 -5
  12. package/build/lib/remote-debugger-real-device.js.map +1 -1
  13. package/build/lib/remote-debugger.d.ts +0 -2
  14. package/build/lib/remote-debugger.d.ts.map +1 -1
  15. package/build/lib/remote-debugger.js +0 -2
  16. package/build/lib/remote-debugger.js.map +1 -1
  17. package/build/lib/rpc/remote-messages.d.ts +1 -1
  18. package/build/lib/rpc/remote-messages.d.ts.map +1 -1
  19. package/build/lib/rpc/remote-messages.js.map +1 -1
  20. package/build/lib/rpc/rpc-client-real-device.d.ts +10 -2
  21. package/build/lib/rpc/rpc-client-real-device.d.ts.map +1 -1
  22. package/build/lib/rpc/rpc-client-real-device.js +17 -0
  23. package/build/lib/rpc/rpc-client-real-device.js.map +1 -1
  24. package/build/lib/rpc/rpc-client-simulator.d.ts +33 -9
  25. package/build/lib/rpc/rpc-client-simulator.d.ts.map +1 -1
  26. package/build/lib/rpc/rpc-client-simulator.js +25 -1
  27. package/build/lib/rpc/rpc-client-simulator.js.map +1 -1
  28. package/build/lib/rpc/rpc-client.d.ts +114 -27
  29. package/build/lib/rpc/rpc-client.d.ts.map +1 -1
  30. package/build/lib/rpc/rpc-client.js +101 -27
  31. package/build/lib/rpc/rpc-client.js.map +1 -1
  32. package/build/lib/utils.d.ts +14 -7
  33. package/build/lib/utils.d.ts.map +1 -1
  34. package/build/lib/utils.js +15 -20
  35. package/build/lib/utils.js.map +1 -1
  36. package/build/tsconfig.tsbuildinfo +1 -1
  37. package/lib/mixins/connect.js +84 -105
  38. package/lib/mixins/message-handlers.js +30 -70
  39. package/lib/remote-debugger-real-device.js +1 -5
  40. package/lib/remote-debugger.js +1 -3
  41. package/lib/rpc/remote-messages.js +1 -2
  42. package/lib/rpc/rpc-client-real-device.js +18 -1
  43. package/lib/rpc/rpc-client-simulator.js +41 -2
  44. package/lib/rpc/rpc-client.js +149 -33
  45. package/lib/utils.js +15 -20
  46. package/package.json +1 -2
@@ -1,14 +1,12 @@
1
1
  import {
2
2
  pageArrayFromDict,
3
3
  getPossibleDebuggerAppKeys,
4
- simpleStringify,
5
4
  } from '../utils';
6
5
  import events from './events';
7
6
  import { timing } from '@appium/support';
8
7
  import { retryInterval, waitForCondition } from 'asyncbox';
9
8
  import _ from 'lodash';
10
9
 
11
-
12
10
  const APP_CONNECT_TIMEOUT_MS = 0;
13
11
  const APP_CONNECT_INTERVAL_MS = 100;
14
12
  const SELECT_APP_RETRIES = 20;
@@ -16,19 +14,6 @@ const SELECT_APP_RETRY_SLEEP_MS = 500;
16
14
  const SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
17
15
  const BLANK_PAGE_URL = 'about:blank';
18
16
 
19
- /**
20
- * @typedef {Object} AppPages
21
- * @property {string} appIdKey
22
- * @property {Record<string, any>} pageDict
23
- */
24
-
25
- /**
26
- * @typedef {Object} App
27
- * @property {string} id
28
- * @property {string} bundleId
29
- */
30
-
31
-
32
17
  /**
33
18
  *
34
19
  * @this {import('../remote-debugger').RemoteDebugger}
@@ -104,21 +89,12 @@ export async function disconnect () {
104
89
  this.teardown();
105
90
  }
106
91
 
107
- /**
108
- * @typedef {Object} Page
109
- * @property {string} url
110
- * @property {string} title
111
- * @property {number} id
112
- * @property {boolean} isKey
113
- * @property {string} [bundleId]
114
- */
115
-
116
92
  /**
117
93
  *
118
94
  * @this {import('../remote-debugger').RemoteDebugger}
119
- * @param {string?} currentUrl
120
- * @param {number} [maxTries]
121
- * @param {boolean} [ignoreAboutBlankUrl]
95
+ * @param {string?} [currentUrl=null]
96
+ * @param {number} [maxTries=SELECT_APP_RETRIES]
97
+ * @param {boolean} [ignoreAboutBlankUrl=false]
122
98
  * @returns {Promise<Page[]>}
123
99
  */
124
100
  export async function selectApp (currentUrl = null, maxTries = SELECT_APP_RETRIES, ignoreAboutBlankUrl = false) {
@@ -134,25 +110,14 @@ export async function selectApp (currentUrl = null, maxTries = SELECT_APP_RETRIE
134
110
  return [];
135
111
  }
136
112
 
137
- const {appIdKey, pageDict} = await this.searchForApp(currentUrl, maxTries, ignoreAboutBlankUrl) ?? {};
138
-
139
- // if, after all this, we have no dictionary, we have failed
140
- if (!appIdKey || !pageDict) {
141
- throw this.log.errorWithException(`Could not connect to a valid app after ${maxTries} tries.`);
142
- }
143
-
113
+ const { appIdKey } = await this.searchForApp(currentUrl, maxTries, ignoreAboutBlankUrl);
144
114
  if (this.appIdKey !== appIdKey) {
145
115
  this.log.debug(`Received altered app id, updating from '${this.appIdKey}' to '${appIdKey}'`);
146
116
  this.appIdKey = appIdKey;
147
117
  }
148
-
149
- logApplicationDictionary.bind(this)(this.appDict);
150
-
118
+ logApplicationDictionary.bind(this)();
151
119
  // translate the dictionary into a useful form, and return to sender
152
- const pageArray = _.isEmpty(this.appDict[appIdKey].pageArray)
153
- ? pageArrayFromDict(pageDict)
154
- : this.appDict[appIdKey].pageArray;
155
- this.log.debug(`Finally selecting app ${this.appIdKey}: ${simpleStringify(pageArray)}`);
120
+ this.log.debug(`Finally selecting app ${this.appIdKey}`);
156
121
 
157
122
  /** @type {Page[]} */
158
123
  const fullPageArray = [];
@@ -184,80 +149,85 @@ export async function selectApp (currentUrl = null, maxTries = SELECT_APP_RETRIE
184
149
  * @param {string?} currentUrl
185
150
  * @param {number} maxTries
186
151
  * @param {boolean} ignoreAboutBlankUrl
187
- * @returns {Promise<AppPages?>}
152
+ * @returns {Promise<AppPage>}
188
153
  */
189
154
  export async function searchForApp (currentUrl, maxTries, ignoreAboutBlankUrl) {
190
155
  const bundleIds = this.includeSafari && !this.isSafari
191
156
  ? [this.bundleId, ...this.additionalBundleIds, SAFARI_BUNDLE_ID]
192
157
  : [this.bundleId, ...this.additionalBundleIds];
193
158
  let retryCount = 0;
194
- try {
195
- return await retryInterval(maxTries, SELECT_APP_RETRY_SLEEP_MS, async () => {
196
- logApplicationDictionary.bind(this)(this.appDict);
197
- const possibleAppIds = getPossibleDebuggerAppKeys(/** @type {string[]} */ (bundleIds), this.appDict);
198
- this.log.debug(`Trying out the possible app ids: ${possibleAppIds.join(', ')} (try #${retryCount + 1} of ${maxTries})`);
199
- for (const attemptedAppIdKey of possibleAppIds) {
159
+ return /** @type {AppPage} */ (await retryInterval(maxTries, SELECT_APP_RETRY_SLEEP_MS, async () => {
160
+ logApplicationDictionary.bind(this)();
161
+ const possibleAppIds = getPossibleDebuggerAppKeys(/** @type {string[]} */ (bundleIds), this.appDict);
162
+ this.log.debug(`Trying out the possible app ids: ${possibleAppIds.join(', ')} (try #${retryCount + 1} of ${maxTries})`);
163
+ for (const attemptedAppIdKey of possibleAppIds) {
164
+ try {
165
+ if (!this.appDict[attemptedAppIdKey].isActive) {
166
+ this.log.debug(`Skipping app '${attemptedAppIdKey}' because it is not active`);
167
+ continue;
168
+ }
169
+
170
+ this.log.debug(`Attempting app '${attemptedAppIdKey}'`);
171
+ /** @type {string} */
172
+ let appIdKey;
173
+ /** @type {import('@appium/types').StringRecord} */
174
+ let pageDict;
200
175
  try {
201
- if (!this.appDict[attemptedAppIdKey].isActive) {
202
- this.log.debug(`Skipping app '${attemptedAppIdKey}' because it is not active`);
203
- continue;
204
- }
205
- this.log.debug(`Attempting app '${attemptedAppIdKey}'`);
206
- const [appIdKey, pageDict] = await this.requireRpcClient().selectApp(attemptedAppIdKey);
207
- // in iOS 8.2 the connect logic happens, but with an empty dictionary
208
- // which leads to the remote debugger getting disconnected, and into a loop
209
- if (_.isEmpty(pageDict)) {
210
- this.log.debug('Empty page dictionary received. Trying again.');
211
- continue;
212
- }
176
+ [appIdKey, pageDict] = await this.requireRpcClient().selectApp(attemptedAppIdKey);
177
+ } catch (e) {
178
+ this.log.info(`Skipping app '${attemptedAppIdKey}'. Original error: ${e.message}`);
179
+ continue;
180
+ }
213
181
 
214
- // save the page array for this app
215
- this.appDict[appIdKey].pageArray = pageArrayFromDict(pageDict);
182
+ // save the page array for this app
183
+ this.appDict[appIdKey].pageArray = pageArrayFromDict(pageDict);
216
184
 
217
- // if we are looking for a particular url, make sure we
218
- // have the right page. Ignore empty or undefined urls.
219
- // Ignore about:blank if requested.
220
- const result = this.searchForPage(this.appDict, currentUrl, ignoreAboutBlankUrl);
221
- if (result) {
222
- return result;
223
- }
185
+ // if we are looking for a particular url, make sure we
186
+ // have the right page. Ignore empty or undefined urls.
187
+ // Ignore about:blank if requested.
188
+ const result = this.searchForPage(this.appDict, currentUrl, ignoreAboutBlankUrl);
189
+ if (result) {
190
+ return result;
191
+ }
224
192
 
225
- if (currentUrl) {
226
- this.log.debug(`Received app, but expected url ('${currentUrl}') was not found. Trying again.`);
227
- } else {
228
- this.log.debug('Received app, but no match was found. Trying again.');
229
- }
230
- } catch (err) {
231
- this.log.debug(`Error checking application: '${err.message}'. Retrying connection`);
193
+ if (currentUrl) {
194
+ this.log.debug(`Received app, but expected url ('${currentUrl}') was not found. Trying again.`);
195
+ } else {
196
+ this.log.debug('Received app, but no match was found. Trying again.');
232
197
  }
198
+ } catch (err) {
199
+ this.log.debug(err.stack);
200
+ this.log.warn(`Error checking application ${attemptedAppIdKey}: '${err.message}'`);
233
201
  }
234
- retryCount++;
235
- throw new Error('Failed to find an app to select');
236
- });
237
- } catch (ign) {
238
- this.log.errorAndThrow(`Could not connect to a valid app after ${maxTries} tries.`);
239
- }
240
- return null;
202
+ }
203
+ retryCount++;
204
+ throw new Error(
205
+ `Could not connect to a valid webapp. Make sure it is debuggable and has at least one active page.`
206
+ );
207
+ }));
241
208
  }
242
209
 
243
210
  /**
244
211
  *
245
212
  * @this {import('../remote-debugger').RemoteDebugger}
246
- * @param {Record<string, any>} appsDict
213
+ * @param {Record<string, import('../utils').AppInfo>} appsDict
247
214
  * @param {string?} currentUrl
248
215
  * @param {boolean} [ignoreAboutBlankUrl]
249
- * @returns {AppPages?}
216
+ * @returns {AppPage?}
250
217
  */
251
218
  export function searchForPage (appsDict, currentUrl = null, ignoreAboutBlankUrl = false) {
252
219
  for (const appDict of _.values(appsDict)) {
253
- if (!appDict || !appDict.isActive || !appDict.pageArray || appDict.pageArray.promise) {
220
+ if (!appDict || !appDict.isActive || !appDict.pageArray || _.isEmpty(appDict.pageArray)) {
254
221
  continue;
255
222
  }
256
223
 
257
- for (const dict of appDict.pageArray) {
258
- if ((!ignoreAboutBlankUrl || dict.url !== BLANK_PAGE_URL) &&
259
- (!currentUrl || dict.url === currentUrl || dict.url === `${currentUrl}/`)) {
260
- return { appIdKey: appDict.id, pageDict: dict };
224
+ for (const page of appDict.pageArray) {
225
+ if ((!ignoreAboutBlankUrl || page.url !== BLANK_PAGE_URL) &&
226
+ (!currentUrl || page.url === currentUrl || page.url === `${currentUrl}/`)) {
227
+ return {
228
+ appIdKey: appDict.id,
229
+ pageDict: page
230
+ };
261
231
  }
262
232
  }
263
233
  }
@@ -292,23 +262,11 @@ export async function selectPage (appIdKey, pageIdKey, skipReadyCheck = false) {
292
262
 
293
263
  /**
294
264
  * @this {import('../remote-debugger').RemoteDebugger}
295
- * @param {Record<string, any>} apps
296
265
  * @returns {void}
297
266
  */
298
- function logApplicationDictionary (apps) {
299
-
300
- function getValueString (key, value) {
301
- if (_.isFunction(value)) {
302
- return '[Function]';
303
- }
304
- if (key === 'pageArray' && !_.isArray(value)) {
305
- return `"Waiting for data"`;
306
- }
307
- return JSON.stringify(value);
308
- }
309
-
267
+ function logApplicationDictionary () {
310
268
  this.log.debug('Current applications available:');
311
- for (const [app, info] of _.toPairs(apps)) {
269
+ for (const [app, info] of _.toPairs(this.appDict)) {
312
270
  this.log.debug(` Application: "${app}"`);
313
271
  for (const [key, value] of _.toPairs(info)) {
314
272
  if (key === 'pageArray' && Array.isArray(value) && value.length) {
@@ -321,9 +279,30 @@ function logApplicationDictionary (apps) {
321
279
  }
322
280
  }
323
281
  } else {
324
- const valueString = getValueString(key, value);
282
+ const valueString = _.isFunction(value) ? '[Function]' : JSON.stringify(value);
325
283
  this.log.debug(` ${key}: ${valueString}`);
326
284
  }
327
285
  }
328
286
  }
329
287
  }
288
+
289
+ /**
290
+ * @typedef {Object} AppPage
291
+ * @property {string} appIdKey
292
+ * @property {Page} pageDict
293
+ */
294
+
295
+ /**
296
+ * @typedef {Object} App
297
+ * @property {string} id
298
+ * @property {string} bundleId
299
+ */
300
+
301
+ /**
302
+ * @typedef {Object} Page
303
+ * @property {string} url
304
+ * @property {string} title
305
+ * @property {number} id
306
+ * @property {boolean} isKey
307
+ * @property {string} [bundleId]
308
+ */
@@ -2,9 +2,7 @@ import events from './events';
2
2
  import {
3
3
  pageArrayFromDict,
4
4
  getDebuggerAppKey,
5
- simpleStringify,
6
5
  appInfoFromDict,
7
- deferredPromise,
8
6
  } from '../utils';
9
7
  import _ from 'lodash';
10
8
 
@@ -21,48 +19,39 @@ import _ from 'lodash';
21
19
  * @param {Record<string, any>} pageDict
22
20
  * @returns {Promise<void>}
23
21
  */
22
+ // eslint-disable-next-line require-await
24
23
  export async function onPageChange (err, appIdKey, pageDict) {
25
24
  if (_.isEmpty(pageDict)) {
26
25
  return;
27
26
  }
28
27
 
29
- const pageArray = pageArrayFromDict(pageDict);
30
-
31
- await useAppDictLock.bind(this)((/** @type {() => void} */ done) => {
32
- try {
33
- // save the page dict for this app
34
- if (this.appDict[appIdKey]) {
35
- if (this.appDict[appIdKey].pageArray) {
36
- if (this.appDict[appIdKey].pageArray.resolve) {
37
- // pageDict is a pending promise, so resolve
38
- this.appDict[appIdKey].pageArray.resolve();
39
- } else {
40
- // we have a pre-existing pageDict
41
- if (_.isEqual(this.appDict[appIdKey].pageArray, pageArray)) {
42
- this.log.debug(`Received page change notice for app '${appIdKey}' ` +
43
- `but the listing has not changed. Ignoring.`);
44
- return done();
45
- }
46
- }
47
- }
48
- // keep track of the page dictionary
49
- this.appDict[appIdKey].pageArray = pageArray;
50
- }
51
- } finally {
52
- done();
28
+ const currentPages = pageArrayFromDict(pageDict);
29
+ // save the page dict for this app
30
+ if (this.appDict[appIdKey]) {
31
+ const previousPages = this.appDict[appIdKey].pageArray;
32
+ // we have a pre-existing pageDict
33
+ if (previousPages && _.isEqual(previousPages, currentPages)) {
34
+ this.log.debug(
35
+ `Received page change notice for app '${appIdKey}' ` +
36
+ `but the listing has not changed. Ignoring.`
37
+ );
38
+ return;
53
39
  }
54
- });
40
+ // keep track of the page dictionary
41
+ this.appDict[appIdKey].pageArray = currentPages;
42
+ this.log.debug(
43
+ `Pages changed for ${appIdKey}: ${JSON.stringify(previousPages)} -> ${JSON.stringify(currentPages)}`
44
+ );
45
+ }
55
46
 
56
47
  if (this._navigatingToPage) {
57
48
  // in the middle of navigating, so reporting a page change will cause problems
58
49
  return;
59
50
  }
60
51
 
61
- this.log.debug(`Page changed: ${simpleStringify(pageDict, true)}`);
62
-
63
52
  this.emit(events.EVENT_PAGE_CHANGE, {
64
53
  appIdKey: appIdKey.replace('PID:', ''),
65
- pageArray,
54
+ pageArray: currentPages,
66
55
  });
67
56
  }
68
57
 
@@ -72,28 +61,23 @@ export async function onPageChange (err, appIdKey, pageDict) {
72
61
  * @param {Record<string, any>} dict
73
62
  * @returns {Promise<void>}
74
63
  */
64
+ // eslint-disable-next-line require-await
75
65
  export async function onAppConnect (err, dict) {
76
66
  const appIdKey = dict.WIRApplicationIdentifierKey;
77
67
  this.log.debug(`Notified that new application '${appIdKey}' has connected`);
78
- await useAppDictLock.bind(this)((/** @type {() => void} */ done) => {
79
- try {
80
- updateAppsWithDict.bind(this)(dict);
81
- } finally {
82
- done();
83
- }
84
- });
68
+ updateAppsWithDict.bind(this)(dict);
85
69
  }
86
70
 
87
71
  /**
88
72
  * @this {import('../remote-debugger').RemoteDebugger}
89
73
  * @param {Error?} err
90
- * @param {Record<string, any>} dict
74
+ * @param {import('@appium/types').StringRecord} dict
91
75
  * @returns {void}
92
76
  */
93
77
  export function onAppDisconnect (err, dict) {
94
78
  const appIdKey = dict.WIRApplicationIdentifierKey;
95
79
  this.log.debug(`Application '${appIdKey}' disconnected. Removing from app dictionary.`);
96
- this.log.debug(`Current app is '${this.appIdKey}'`);
80
+ this.log.debug(`Current app is '${this.appIdKey}'`);
97
81
 
98
82
  // get rid of the entry in our app dictionary,
99
83
  // since it is no longer available
@@ -119,14 +103,10 @@ export function onAppDisconnect (err, dict) {
119
103
  * @param {Record<string, any>} dict
120
104
  * @returns {Promise<void>}
121
105
  */
106
+ // eslint-disable-next-line require-await
122
107
  export async function onAppUpdate (err, dict) {
123
- await useAppDictLock.bind(this)((/** @type {() => void} */ done) => {
124
- try {
125
- updateAppsWithDict.bind(this)(dict);
126
- } finally {
127
- done();
128
- }
129
- });
108
+ this.log.debug(`Notified that an application has been updated`);
109
+ updateAppsWithDict.bind(this)(dict);
130
110
  }
131
111
 
132
112
  /**
@@ -159,6 +139,7 @@ export function onCurrentState (err, state) {
159
139
  * @param {Record<string, any>} apps
160
140
  * @returns {Promise<void>}
161
141
  */
142
+ // eslint-disable-next-line require-await
162
143
  export async function onConnectedApplicationList (err, apps) {
163
144
  this.log.debug(`Received connected applications list: ${_.keys(apps).join(', ')}`);
164
145
 
@@ -173,25 +154,9 @@ export async function onConnectedApplicationList (err, apps) {
173
154
  newDict[id] = entry;
174
155
  }
175
156
  // update the object's list of apps
176
- await useAppDictLock.bind(this)((/** @type {() => void} */ done) => {
177
- try {
178
- _.defaults(this.appDict, newDict);
179
- } finally {
180
- done();
181
- }
182
- });
157
+ _.defaults(this.appDict, newDict);
183
158
  }
184
159
 
185
- /**
186
- * @this {import('../remote-debugger').RemoteDebugger}
187
- * @param {(done: () => any) => any} fn
188
- * @returns {Promise<any>}
189
- */
190
- async function useAppDictLock (fn) {
191
- return await this._lock.acquire('appDict', fn);
192
- }
193
-
194
-
195
160
  /**
196
161
  *
197
162
  * @this {import('../remote-debugger').RemoteDebugger}
@@ -201,19 +166,14 @@ async function useAppDictLock (fn) {
201
166
  function updateAppsWithDict (dict) {
202
167
  // get the dictionary entry into a nice form, and add it to the
203
168
  // application dictionary
204
- this.appDict = this.appDict || {};
205
- let [id, entry] = appInfoFromDict(dict);
169
+ this.appDict ??= {};
170
+ const [id, entry] = appInfoFromDict(dict);
206
171
  if (this.appDict[id]) {
207
172
  // preserve the page dictionary for this entry
208
173
  entry.pageArray = this.appDict[id].pageArray;
209
174
  }
210
175
  this.appDict[id] = entry;
211
176
 
212
- // add a promise to get the page dictionary
213
- if (_.isUndefined(entry.pageArray)) {
214
- entry.pageArray = deferredPromise();
215
- }
216
-
217
177
  // try to get the app id from our connected apps
218
178
  if (!this.appIdKey) {
219
179
  this.appIdKey = getDebuggerAppKey(/** @type {string} */ (this.bundleId), this.appDict);
@@ -29,15 +29,11 @@ export default class RemoteDebuggerRealDevice extends RemoteDebugger {
29
29
  bundleId: this.bundleId,
30
30
  platformVersion: this.platformVersion,
31
31
  isSafari: this.isSafari,
32
- host: this.host,
33
- port: this.port,
34
- socketPath: this.socketPath,
35
- messageProxy: this.remoteDebugProxy,
36
32
  logAllCommunication: this.logAllCommunication,
37
33
  logAllCommunicationHexDump: this.logAllCommunicationHexDump,
38
34
  socketChunkSize: this.socketChunkSize,
39
35
  webInspectorMaxFrameLength: this.webInspectorMaxFrameLength,
40
- udid: this.udid
36
+ udid: this.udid,
41
37
  });
42
38
  }
43
39
  }
@@ -11,7 +11,7 @@ import * as screenshotMixins from './mixins/screenshot';
11
11
  import * as eventMixins from './mixins/events';
12
12
  import * as miscellaneousMixins from './mixins/misc';
13
13
  import _ from 'lodash';
14
- import AsyncLock from 'async-lock';
14
+
15
15
 
16
16
  export const REMOTE_DEBUGGER_PORT = 27753;
17
17
  /* How many milliseconds to wait for webkit to return a response before timing out */
@@ -160,8 +160,6 @@ export class RemoteDebugger extends EventEmitter {
160
160
  this.fullPageInitialization = fullPageInitialization;
161
161
 
162
162
  this.pageLoadStrategy = pageLoadStrategy;
163
-
164
- this._lock = new AsyncLock();
165
163
  }
166
164
 
167
165
  /**
@@ -24,7 +24,7 @@ const COMMANDS = {
24
24
  'Timeline.stop': FULL_COMMAND,
25
25
  };
26
26
 
27
- class RemoteMessages {
27
+ export class RemoteMessages {
28
28
  constructor (isTargetBased = false) {
29
29
  this.isTargetBased = isTargetBased;
30
30
  }
@@ -249,5 +249,4 @@ class RemoteMessages {
249
249
  }
250
250
  }
251
251
 
252
- export { RemoteMessages };
253
252
  export default RemoteMessages;
@@ -3,13 +3,19 @@ import RpcClient from './rpc-client';
3
3
  import { services } from 'appium-ios-device';
4
4
 
5
5
 
6
- export default class RpcClientRealDevice extends RpcClient {
6
+ export class RpcClientRealDevice extends RpcClient {
7
+ /**
8
+ * @param {import('./rpc-client').RpcClientOptions} [opts={}]
9
+ */
7
10
  constructor (opts = {}) {
8
11
  super(Object.assign({
9
12
  shouldCheckForTarget: false,
10
13
  }, opts));
11
14
  }
12
15
 
16
+ /**
17
+ * @override
18
+ */
13
19
  async connect () {
14
20
  this.service = await services.startWebInspectorService(this.udid, {
15
21
  osVersion: this.platformVersion,
@@ -24,6 +30,9 @@ export default class RpcClientRealDevice extends RpcClient {
24
30
  this.isConnected = true;
25
31
  }
26
32
 
33
+ /**
34
+ * @override
35
+ */
27
36
  async disconnect () {
28
37
  if (!this.isConnected) {
29
38
  return;
@@ -35,10 +44,16 @@ export default class RpcClientRealDevice extends RpcClient {
35
44
  this.isConnected = false;
36
45
  }
37
46
 
47
+ /**
48
+ * @override
49
+ */
38
50
  async sendMessage (cmd) { // eslint-disable-line require-await
39
51
  this.service.sendMessage(cmd);
40
52
  }
41
53
 
54
+ /**
55
+ * @override
56
+ */
42
57
  async receive (data) {
43
58
  if (!this.isConnected) {
44
59
  return;
@@ -47,3 +62,5 @@ export default class RpcClientRealDevice extends RpcClient {
47
62
  await this.messageHandler.handleMessage(data);
48
63
  }
49
64
  }
65
+
66
+ export default RpcClientRealDevice;
@@ -5,8 +5,25 @@ import net from 'net';
5
5
  import RpcClient from './rpc-client';
6
6
  import { services } from 'appium-ios-device';
7
7
 
8
+ export class RpcClientSimulator extends RpcClient {
9
+ /** @type {string|undefined} */
10
+ host;
8
11
 
9
- export default class RpcClientSimulator extends RpcClient {
12
+ /** @type {number|undefined} */
13
+ port;
14
+
15
+ /** @type {any} */
16
+ messageProxy;
17
+
18
+ /** @type {import('node:net').Socket|null} */
19
+ socket;
20
+
21
+ /** @type {string|undefined} */
22
+ socketPath;
23
+
24
+ /**
25
+ * @param {import('./rpc-client').RpcClientOptions & RpcClientSimulatorOptions} [opts={}]
26
+ */
10
27
  constructor (opts = {}) {
11
28
  super(Object.assign({
12
29
  shouldCheckForTarget: false,
@@ -28,6 +45,9 @@ export default class RpcClientSimulator extends RpcClient {
28
45
  this.socketPath = socketPath;
29
46
  }
30
47
 
48
+ /**
49
+ * @override
50
+ */
31
51
  async connect () {
32
52
  // create socket and handle its messages
33
53
  if (this.socketPath) {
@@ -59,7 +79,7 @@ export default class RpcClientSimulator extends RpcClient {
59
79
  // tcp socket
60
80
  log.debug(`Connecting to remote debugger ${this.messageProxy ? 'via proxy ' : ''}through TCP: ${this.host}:${this.port}`);
61
81
  this.socket = new net.Socket();
62
- this.socket.connect(this.port, this.host);
82
+ this.socket.connect(/** @type {number} */ (this.port), /** @type {String} */ (this.host));
63
83
  }
64
84
 
65
85
  this.socket.setNoDelay(true);
@@ -107,6 +127,9 @@ export default class RpcClientSimulator extends RpcClient {
107
127
  });
108
128
  }
109
129
 
130
+ /**
131
+ * @override
132
+ */
110
133
  async disconnect () {
111
134
  if (!this.isConnected) {
112
135
  return;
@@ -118,6 +141,9 @@ export default class RpcClientSimulator extends RpcClient {
118
141
  this.isConnected = false;
119
142
  }
120
143
 
144
+ /**
145
+ * @override
146
+ */
121
147
  async sendMessage (cmd) {
122
148
  let onSocketError;
123
149
 
@@ -148,6 +174,9 @@ export default class RpcClientSimulator extends RpcClient {
148
174
  });
149
175
  }
150
176
 
177
+ /**
178
+ * @override
179
+ */
151
180
  async receive (data) {
152
181
  if (!this.isConnected) {
153
182
  return;
@@ -166,3 +195,13 @@ export default class RpcClientSimulator extends RpcClient {
166
195
  await this.messageHandler.handleMessage(data);
167
196
  }
168
197
  }
198
+
199
+ export default RpcClientSimulator;
200
+
201
+ /**
202
+ * @typedef {Object} RpcClientSimulatorOptions
203
+ * @property {string} [socketPath]
204
+ * @property {string} [host='::1']
205
+ * @property {number} [port]
206
+ * @property {any} [messageProxy]
207
+ */