appium-xcuitest-driver 7.13.0 → 7.15.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/lib/app-infos-cache.d.ts +46 -0
  3. package/build/lib/app-infos-cache.d.ts.map +1 -0
  4. package/build/lib/app-infos-cache.js +156 -0
  5. package/build/lib/app-infos-cache.js.map +1 -0
  6. package/build/lib/app-utils.d.ts +60 -51
  7. package/build/lib/app-utils.d.ts.map +1 -1
  8. package/build/lib/app-utils.js +496 -182
  9. package/build/lib/app-utils.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +5 -4
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +14 -7
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/app-strings.d.ts +5 -2
  15. package/build/lib/commands/app-strings.d.ts.map +1 -1
  16. package/build/lib/commands/app-strings.js +6 -3
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/file-movement.js +1 -1
  19. package/build/lib/commands/file-movement.js.map +1 -1
  20. package/build/lib/commands/types.d.ts +1 -0
  21. package/build/lib/commands/types.d.ts.map +1 -1
  22. package/build/lib/commands/xctest-record-screen.d.ts +1 -1
  23. package/build/lib/desired-caps.d.ts +2 -0
  24. package/build/lib/desired-caps.d.ts.map +1 -1
  25. package/build/lib/desired-caps.js +1 -0
  26. package/build/lib/desired-caps.js.map +1 -1
  27. package/build/lib/driver.d.ts +35 -40
  28. package/build/lib/driver.d.ts.map +1 -1
  29. package/build/lib/driver.js +15 -99
  30. package/build/lib/driver.js.map +1 -1
  31. package/build/lib/execute-method-map.d.ts +1 -1
  32. package/build/lib/execute-method-map.js +1 -1
  33. package/build/lib/execute-method-map.js.map +1 -1
  34. package/build/lib/ios-fs-helpers.d.ts +30 -15
  35. package/build/lib/ios-fs-helpers.d.ts.map +1 -1
  36. package/build/lib/ios-fs-helpers.js +54 -21
  37. package/build/lib/ios-fs-helpers.js.map +1 -1
  38. package/build/lib/real-device-management.d.ts +0 -5
  39. package/build/lib/real-device-management.d.ts.map +1 -1
  40. package/build/lib/real-device-management.js +8 -5
  41. package/build/lib/real-device-management.js.map +1 -1
  42. package/build/lib/real-device.d.ts +13 -9
  43. package/build/lib/real-device.d.ts.map +1 -1
  44. package/build/lib/real-device.js +49 -75
  45. package/build/lib/real-device.js.map +1 -1
  46. package/lib/app-infos-cache.js +159 -0
  47. package/lib/app-utils.js +529 -193
  48. package/lib/commands/app-management.js +20 -9
  49. package/lib/commands/app-strings.js +6 -3
  50. package/lib/commands/file-movement.js +1 -1
  51. package/lib/commands/types.ts +1 -0
  52. package/lib/desired-caps.js +1 -0
  53. package/lib/driver.js +17 -120
  54. package/lib/execute-method-map.ts +1 -1
  55. package/lib/ios-fs-helpers.js +57 -23
  56. package/lib/real-device-management.js +7 -5
  57. package/lib/real-device.js +62 -88
  58. package/npm-shrinkwrap.json +40 -32
  59. package/package.json +2 -2
@@ -1,23 +1,16 @@
1
- import {fs, timing, util} from 'appium/support';
1
+ import {timing, util, fs} from 'appium/support';
2
2
  import path from 'path';
3
3
  import {services, utilities, INSTRUMENT_CHANNEL} from 'appium-ios-device';
4
4
  import B from 'bluebird';
5
5
  import defaultLogger from './logger';
6
6
  import _ from 'lodash';
7
- import {exec} from 'teen_process';
8
- import {extractBundleId, SAFARI_BUNDLE_ID} from './app-utils';
9
- import {pushFolder} from './ios-fs-helpers';
7
+ import {SAFARI_BUNDLE_ID} from './app-utils';
8
+ import {pushFile, pushFolder, IO_TIMEOUT_MS} from './ios-fs-helpers';
10
9
  import { Devicectl } from './devicectl';
11
10
 
12
11
  const APPLICATION_INSTALLED_NOTIFICATION = 'com.apple.mobile.application_installed';
13
- const INSTALLATION_STAGING_DIR = 'PublicStaging';
14
12
  const APPLICATION_NOTIFICATION_TIMEOUT_MS = 30 * 1000;
