appium-remote-debugger 12.0.0 → 12.0.1

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 (53) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/lib/mixins/connect.d.ts +8 -52
  3. package/build/lib/mixins/connect.d.ts.map +1 -1
  4. package/build/lib/mixins/connect.js +31 -41
  5. package/build/lib/mixins/connect.js.map +1 -1
  6. package/build/lib/mixins/cookies.d.ts +4 -8
  7. package/build/lib/mixins/cookies.d.ts.map +1 -1
  8. package/build/lib/mixins/cookies.js +9 -13
  9. package/build/lib/mixins/cookies.js.map +1 -1
  10. package/build/lib/mixins/events.d.ts +10 -16
  11. package/build/lib/mixins/events.d.ts.map +1 -1
  12. package/build/lib/mixins/events.js +7 -10
  13. package/build/lib/mixins/events.js.map +1 -1
  14. package/build/lib/mixins/execute.d.ts +5 -16
  15. package/build/lib/mixins/execute.d.ts.map +1 -1
  16. package/build/lib/mixins/execute.js +17 -21
  17. package/build/lib/mixins/execute.js.map +1 -1
  18. package/build/lib/mixins/message-handlers.d.ts +9 -49
  19. package/build/lib/mixins/message-handlers.d.ts.map +1 -1
  20. package/build/lib/mixins/message-handlers.js +24 -35
  21. package/build/lib/mixins/message-handlers.js.map +1 -1
  22. package/build/lib/mixins/misc.d.ts +6 -10
  23. package/build/lib/mixins/misc.d.ts.map +1 -1
  24. package/build/lib/mixins/misc.js +15 -16
  25. package/build/lib/mixins/misc.js.map +1 -1
  26. package/build/lib/mixins/navigate.d.ts +9 -47
  27. package/build/lib/mixins/navigate.d.ts.map +1 -1
  28. package/build/lib/mixins/navigate.js +38 -44
  29. package/build/lib/mixins/navigate.js.map +1 -1
  30. package/build/lib/mixins/property-accessors.d.ts +27 -0
  31. package/build/lib/mixins/property-accessors.d.ts.map +1 -0
  32. package/build/lib/mixins/property-accessors.js +95 -0
  33. package/build/lib/mixins/property-accessors.js.map +1 -0
  34. package/build/lib/mixins/screenshot.d.ts +2 -10
  35. package/build/lib/mixins/screenshot.d.ts.map +1 -1
  36. package/build/lib/mixins/screenshot.js +4 -9
  37. package/build/lib/mixins/screenshot.js.map +1 -1
  38. package/build/lib/remote-debugger.d.ts +5 -2
  39. package/build/lib/remote-debugger.d.ts.map +1 -1
  40. package/build/lib/remote-debugger.js +14 -1
  41. package/build/lib/remote-debugger.js.map +1 -1
  42. package/build/tsconfig.tsbuildinfo +1 -1
  43. package/lib/mixins/connect.js +43 -43
  44. package/lib/mixins/cookies.js +12 -14
  45. package/lib/mixins/events.js +10 -11
  46. package/lib/mixins/execute.js +28 -24
  47. package/lib/mixins/message-handlers.js +33 -37
  48. package/lib/mixins/misc.js +18 -17
  49. package/lib/mixins/navigate.js +46 -45
  50. package/lib/mixins/property-accessors.ts +96 -0
  51. package/lib/mixins/screenshot.js +8 -10
  52. package/lib/remote-debugger.ts +20 -3
  53. package/package.json +1 -1
@@ -7,6 +7,17 @@ import events from './events';
7
7
  import { timing, util } from '@appium/support';
8
8
  import { retryInterval, waitForCondition } from 'asyncbox';
9
9
  import _ from 'lodash';
10
+ import {
11
+ setAppIdKey,
12
+ getAppDict,
13
+ getAppIdKey,
14
+ setPageIdKey,
15
+ getRcpClient,
16
+ getIsSafari,
17
+ getIncludeSafari,
18
+ getBundleId,
19
+ getAdditionalBundleIds,
20
+ } from './property-accessors';
10
21
 
11
22
  const APP_CONNECT_TIMEOUT_MS = 0;
12
23
  const APP_CONNECT_INTERVAL_MS = 100;