15
- const IOS_DEPLOY = 'ios-deploy';
16
- const APP_INSTALL_STRATEGY = Object.freeze({
17
- SERIAL: 'serial',
18
- PARALLEL: 'parallel',
19
- IOS_DEPLOY,
20
- });
13
+ const INSTALLATION_STAGING_DIR = 'PublicStaging';
21
14
 
22
15
  /**
23
16
  * @returns {Promise<string[]>}
@@ -26,6 +19,11 @@ export async function getConnectedDevices() {
26
19
  return await utilities.getConnectedDevices();
27
20
  }
28
21
 
22
+ /**
23
+ * @typedef {Object} InstallOptions
24
+ * @param {number} [timeoutMs=240000] Application installation timeout in milliseconds
25
+ */
26
+
29
27
  /**
30
28
  * @typedef {Object} InstallOrUpgradeOptions
31
29
  * @property {number} timeout Install/upgrade timeout in milliseconds
@@ -71,82 +69,52 @@ export class RealDevice {
71
69
 
72
70
  /**
73
71
  *
74
- * @param {string} app
75
- * @param {number} timeout
76
- * @param {'ios-deploy'|'serial'|'parallel'|null} strategy
77
- * @privateRemarks This really needs type guards built out
72
+ * @param {string} appPath
73
+ * @param {string} bundleId
74
+ * @param {InstallOptions} [opts={}]
78
75
  */