@@ -36,7 +47,7 @@ export async function setConnectionKey () {
36
47
  *
37
48
  * @this {RemoteDebugger}
38
49
  * @param {number} [timeout=APP_CONNECT_TIMEOUT_MS]
39
- * @returns {Promise<import('@appium/types').StringRecord>}
50
+ * @returns {Promise<import('../types').AppDict>}
40
51
  */
41
52
  export async function connect (timeout = APP_CONNECT_TIMEOUT_MS) {
42
53
  this.setup();
@@ -66,19 +77,19 @@ export async function connect (timeout = APP_CONNECT_TIMEOUT_MS) {
66
77
  const timer = new timing.Timer().start();
67
78
  this.log.debug(`Waiting up to ${timeout}ms for applications to be reported`);
68
79
  try {
69
- await waitForCondition(() => !_.isEmpty(this._appDict), {
80
+ await waitForCondition(() => !_.isEmpty(getAppDict(this)), {
70
81
  waitMs: timeout,
71
82
  intervalMs: APP_CONNECT_INTERVAL_MS,
72
83
  });
73
84
  this.log.debug(
74
- `Retrieved ${util.pluralize('application', _.size(this._appDict), true)} ` +
85
+ `Retrieved ${util.pluralize('application', _.size(getAppDict(this)), true)} ` +
75
86
  `within ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`
76
87
  );
77
88
  } catch (err) {
78
89
  this.log.debug(`Timed out waiting for applications to be reported`);
79
90
  }
80
91
  }
81
- return this._appDict || {};
92
+ return _.cloneDeep(getAppDict(this));
82
93
  } catch (err) {
83
94
  this.log.error(`Error setting connection key: ${err.message}`);
84
95
  await this.disconnect();
@@ -92,9 +103,7 @@ export async function connect (timeout = APP_CONNECT_TIMEOUT_MS) {
92
103
  * @returns {Promise<void>}
93
104
  */
94
105
  export async function disconnect () {
95
- if (this._rpcClient) {
96
- await this._rpcClient.disconnect();
97
- }
106
+ await getRcpClient(this)?.disconnect();
98
107
  this.emit(events.EVENT_DISCONNECT, true);
99
108
  this.teardown();
100
109
  }
@@ -115,23 +124,23 @@ export async function selectApp (currentUrl = null, maxTries = SELECT_APP_RETRIE
115
124
  rpcClient.shouldCheckForTarget = false;
116
125
  try {
117
126
  const timer = new timing.Timer().start();
118
- if (!this._appDict || _.isEmpty(this._appDict)) {
127
+ if (_.isEmpty(getAppDict(this))) {
119
128
  this.log.debug('No applications currently connected.');
120
129
  return [];
121
130
  }
122
131
 
123
132
  const { appIdKey } = await searchForApp.bind(this)(currentUrl, maxTries, ignoreAboutBlankUrl);
124
- if (this._appIdKey !== appIdKey) {
125
- this.log.debug(`Received altered app id, updating from '${this._appIdKey}' to '${appIdKey}'`);
126
- this._appIdKey = appIdKey;
133
+ if (getAppIdKey(this) !== appIdKey) {
134
+ this.log.debug(`Received altered app id, updating from '${getAppIdKey(this)}' to '${appIdKey}'`);
135
+ setAppIdKey(this, appIdKey);
127
136
  }
128
137
  logApplicationDictionary.bind(this)();
129
138
  // translate the dictionary into a useful form, and return to sender
130
- this.log.debug(`Finally selecting app ${this._appIdKey}`);
139
+ this.log.debug(`Finally selecting app ${getAppIdKey(this)}`);
131
140
 
132
141
  /** @type {import('../types').Page[]} */
133
142
  const fullPageArray = [];
134
- for (const [app, info] of _.toPairs(this._appDict)) {
143
+ for (const [app, info] of _.toPairs(getAppDict(this))) {
135
144
  if (!_.isArray(info.pageArray) || !info.isActive) {
136
145
  continue;
137
146
  }
@@ -162,14 +171,15 @@ export async function selectApp (currentUrl = null, maxTries = SELECT_APP_RETRIE
162
171
  * @returns {Promise<void>}
163
172
  */
164
173
  export async function selectPage (appIdKey, pageIdKey, skipReadyCheck = false) {
165
- this._appIdKey = _.startsWith(`${appIdKey}`, 'PID:') ? `${appIdKey}` : `PID:${appIdKey}`;
166
- this._pageIdKey = pageIdKey;
174
+ const fullAppIdKey = _.startsWith(`${appIdKey}`, 'PID:') ? `${appIdKey}` : `PID:${appIdKey}`;
175
+ setAppIdKey(this, fullAppIdKey);
176
+ setPageIdKey(this, pageIdKey);
167
177
 
168
- this.log.debug(`Selecting page '${pageIdKey}' on app '${this._appIdKey}' and forwarding socket setup`);
178
+ this.log.debug(`Selecting page '${pageIdKey}' on app '${fullAppIdKey}' and forwarding socket setup`);
169
179
 
170
180
  const timer = new timing.Timer().start();
171
181
 
172
- await this.requireRpcClient().selectPage(this._appIdKey, pageIdKey);
182
+ await this.requireRpcClient().selectPage(fullAppIdKey, pageIdKey);
173
183
 
174
184
  if (!skipReadyCheck && !await this.checkPageIsReady()) {
175
185
  await this.waitForDom();
@@ -178,7 +188,6 @@ export async function selectPage (appIdKey, pageIdKey, skipReadyCheck = false) {
178
188
  this.log.debug(`Selected page after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
179
189
  }
180
190
 
181
-
182
191
  /**
183
192
  *
184
193
  * @this {RemoteDebugger}
@@ -188,9 +197,14 @@ export async function selectPage (appIdKey, pageIdKey, skipReadyCheck = false) {
188
197
  * @returns {Promise<import('../types').AppPage>}
189
198
  */
190
199
  async function searchForApp (currentUrl, maxTries, ignoreAboutBlankUrl) {
191
- const bundleIds = this._includeSafari && !this._isSafari
192
- ? [this._bundleId, ...this._additionalBundleIds, SAFARI_BUNDLE_ID]
193
- : [this._bundleId, ...this._additionalBundleIds];
200
+ /** @type {string[]} */
201
+ const bundleIds = _.compact(
202
+ [
203
+ getBundleId(this),
204
+ ...(getAdditionalBundleIds(this) ?? []),
205
+ ...(getIncludeSafari(this) && !getIsSafari(this) ? [SAFARI_BUNDLE_ID] : []),
206
+ ]
207
+ );
194
208
  let retryCount = 0;
195
209
  return /** @type {import('../types').AppPage} */ (await retryInterval(maxTries, SELECT_APP_RETRY_SLEEP_MS, async () => {
196
210
  logApplicationDictionary.bind(this)();
@@ -198,7 +212,7 @@ async function searchForApp (currentUrl, maxTries, ignoreAboutBlankUrl) {
198
212
  this.log.debug(`Trying out the possible app ids: ${possibleAppIds.join(', ')} (try #${retryCount + 1} of ${maxTries})`);
199
213
  for (const attemptedAppIdKey of possibleAppIds) {
200
214
  try {
201
- if (!this._appDict[attemptedAppIdKey].isActive) {
215
+ if (!getAppDict(this)[attemptedAppIdKey].isActive) {
202
216
  this.log.debug(`Skipping app '${attemptedAppIdKey}' because it is not active`);
203
217
  continue;
204
218
  }
@@ -216,12 +230,12 @@ async function searchForApp (currentUrl, maxTries, ignoreAboutBlankUrl) {
216
230
  }
217
231
 
218
232
  // save the page array for this app
219
- this._appDict[appIdKey].pageArray = pageArrayFromDict(pageDict);
233
+ getAppDict(this)[appIdKey].pageArray = pageArrayFromDict(pageDict);
220
234
 
221
235
  // if we are looking for a particular url, make sure we
222
236
  // have the right page. Ignore empty or undefined urls.
223
237
  // Ignore about:blank if requested.
224
- const result = searchForPage.bind(this)(this._appDict, currentUrl, ignoreAboutBlankUrl);
238
+ const result = searchForPage.bind(this)(getAppDict(this), currentUrl, ignoreAboutBlankUrl);
225
239
  if (result) {
226
240
  return result;
227
241
  }
@@ -276,7 +290,7 @@ function searchForPage (appsDict, currentUrl = null, ignoreAboutBlankUrl = false
276
290
  */
277
291
  function logApplicationDictionary () {
278
292
  this.log.debug('Current applications available:');
279
- for (const [app, info] of _.toPairs(this._appDict)) {
293
+ for (const [app, info] of _.toPairs(getAppDict(this))) {
280
294
  this.log.debug(` Application: "${app}"`);
281
295
  for (const [key, value] of _.toPairs(info)) {
282
296
  if (key === 'pageArray' && Array.isArray(value) && value.length) {
@@ -307,7 +321,7 @@ function logApplicationDictionary () {
307
321
  export function getPossibleDebuggerAppKeys(bundleIds) {
308
322
  if (bundleIds.includes(WILDCARD_BUNDLE_ID)) {
309
323
  this.log.debug('Skip checking bundle identifiers because the bundleIds includes a wildcard');
310
- return _.uniq(Object.keys(this._appDict));
324
+ return _.uniq(Object.keys(getAppDict(this)));
311
325
  }
312
326
 
313
327
  // go through the possible bundle identifiers
@@ -324,10 +338,10 @@ export function getPossibleDebuggerAppKeys(bundleIds) {
324
338
  const proxiedAppIds = new Set();
325
339
  for (const bundleId of possibleBundleIds) {
326
340
  // now we need to determine if we should pick a proxy for this instead
327
- for (const appId of appIdsForBundle(bundleId, this._appDict)) {
341
+ for (const appId of appIdsForBundle(bundleId, getAppDict(this))) {
328
342
  proxiedAppIds.add(appId);
329
343
  this.log.debug(`Found app id key '${appId}' for bundle '${bundleId}'`);
330
- for (const [key, data] of _.toPairs(this._appDict)) {
344
+ for (const [key, data] of _.toPairs(getAppDict(this))) {
331
345
  if (data.isProxy && data.hostId === appId) {
332
346
  this.log.debug(
333
347
  `Found separate bundleId '${data.bundleId}' ` +
@@ -343,19 +357,5 @@ export function getPossibleDebuggerAppKeys(bundleIds) {
343
357
  }
344
358
 
345
359
  /**
346
- * @typedef {Object} HasConnectionRelatedProperties
347
- * @property {string | null | undefined} _appIdKey
348
- * @property {string | number | null | undefined} _pageIdKey
349
- * @property {import('../types').AppDict} _appDict
350
- * @property {string | undefined} _bundleId
351
- * @property {import('../rpc/rpc-client').RpcClient | undefined} _rpcClient
352
- * @property {boolean} _includeSafari
353
- * @property {boolean} _isSafari
354
- * @property {string[]} _additionalBundleIds
355
- * @property {(this: RemoteDebugger, timeoutMs?: number | undefined) => Promise<boolean>} checkPageIsReady:
356
- * @property {(this: RemoteDebugger, startPageLoadTimer?: timing.Timer | null | undefined) => Promise<void>} waitForDom:
357
- */
358
-
359
- /**
360
- * @typedef {import('../remote-debugger').RemoteDebugger & HasConnectionRelatedProperties} RemoteDebugger
360
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
361
361
  */
@@ -1,3 +1,7 @@
1
+ import {
2
+ getAppIdKey,
3
+ getPageIdKey,
4
+ } from './property-accessors';
1
5
 
2
6
  /**
3
7
  *
@@ -7,8 +11,8 @@
7
11
  export async function getCookies () {
8
12
  this.log.debug('Getting cookies');
9
13
  return await this.requireRpcClient().send('Page.getCookies', {
10
- appIdKey: this._appIdKey,
11
- pageIdKey: this._pageIdKey
14
+ appIdKey: getAppIdKey(this),
15
+ pageIdKey: getPageIdKey(this),
12
16
  });
13
17
  }
14
18
 
@@ -21,9 +25,9 @@ export async function getCookies () {
21
25
  export async function setCookie (cookie) {
22
26
  this.log.debug('Setting cookie');
23
27
  return await this.requireRpcClient().send('Page.setCookie', {
24
- appIdKey: this._appIdKey,
25
- pageIdKey: this._pageIdKey,
26
- cookie
28
+ appIdKey: getAppIdKey(this),
29
+ pageIdKey: getPageIdKey(this),
30
+ cookie,
27
31
  });
28
32
  }
29
33
 
@@ -37,19 +41,13 @@ export async function setCookie (cookie) {
37
41
  export async function deleteCookie (cookieName, url) {
38
42
  this.log.debug(`Deleting cookie '${cookieName}' on '${url}'`);
39
43
  return await this.requireRpcClient().send('Page.deleteCookie', {
40
- appIdKey: this._appIdKey,
41
- pageIdKey: this._pageIdKey,
44
+ appIdKey: getAppIdKey(this),
45
+ pageIdKey: getPageIdKey(this),
42
46
  cookieName,
43
47
  url,
44
48
  });
45
49
  }
46
50
 
47
51
  /**
48
- * @typedef {Object} HasCookiesRelatedProperties
49
- * @property {string | null | undefined} _appIdKey
50
- * @property {string | number | null | undefined} _pageIdKey
51
- */
52
-
53
- /**
54
- * @typedef {import('../remote-debugger').RemoteDebugger & HasCookiesRelatedProperties} RemoteDebugger
52
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
55
53
  */
@@ -1,9 +1,13 @@
1
+ import {
2
+ getClientEventListeners,
3
+ } from './property-accessors';
4
+
1
5
  // event emitted publically
2
- export const events = {
6
+ export const events = /** @type {const} */ ({
3
7
  EVENT_PAGE_CHANGE: 'remote_debugger_page_change',
4
8
  EVENT_FRAMES_DETACHED: 'remote_debugger_frames_detached',
5
9
  EVENT_DISCONNECT: 'remote_debugger_disconnect',
6
- };
10
+ });
7
11
 
8
12
  /**
9
13
  * Keep track of the client event listeners so they can be removed
@@ -14,8 +18,8 @@ export const events = {
14
18
  * @returns {void}
15
19
  */
16
20
  export function addClientEventListener (eventName, listener) {
17
- this._clientEventListeners[eventName] ??= [];
18
- this._clientEventListeners[eventName].push(listener);
21
+ getClientEventListeners(this)[eventName] ??= [];
22
+ getClientEventListeners(this)[eventName].push(listener);
19
23
  this.requireRpcClient().on(eventName, listener);
20
24
  }
21
25
 
@@ -25,7 +29,7 @@ export function addClientEventListener (eventName, listener) {
25
29
  * @returns {void}
26
30
  */
27
31
  export function removeClientEventListener (eventName) {
28
- for (const listener of (this._clientEventListeners[eventName] || [])) {
32
+ for (const listener of (getClientEventListeners(this)[eventName] || [])) {
29
33
  this.requireRpcClient().off(eventName, listener);
30
34
  }
31
35
  }
@@ -73,10 +77,5 @@ export function stopNetwork () {
73
77
  export default events;
74
78
 
75
79
  /**
76
- * @typedef {Object} HasEventsRelatedProperties
77
- * @property {import('@appium/types').StringRecord<import('../types').EventListener[]>} _clientEventListeners:
78
- */
79
-
80
- /**
81
- * @typedef {import('../remote-debugger').RemoteDebugger & HasEventsRelatedProperties} RemoteDebugger
80
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
82
81
  */
@@ -1,10 +1,20 @@
1
1
  import { errors } from '@appium/base-driver';
2
- import { checkParams, simpleStringify, convertResult, RESPONSE_LOG_LENGTH } from '../utils';
2
+ import {
3
+ checkParams,
4
+ simpleStringify,
5
+ convertResult,
6
+ RESPONSE_LOG_LENGTH,
7
+ } from '../utils';
3
8
  import { getScriptForAtom } from '../atoms';
4
9
  import { util, timing } from '@appium/support';
5
10
  import { retryInterval } from 'asyncbox';
6
11
  import _ from 'lodash';
7
-
12
+ import {
13
+ getAppIdKey,
14
+ getPageIdKey,
15
+ getPageLoading,
16
+ getGarbageCollectOnExecute,
17
+ } from './property-accessors';
8
18
 
9
19
  /* How many milliseconds to wait for webkit to return a response before timing out */
10
20
  const RPC_RESPONSE_TIMEOUT_MS = 5000;
@@ -36,8 +46,8 @@ export async function executeAtom (atom, args = [], frames = []) {
36
46
  export async function executeAtomAsync (atom, args = [], frames = []) {
37
47
  // helper to send directly to the web inspector
38
48
  const evaluate = async (method, opts) => await this.requireRpcClient(true).send(method, Object.assign({
39
- appIdKey: this._appIdKey,
40
- pageIdKey: this._pageIdKey,
49
+ appIdKey: getAppIdKey(this),
50
+ pageIdKey: getPageIdKey(this),
41
51
  returnByValue: false,
42
52
  }, opts));
43
53
 
@@ -125,19 +135,19 @@ export async function executeAtomAsync (atom, args = [], frames = []) {
125
135
  */
126
136
  export async function execute (command, override) {
127
137
  // if the page is not loaded yet, wait for it
128
- if (this._pageLoading && !override) {
138
+ if (getPageLoading(this) && !override) {
129
139
  this.log.debug('Trying to execute but page is not loaded.');
130
140
  await this.waitForDom();
131
141
  }
132
142
 
133
- if (_.isNil(this._appIdKey)) {
143
+ if (_.isNil(getAppIdKey(this))) {
134
144
  throw new Error('Missing parameter: appIdKey. Is the target web application still alive?');
135
145
  }
136
- if (_.isNil(this._pageIdKey)) {
146
+ if (_.isNil(getPageIdKey(this))) {
137
147
  throw new Error('Missing parameter: pageIdKey. Is the target web page still alive?');
138
148
  }
139
149
 
140
- if (this._garbageCollectOnExecute) {
150
+ if (getGarbageCollectOnExecute(this)) {
141
151
  await this.garbageCollect();
142
152
  }
143
153
 
@@ -145,8 +155,8 @@ export async function execute (command, override) {
145
155
  const res = await this.requireRpcClient(true).send('Runtime.evaluate', {
146
156
  expression: command,
147
157
  returnByValue: true,
148
- appIdKey: this._appIdKey,
149
- pageIdKey: this._pageIdKey,
158
+ appIdKey: getAppIdKey(this),
159
+ pageIdKey: getPageIdKey(this),
150
160
  });
151
161
  return convertResult(res);
152
162
  }
@@ -158,9 +168,12 @@ export async function execute (command, override) {
158
168
  * @param {any[]} [args]
159
169
  */
160
170
  export async function callFunction (objectId, fn, args) {
161
- checkParams({appIdKey: this._appIdKey, pageIdKey: this._pageIdKey});
171
+ checkParams({
172
+ appIdKey: getAppIdKey(this),
173
+ pageIdKey: getPageIdKey(this),
174
+ });
162
175
 
163
- if (this._garbageCollectOnExecute) {
176
+ if (getGarbageCollectOnExecute(this)) {
164
177
  await this.garbageCollect();
165
178
  }
166
179
 
@@ -170,22 +183,13 @@ export async function callFunction (objectId, fn, args) {
170
183
  functionDeclaration: fn,
171
184
  arguments: args,
172
185
  returnByValue: true,
173
- appIdKey: this._appIdKey,
174
- pageIdKey: this._pageIdKey,
186
+ appIdKey: getAppIdKey(this),
187
+ pageIdKey: getPageIdKey(this),
175
188
  });
176
189
 
177
190
  return convertResult(res);
178
191
  }
179
192
 
180
193
  /**
181
- * @typedef {Object} HasExecutionRelatedProperties
182
- * @property {string | null | undefined} _appIdKey
183
- * @property {string | number | null | undefined} _pageIdKey
184
- * @property {boolean} _pageLoading
185
- * @property {boolean} _garbageCollectOnExecute
186
- * @property {(this: RemoteDebugger, startPageLoadTimer?: timing.Timer | null | undefined) => Promise<void>} waitForDom:
187
- */
188
-
189
- /**
190
- * @typedef {import('../remote-debugger').RemoteDebugger & HasExecutionRelatedProperties} RemoteDebugger
194
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
191
195
  */
@@ -4,7 +4,16 @@ import {
4
4
  appInfoFromDict,
5
5
  } from '../utils';
6
6
  import _ from 'lodash';
7
-
7
+ import {
8
+ setAppIdKey,
9
+ getAppDict,
10
+ getAppIdKey,
11
+ getBundleId,
12
+ getNavigatingToPage,
13
+ setCurrentState,
14
+ setConnectedDrivers,
15
+ getSkippedApps,
16
+ } from './property-accessors';
8
17
 
9
18
  /*
10
19
  * Generic callbacks used throughout the lifecycle of the Remote Debugger.
@@ -26,8 +35,8 @@ export async function onPageChange (err, appIdKey, pageDict) {
26
35
 
27
36
  const currentPages = pageArrayFromDict(pageDict);
28
37
  // save the page dict for this app
29
- if (this._appDict[appIdKey]) {
30
- const previousPages = this._appDict[appIdKey].pageArray;
38
+ if (getAppDict(this)[appIdKey]) {
39
+ const previousPages = getAppDict(this)[appIdKey].pageArray;
31
40
  // we have a pre-existing pageDict
32
41
  if (previousPages && _.isEqual(previousPages, currentPages)) {
33
42
  this.log.debug(
@@ -37,13 +46,13 @@ export async function onPageChange (err, appIdKey, pageDict) {
37
46
  return;
38
47
  }
39
48
  // keep track of the page dictionary
40
- this._appDict[appIdKey].pageArray = currentPages;
49
+ getAppDict(this)[appIdKey].pageArray = currentPages;
41
50
  this.log.debug(
42
51
  `Pages changed for ${appIdKey}: ${JSON.stringify(previousPages)} -> ${JSON.stringify(currentPages)}`
43
52
  );
44
53
  }
45
54
 
46
- if (this._navigatingToPage) {
55
+ if (getNavigatingToPage(this)) {
47
56
  // in the middle of navigating, so reporting a page change will cause problems
48
57
  return;
49
58
  }
@@ -76,19 +85,19 @@ export async function onAppConnect (err, dict) {
76
85
  export function onAppDisconnect (err, dict) {
77
86
  const appIdKey = dict.WIRApplicationIdentifierKey;
78
87
  this.log.debug(`Application '${appIdKey}' disconnected. Removing from app dictionary.`);
79
- this.log.debug(`Current app is '${this._appIdKey}'`);
88
+ this.log.debug(`Current app is '${getAppIdKey(this)}'`);
80
89
 
81
90
  // get rid of the entry in our app dictionary,
82
91
  // since it is no longer available
83
- delete this._appDict[appIdKey];
92
+ delete getAppDict(this)[appIdKey];
84
93
 
85
94
  // if the disconnected app is the one we are connected to, try to find another
86
- if (this._appIdKey === appIdKey) {
95
+ if (getAppIdKey(this) === appIdKey) {
87
96
  this.log.debug(`No longer have app id. Attempting to find new one.`);
88
- this._appIdKey = getDebuggerAppKey.bind(this)(/** @type {string} */ (this._bundleId));
97
+ setAppIdKey(this, getDebuggerAppKey.bind(this)(/** @type {string} */ (getBundleId(this))));
89
98
  }
90
99
 
91
- if (!this._appDict) {
100
+ if (_.isEmpty(getAppDict(this))) {
92
101
  // this means we no longer have any apps. what the what?
93
102
  this.log.debug('Main app disconnected. Disconnecting altogether.');
94
103
  this.emit(events.EVENT_DISCONNECT, true);
@@ -114,8 +123,8 @@ export async function onAppUpdate (err, dict) {
114
123
  * @returns {void}
115
124
  */
116
125
  export function onConnectedDriverList (err, drivers) {
117
- this._connectedDrivers = drivers.WIRDriverDictionaryKey;
118
- this.log.debug(`Received connected driver list: ${JSON.stringify(this._connectedDrivers)}`);
126
+ setConnectedDrivers(this, drivers.WIRDriverDictionaryKey);
127
+ this.log.debug(`Received connected driver list: ${JSON.stringify(this.connectedDrivers)}`);
119
128
  }
120
129
 
121
130
  /**
@@ -125,10 +134,10 @@ export function onConnectedDriverList (err, drivers) {
125
134
  * @returns {void}
126
135
  */
127
136
  export function onCurrentState (err, state) {
128
- this._currentState = state.WIRAutomationAvailabilityKey;
137
+ setCurrentState(this, state.WIRAutomationAvailabilityKey);
129
138
  // This state changes when 'Remote Automation' in 'Settings app' > 'Safari' > 'Advanced' > 'Remote Automation' changes
130
139
  // WIRAutomationAvailabilityAvailable or WIRAutomationAvailabilityNotAvailable
131
- this.log.debug(`Received connected automation availability state: ${JSON.stringify(this._currentState)}`);
140
+ this.log.debug(`Received connected automation availability state: ${JSON.stringify(this.currentState)}`);
132
141
  }
133
142
 
134
143
  /**
@@ -146,13 +155,13 @@ export async function onConnectedApplicationList (err, apps) {
146
155
  let newDict = {};
147
156
  for (const dict of _.values(apps)) {
148
157
  const [id, entry] = appInfoFromDict(dict);
149
- if (this._skippedApps.includes(entry.name)) {
158
+ if (getSkippedApps(this).includes(entry.name)) {
150
159
  continue;
151
160
  }
152
161
  newDict[id] = entry;
153
162
  }
154
163
  // update the object's list of apps
155
- _.defaults(this._appDict, newDict);
164
+ _.defaults(getAppDict(this), newDict);
156
165
  }
157
166
 
158
167
  /**
@@ -164,17 +173,16 @@ export async function onConnectedApplicationList (err, apps) {
164
173
  function updateAppsWithDict (dict) {
165
174
  // get the dictionary entry into a nice form, and add it to the
166
175
  // application dictionary
167
- this._appDict ??= {};
168
176
  const [id, entry] = appInfoFromDict(dict);
169
- if (this._appDict[id]) {
177
+ if (getAppDict(this)[id]) {
170
178
  // preserve the page dictionary for this entry
171
- entry.pageArray = this._appDict[id].pageArray;
179
+ entry.pageArray = getAppDict(this)[id].pageArray;
172
180
  }
173
- this._appDict[id] = entry;
181
+ getAppDict(this)[id] = entry;
174
182
 
175
183
  // try to get the app id from our connected apps
176
- if (!this._appIdKey) {
177
- this._appIdKey = getDebuggerAppKey.bind(this)(/** @type {string} */ (this._bundleId));
184
+ if (!getAppIdKey(this)) {
185
+ setAppIdKey(this, getDebuggerAppKey.bind(this)(/** @type {string} */ (getBundleId(this))));
178
186
  }
179
187
  }
180
188
 
@@ -188,7 +196,7 @@ function updateAppsWithDict (dict) {
188
196
  */
189
197
  export function getDebuggerAppKey (bundleId) {
190
198
  let appId;
191
- for (const [key, data] of _.toPairs(this._appDict)) {
199
+ for (const [key, data] of _.toPairs(getAppDict(this))) {
192
200
  if (data.bundleId === bundleId) {
193
201
  appId = key;
194
202
  break;
@@ -198,7 +206,7 @@ export function getDebuggerAppKey (bundleId) {
198
206
  if (appId) {
199
207
  this.log.debug(`Found app id key '${appId}' for bundle '${bundleId}'`);
200
208
  let proxyAppId;
201
- for (const [key, data] of _.toPairs(this._appDict)) {
209
+ for (const [key, data] of _.toPairs(getAppDict(this))) {
202
210
  if (data.isProxy && data.hostId === appId) {
203
211
  this.log.debug(`Found separate bundleId '${data.bundleId}' ` +
204
212
  `acting as proxy for '${bundleId}', with app id '${key}'`);
@@ -216,17 +224,5 @@ export function getDebuggerAppKey (bundleId) {
216
224
  }
217
225
 
218
226
  /**
219
- * @typedef {Object} HasMessageHandlersRelatedProperties
220
- * @property {string | null | undefined} _appIdKey
221
- * @property {string | number | null | undefined} _pageIdKey
222
- * @property {import('../types').AppDict} _appDict
223
- * @property {boolean} _navigatingToPage
224
- * @property {string | undefined} _currentState
225
- * @property {string | undefined} _bundleId
226
- * @property {string[] | undefined} _connectedDrivers
227
- * @property {string[]} _skippedApps
228
- */
229
-
230
- /**
231
- * @typedef {import('../remote-debugger').RemoteDebugger & HasMessageHandlersRelatedProperties} RemoteDebugger
227
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
232
228
  */
@@ -1,5 +1,9 @@
1
1
  import { checkParams } from '../utils';
2
2
  import B from 'bluebird';
3
+ import {
4
+ getAppIdKey,
5
+ getPageIdKey,
6
+ } from './property-accessors';
3
7
 
4
8
  const SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
5
9
  const GARBAGE_COLLECT_TIMEOUT_MS = 5000;
@@ -23,8 +27,8 @@ export async function startTimeline (fn) {
23
27
  this.log.debug('Starting to record the timeline');
24
28
  this.requireRpcClient().on('Timeline.eventRecorded', fn);
25
29
  return await this.requireRpcClient().send('Timeline.start', {
26
- appIdKey: this._appIdKey,
27
- pageIdKey: this._pageIdKey,
30
+ appIdKey: getAppIdKey(this),
31
+ pageIdKey: getPageIdKey(this),
28
32
  });
29
33
  }
30
34
 
@@ -35,8 +39,8 @@ export async function startTimeline (fn) {
35
39
  export async function stopTimeline () {
36
40
  this.log.debug('Stopping to record the timeline');
37
41
  await this.requireRpcClient().send('Timeline.stop', {
38
- appIdKey: this._appIdKey,
39
- pageIdKey: this._pageIdKey,
42
+ appIdKey: getAppIdKey(this),
43
+ pageIdKey: getPageIdKey(this),
40
44
  });
41
45
  }
42
46
 
@@ -49,9 +53,9 @@ export async function stopTimeline () {
49
53
  export async function overrideUserAgent (value) {
50
54
  this.log.debug('Setting overrideUserAgent');
51
55
  return await this.requireRpcClient().send('Page.overrideUserAgent', {
52
- appIdKey: this._appIdKey,
53
- pageIdKey: this._pageIdKey,
54
- value
56
+ appIdKey: getAppIdKey(this),
57
+ pageIdKey: getPageIdKey(this),
58
+ value,
55
59
  });
56
60
  }
57
61
 
@@ -64,7 +68,10 @@ export async function garbageCollect (timeoutMs = GARBAGE_COLLECT_TIMEOUT_MS) {
64
68
  this.log.debug(`Garbage collecting with ${timeoutMs}ms timeout`);
65
69
 
66
70
  try {
67
- checkParams({appIdKey: this._appIdKey, pageIdKey: this._pageIdKey});
71
+ checkParams({
72
+ appIdKey: getAppIdKey(this),
73
+ pageIdKey: getPageIdKey(this),
74
+ });
68
75
  } catch (err) {
69
76
  this.log.debug(`Unable to collect garbage at this time`);
70
77
  return;
@@ -73,8 +80,8 @@ export async function garbageCollect (timeoutMs = GARBAGE_COLLECT_TIMEOUT_MS) {
73
80
  try {
74
81
  await B.resolve(this.requireRpcClient().send(
75
82
  'Heap.gc', {
76
- appIdKey: this._appIdKey,
77
- pageIdKey: this._pageIdKey,
83
+ appIdKey: getAppIdKey(this),
84
+ pageIdKey: getPageIdKey(this),
78
85
  })
79
86
  ).timeout(timeoutMs);
80
87
  this.log.debug(`Garbage collection successful`);
@@ -88,11 +95,5 @@ export async function garbageCollect (timeoutMs = GARBAGE_COLLECT_TIMEOUT_MS) {
88
95
  }
89
96
 
90
97
  /**
91
- * @typedef {Object} HasMiscRelatedProperties
92
- * @property {string | null | undefined} _appIdKey
93
- * @property {string | number | null | undefined} _pageIdKey
94
- */
95
-
96
- /**
97
- * @typedef {import('../remote-debugger').RemoteDebugger & HasMiscRelatedProperties} RemoteDebugger
98
+ * @typedef {import('../remote-debugger').RemoteDebugger} RemoteDebugger
98
99
  */