79
- async install(app, timeout, strategy = null) {
80
- if (
81
- strategy &&
82
- !_.values(APP_INSTALL_STRATEGY).includes(/** @type {any} */ (_.toLower(strategy)))
83
- ) {
84
- throw new Error(
85
- `App installation strategy '${strategy}' is unknown. ` +
86
- `Only the following strategies are supported: ${_.values(APP_INSTALL_STRATEGY)}`,
87
- );
88
- }
89
- this.log.debug(
90
- `Using '${strategy ?? APP_INSTALL_STRATEGY.SERIAL}' app deployment strategy. ` +
91
- `You could change it by providing another value to the 'appInstallStrategy' capability`,
92
- );
93
-
94
- const installWithIosDeploy = async () => {
95
- try {
96
- await fs.which(IOS_DEPLOY);
97
- } catch (err) {
98
- throw new Error(`'${IOS_DEPLOY}' utility has not been found in PATH. Is it installed?`);
99
- }
100
- try {
101
- await exec(IOS_DEPLOY, ['--id', this.udid, '--bundle', app], {timeout});
102
- } catch (err) {
103
- throw new Error(err.stderr || err.stdout || err.message);
104
- }
105
- };
106
-
76
+ async install(appPath, bundleId, opts = {}) {
77
+ const {
78
+ timeoutMs = IO_TIMEOUT_MS,
79
+ } = opts;
107
80
  const timer = new timing.Timer().start();
108
- if (_.toLower(/** @type {'ios-deploy'} */ (strategy)) === APP_INSTALL_STRATEGY.IOS_DEPLOY) {
109
- await installWithIosDeploy();
110
- } else {
111
- const afcService = await services.startAfcService(this.udid);
112
- const enableParallelPush = _.toLower(/** @type {'parallel'} */ (strategy)) === APP_INSTALL_STRATEGY.PARALLEL;
113
- try {
114
- const bundleId = await extractBundleId(app);
115
- const bundlePathOnPhone = path.join(INSTALLATION_STAGING_DIR, bundleId);
116
- await pushFolder(afcService, app, bundlePathOnPhone, {
117
- enableParallelPush,
118
- timeoutMs: timeout,
81
+ const afcService = await services.startAfcService(this.udid);
82
+ try {
83
+ let bundlePathOnPhone;
84
+ if ((await fs.stat(appPath)).isFile()) {
85
+ // https://github.com/doronz88/pymobiledevice3/blob/6ff5001f5776e03b610363254e82d7fbcad4ef5f/pymobiledevice3/services/installation_proxy.py#L75
86
+ bundlePathOnPhone = `/${path.basename(appPath)}`;
87
+ await pushFile(afcService, appPath, bundlePathOnPhone, {
88
+ timeoutMs,
119
89
  });
120
- await this.installOrUpgradeApplication(
121
- bundlePathOnPhone,
122
- {
123
- timeout: Math.max(timeout - timer.getDuration().asMilliSeconds, 60000),
124
- isUpgrade: await this.isAppInstalled(bundleId),
125
- }
126
- );
127
- } catch (err) {
128
- this.log.warn(`Error installing app '${app}': ${err.message}`);
129
- if (err instanceof B.TimeoutError) {
130
- this.log.info(
131
- `Consider increasing the value of 'appPushTimeout' capability (the current value equals to ${timeout}ms)`
132
- );
133
- if (!enableParallelPush) {
134
- this.log.info(`Consider setting the value of 'appInstallStrategy' capability to 'parallel'`);
135
- }
136
- }
137
- this.log.warn(`Falling back to '${IOS_DEPLOY}' usage`);
138
- try {
139
- await installWithIosDeploy();
140
- } catch (err1) {
141
- throw new Error(
142
- `Could not install '${app}':\n` + ` - ${err.message}\n` + ` - ${err1.message}`,
143
- );
90
+ } else {
91
+ bundlePathOnPhone = `${INSTALLATION_STAGING_DIR}/${bundleId}`;
92
+ await pushFolder(afcService, appPath, bundlePathOnPhone, {
93
+ enableParallelPush: true,
94
+ timeoutMs,
95
+ });
96
+ }
97
+ await this.installOrUpgradeApplication(
98
+ bundlePathOnPhone,
99
+ {
100
+ timeout: Math.max(timeoutMs - timer.getDuration().asMilliSeconds, 60000),
101
+ isUpgrade: await this.isAppInstalled(bundleId),
144
102
  }
145
- } finally {
146
- afcService.close();
103
+ );
104
+ } catch (err) {
105
+ this.log.debug(err.stack);
106
+ let errMessage = `Cannot install the ${bundleId} application`;
107
+ if (err instanceof B.TimeoutError) {
108
+ errMessage += `. Consider increasing the value of 'appPushTimeout' capability (the current value equals to ${timeoutMs}ms)`;
147
109
  }
110
+ errMessage += `. Original error: ${err.message}`;
111
+ throw new Error(errMessage);
112
+ } finally {
113
+ afcService.close();
148
114
  }
149
- this.log.info(`App installation succeeded after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
115
+ this.log.info(
116
+ `The installation of '${bundleId}' succeeded after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`
117
+ );
150
118
  }
151
119
 
152
120
  /**
@@ -164,10 +132,16 @@ export class RealDevice {
164
132
  const clientOptions = {PackageType: 'Developer'};
165
133
  try {
166
134
  if (isUpgrade) {
167
- this.log.debug(`An upgrade of the existing application is going to be performed. Will timeout in ${timeout} ms`);
135
+ this.log.debug(
136
+ `An upgrade of the existing application is going to be performed. ` +
137
+ `Will timeout in ${timeout.toFixed(0)} ms`
138
+ );
168
139
  await installationService.upgradeApplication(bundlePathOnPhone, clientOptions, timeout);
169
140
  } else {
170
- this.log.debug(`A new application installation is going to be performed. Will timeout in ${timeout} ms`);
141
+ this.log.debug(
142
+ `A new application installation is going to be performed. ` +
143
+ `Will timeout in ${timeout.toFixed(0)} ms`
144
+ );
171
145
  await installationService.installApplication(bundlePathOnPhone, clientOptions, timeout);
172
146
  }
173
147
  try {
@@ -187,12 +161,12 @@ export class RealDevice {
187
161
 
188
162
  /**
189
163
  * Alias for {@linkcode install}
190
- * @param {string} app
191
- * @param {number} timeout
192
- * @param {'ios-deploy'|'serial'|'parallel'|null} strategy
164
+ * @param {string} appPath
165
+ * @param {string} bundleId
166
+ * @param {InstallOptions} [opts={}]
193
167
  */
194
- async installApp(app, timeout, strategy) {
195
- return await this.install(app, timeout, strategy);
168
+ async installApp(appPath, bundleId, opts = {}) {
169
+ return await this.install(appPath, bundleId, opts);
196
170
  }
197
171
 
198
172
  /**
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "7.13.0",
3
+ "version": "7.15.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "7.13.0",
9
+ "version": "7.15.0",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@colors/colors": "^1.6.0",
@@ -83,16 +83,16 @@
83
83
  "npm": ">=8"
84
84
  },
85
85
  "peerDependencies": {
86
- "appium": "^2.4.1"
86
+ "appium": "^2.5.4"
87
87
  }
88
88
  },
89
89
  "node_modules/@appium/base-driver": {
90
- "version": "9.5.4",
91
- "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.5.4.tgz",
92
- "integrity": "sha512-kYBYyfXu15RAvAaJ/FUR2gosm74E5Nl9N6A3AzX1SZVDqm7mLojSgBZCGrRsd/oMVE1vpMcwHWJt4JpYXkrbhw==",
90
+ "version": "9.6.0",
91
+ "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.6.0.tgz",
92
+ "integrity": "sha512-8+pqWHQ4tbvtwOxNCtHa5m0SUwQIvAwHTVKq/YUbgDn18ep4nGhz5rlryvvqyNpXEgEOhbLInIRma1KIrYdX8Q==",
93
93
  "dependencies": {
94
- "@appium/support": "^4.2.4",
95
- "@appium/types": "^0.16.2",
94
+ "@appium/support": "^4.2.5",
95
+ "@appium/types": "^0.17.0",
96
96
  "@colors/colors": "1.6.0",
97
97
  "@types/async-lock": "1.4.2",
98
98
  "@types/bluebird": "3.5.42",
@@ -125,6 +125,14 @@
125
125
  "spdy": "4.0.2"
126
126
  }
127
127
  },
128
+ "node_modules/@appium/base-driver/node_modules/lru-cache": {
129
+ "version": "10.2.0",
130
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
131
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
132
+ "engines": {
133
+ "node": "14 || >=16.14"
134
+ }
135
+ },
128
136
  "node_modules/@appium/base-driver/node_modules/type-fest": {
129
137
  "version": "4.10.1",
130
138
  "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz",
@@ -137,11 +145,11 @@
137
145
  }
138
146
  },
139
147
  "node_modules/@appium/docutils": {
140
- "version": "1.0.6",
141
- "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.6.tgz",
142
- "integrity": "sha512-I7irwTyBlMfNPfhFAcNkGLsJdZxNvWXsbcgV/oW4PU5dBN0wfwqrfLJQrrfHGTDpgDukpaTl7J+Ro82WgATWfA==",
148
+ "version": "1.0.7",
149
+ "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.7.tgz",
150
+ "integrity": "sha512-cuVcE3nNKlhJZsXrleubYkrr4VrEXaVKxq0GePb5+qmgpkx2OQb18imoPx1FKBlDbxHGrV7fuLxc/5LbmsV0dA==",
143
151
  "dependencies": {
144
- "@appium/support": "^4.2.4",
152
+ "@appium/support": "^4.2.5",
145
153
  "@appium/tsconfig": "^0.3.3",
146
154
  "@sliphua/lilconfig-ts-loader": "3.2.2",
147
155
  "@types/which": "3.0.3",
@@ -209,12 +217,12 @@
209
217
  }
210
218
  },
211
219
  "node_modules/@appium/support": {
212
- "version": "4.2.4",
213
- "resolved": "https://registry.npmjs.org/@appium/support/-/support-4.2.4.tgz",
214
- "integrity": "sha512-TfZ+sIm295EQzL89ympDwwWfuzRHnkiZv5SPDMBcrCJHXcJVcL7BhuQhkiPkHaZvNgKvyvcEb9kGNC+L2UtN+g==",
220
+ "version": "4.2.5",
221
+ "resolved": "https://registry.npmjs.org/@appium/support/-/support-4.2.5.tgz",
222
+ "integrity": "sha512-txTDZHjJF7UjEFi4uyj23gciz3yAq7OwzXFdJgtQBzkK1cIiCnywQ6igLmBg52jZp84ki8eZIDMXsQetVUuDDg==",
215
223
  "dependencies": {
216
224
  "@appium/tsconfig": "^0.3.3",
217
- "@appium/types": "^0.16.2",
225
+ "@appium/types": "^0.17.0",
218
226
  "@colors/colors": "1.6.0",
219
227
  "@types/archiver": "6.0.2",
220
228
  "@types/base64-stream": "1.0.5",
@@ -265,7 +273,7 @@
265
273
  "type-fest": "4.10.1",
266
274
  "uuid": "9.0.1",
267
275
  "which": "4.0.0",
268
- "yauzl": "3.1.2"
276
+ "yauzl": "3.1.3"
269
277
  },
270
278
  "engines": {
271
279
  "node": "^14.17.0 || ^16.13.0 || >=18.0.0",
@@ -299,9 +307,9 @@
299
307
  }
300
308
  },
301
309
  "node_modules/@appium/types": {
302
- "version": "0.16.2",
303
- "resolved": "https://registry.npmjs.org/@appium/types/-/types-0.16.2.tgz",
304
- "integrity": "sha512-4LpzS26hfTuK5rAXogotydMFjA0UdWKpQscpsIJKJQ3KGNYNNSQL0fpVcJ6hHHXA2/ySI6DtQeK9+ayUBCUqYg==",
310
+ "version": "0.17.0",
311
+ "resolved": "https://registry.npmjs.org/@appium/types/-/types-0.17.0.tgz",
312
+ "integrity": "sha512-7Q9C5Y4G8ZQzdU0uJIlfVqpGMAzNqdXpNWziQTUfZyD7fHbYz9ScZrlgs2/DYMITRrHiIblmzY/5yzfu00rQuA==",
305
313
  "dependencies": {
306
314
  "@appium/schema": "^0.5.0",
307
315
  "@appium/tsconfig": "^0.3.3",
@@ -922,9 +930,9 @@
922
930
  }
923
931
  },
924
932
  "node_modules/appium-remote-debugger": {
925
- "version": "11.1.0",
926
- "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-11.1.0.tgz",
927
- "integrity": "sha512-Hexj1V8e7BnnfhfDbUU+jDOd6ChK8lSZktm8eXXfaobABXo/0/pkfoyo6S5Gt/o9bmualQOLzjcsEWJOJEedtg==",
933
+ "version": "11.1.1",
934
+ "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-11.1.1.tgz",
935
+ "integrity": "sha512-Fcu3U6mQtWBq+zQDb1fhnxoVTyZ5cmPi+dpM6zy+eVbYk/nR9n20v4uOQstH2ySnAknpNGVMSQVPBoZOP+YS2Q==",
928
936
  "dependencies": {
929
937
  "@appium/base-driver": "^9.0.0",
930
938
  "@appium/support": "^4.0.0",
@@ -944,9 +952,9 @@
944
952
  }
945
953
  },
946
954
  "node_modules/appium-webdriveragent": {
947
- "version": "8.5.2",
948
- "resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-8.5.2.tgz",
949
- "integrity": "sha512-v7DfnS9sN4KD6ahAOixGF90ajJUZADYim9mxOSIH2Qs3hX/KHURbHD9khQJp5Kbu0jeIpmaLj+yXpbtAg8c+9g==",
955
+ "version": "8.5.6",
956
+ "resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-8.5.6.tgz",
957
+ "integrity": "sha512-9cfqCfgQ4RmVI66jWuw71Xf1u9EErVaB8KVDGMtOaYxpS3QH6DoGRTWDEzUfmhvOfOZg0mtkHnh4WM1fvscI7w==",
950
958
  "dependencies": {
951
959
  "@appium/base-driver": "^9.0.0",
952
960
  "@appium/strongbox": "^0.x",
@@ -2532,9 +2540,9 @@
2532
2540
  }
2533
2541
  },
2534
2542
  "node_modules/lru-cache": {
2535
- "version": "10.2.0",
2536
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
2537
- "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
2543
+ "version": "10.2.1",
2544
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.1.tgz",
2545
+ "integrity": "sha512-tS24spDe/zXhWbNPErCHs/AGOzbKGHT+ybSBqmdLm8WZ1xXLWvH8Qn71QPAlqVhd0qUTWjy+Kl9JmISgDdEjsA==",
2538
2546
  "engines": {
2539
2547
  "node": "14 || >=16.14"
2540
2548
  }
@@ -4217,9 +4225,9 @@
4217
4225
  }
4218
4226
  },
4219
4227
  "node_modules/yauzl": {
4220
- "version": "3.1.2",
4221
- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.2.tgz",
4222
- "integrity": "sha512-621iCPgEG1wXViDZS/L3h9F8TgrdQV1eayJlJ8j5A2SZg8OdY/1DLf+VxNeD+q5QbMFEAbjjR8nITj7g4nKa0Q==",
4228
+ "version": "3.1.3",
4229
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.1.3.tgz",
4230
+ "integrity": "sha512-JCCdmlJJWv7L0q/KylOekyRaUrdEoUxWkWVcgorosTROCFWiS9p2NNPE9Yb91ak7b1N5SxAZEliWpspbZccivw==",
4223
4231
  "dependencies": {
4224
4232
  "buffer-crc32": "~0.2.3",
4225
4233
  "pend": "~1.2.0"
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "7.13.0",
11
+ "version": "7.15.0",
12
12
  "author": "Appium Contributors",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {
@@ -131,7 +131,7 @@
131
131
  "singleQuote": true
132
132
  },
133
133
  "peerDependencies": {
134
- "appium": "^2.4.1"
134
+ "appium": "^2.5.4"
135
135
  },
136
136
  "devDependencies": {
137
137
  "@appium/docutils": "^1.0.2",