appium-xcuitest-driver 7.6.1 → 7.7.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.
- package/CHANGELOG.md +14 -0
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +9 -17
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +2 -4
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/biometric.d.ts.map +1 -1
- package/build/lib/commands/biometric.js +3 -6
- package/build/lib/commands/biometric.js.map +1 -1
- package/build/lib/commands/certificate.d.ts +1 -1
- package/build/lib/commands/certificate.d.ts.map +1 -1
- package/build/lib/commands/certificate.js +3 -5
- package/build/lib/commands/certificate.js.map +1 -1
- package/build/lib/commands/condition.d.ts.map +1 -1
- package/build/lib/commands/condition.js +2 -4
- package/build/lib/commands/condition.js.map +1 -1
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +1 -2
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/deviceInfo.d.ts.map +1 -1
- package/build/lib/commands/deviceInfo.js +1 -2
- package/build/lib/commands/deviceInfo.js.map +1 -1
- package/build/lib/commands/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +14 -22
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +1 -2
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/gesture.d.ts.map +1 -1
- package/build/lib/commands/gesture.js +1 -2
- package/build/lib/commands/gesture.js.map +1 -1
- package/build/lib/commands/keychains.js +1 -2
- package/build/lib/commands/keychains.js.map +1 -1
- package/build/lib/commands/localization.d.ts.map +1 -1
- package/build/lib/commands/localization.js +1 -3
- package/build/lib/commands/localization.js.map +1 -1
- package/build/lib/commands/location.d.ts.map +1 -1
- package/build/lib/commands/location.js +1 -2
- package/build/lib/commands/location.js.map +1 -1
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +2 -4
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +2 -2
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/notifications.d.ts +1 -1
- package/build/lib/commands/notifications.d.ts.map +1 -1
- package/build/lib/commands/notifications.js +1 -2
- package/build/lib/commands/notifications.js.map +1 -1
- package/build/lib/commands/pasteboard.d.ts.map +1 -1
- package/build/lib/commands/pasteboard.js +2 -4
- package/build/lib/commands/pasteboard.js.map +1 -1
- package/build/lib/commands/pcap.d.ts.map +1 -1
- package/build/lib/commands/pcap.js +1 -2
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +4 -9
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +2 -4
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +1 -2
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/screenshots.d.ts +3 -2
- package/build/lib/commands/screenshots.d.ts.map +1 -1
- package/build/lib/commands/screenshots.js +8 -3
- package/build/lib/commands/screenshots.js.map +1 -1
- package/build/lib/commands/web.d.ts.map +1 -1
- package/build/lib/commands/web.js +1 -2
- package/build/lib/commands/web.js.map +1 -1
- package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
- package/build/lib/commands/xctest-record-screen.js +2 -4
- package/build/lib/commands/xctest-record-screen.js.map +1 -1
- package/build/lib/commands/xctest.d.ts.map +1 -1
- package/build/lib/commands/xctest.js +2 -4
- package/build/lib/commands/xctest.js.map +1 -1
- package/build/lib/driver.d.ts +26 -8
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +89 -83
- package/build/lib/driver.js.map +1 -1
- package/build/lib/py-ios-device-client.d.ts +1 -1
- package/build/lib/real-device-management.d.ts +30 -27
- package/build/lib/real-device-management.d.ts.map +1 -1
- package/build/lib/real-device-management.js +34 -35
- package/build/lib/real-device-management.js.map +1 -1
- package/build/lib/real-device.d.ts +36 -9
- package/build/lib/real-device.d.ts.map +1 -1
- package/build/lib/real-device.js +46 -15
- package/build/lib/real-device.js.map +1 -1
- package/build/lib/simulator-management.d.ts +58 -68
- package/build/lib/simulator-management.d.ts.map +1 -1
- package/build/lib/simulator-management.js +74 -66
- package/build/lib/simulator-management.js.map +1 -1
- package/lib/commands/app-management.js +11 -18
- package/lib/commands/appearance.js +4 -4
- package/lib/commands/biometric.js +3 -6
- package/lib/commands/certificate.js +3 -5
- package/lib/commands/condition.js +2 -4
- package/lib/commands/context.js +1 -2
- package/lib/commands/deviceInfo.js +1 -2
- package/lib/commands/file-movement.js +14 -22
- package/lib/commands/general.js +1 -2
- package/lib/commands/gesture.js +1 -2
- package/lib/commands/keychains.js +2 -2
- package/lib/commands/localization.js +1 -4
- package/lib/commands/location.js +1 -2
- package/lib/commands/log.js +2 -4
- package/lib/commands/memory.js +2 -2
- package/lib/commands/notifications.js +1 -2
- package/lib/commands/pasteboard.js +4 -4
- package/lib/commands/pcap.js +1 -2
- package/lib/commands/performance.js +4 -8
- package/lib/commands/permissions.js +6 -4
- package/lib/commands/recordscreen.js +1 -2
- package/lib/commands/screenshots.js +8 -3
- package/lib/commands/web.js +1 -2
- package/lib/commands/xctest-record-screen.js +2 -4
- package/lib/commands/xctest.js +2 -4
- package/lib/driver.js +91 -86
- package/lib/real-device-management.js +37 -44
- package/lib/real-device.js +47 -17
- package/lib/simulator-management.js +83 -82
- package/npm-shrinkwrap.json +14 -36
- package/package.json +2 -2
package/lib/driver.js
CHANGED
|
@@ -384,6 +384,14 @@ class XCUITestDriver extends BaseDriver {
|
|
|
384
384
|
return didMerge;
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
/**
|
|
388
|
+
* @returns {Simulator|RealDevice}
|
|
389
|
+
*/
|
|
390
|
+
get device() {
|
|
391
|
+
// @ts-ignore This property should exist
|
|
392
|
+
return this.opts?.device;
|
|
393
|
+
}
|
|
394
|
+
|
|
387
395
|
isXcodebuildNeeded() {
|
|
388
396
|
return !(CAP_NAMES_NO_XCODEBUILD_REQUIRED.some((x) => Boolean(this.opts[x])));
|
|
389
397
|
}
|
|
@@ -484,6 +492,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
484
492
|
this.log.info(
|
|
485
493
|
`Determining device to run tests on: udid: '${udid}', real device: ${realDevice}`,
|
|
486
494
|
);
|
|
495
|
+
// TODO: extract device out of opts to a separate driver property
|
|
487
496
|
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
488
497
|
this.opts.device = device;
|
|
489
498
|
this.opts.udid = udid;
|
|
@@ -499,22 +508,18 @@ class XCUITestDriver extends BaseDriver {
|
|
|
499
508
|
this.log.info(
|
|
500
509
|
`Setting simulator devices set path to '${this.opts.simulatorDevicesSetPath}'`,
|
|
501
510
|
);
|
|
502
|
-
|
|
503
|
-
this.opts.device.devicesSetPath = this.opts.simulatorDevicesSetPath;
|
|
511
|
+
(/** @type {Simulator} */ (this.device)).devicesSetPath = this.opts.simulatorDevicesSetPath;
|
|
504
512
|
}
|
|
505
513
|
}
|
|
506
514
|
|
|
507
515
|
// at this point if there is no platformVersion, get it from the device
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
511
|
-
this.opts.platformVersion = await this.opts.device.getPlatformVersion();
|
|
516
|
+
if (!this.opts.platformVersion) {
|
|
517
|
+
this.opts.platformVersion = await this.device.getPlatformVersion();
|
|
512
518
|
this.log.info(
|
|
513
519
|
`No platformVersion specified. Using device version: '${this.opts.platformVersion}'`,
|
|
514
520
|
);
|
|
515
521
|
}
|
|
516
522
|
|
|
517
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
518
523
|
const normalizedVersion = normalizePlatformVersion(this.opts.platformVersion);
|
|
519
524
|
if (this.opts.platformVersion !== normalizedVersion) {
|
|
520
525
|
this.log.info(
|
|
@@ -604,8 +609,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
604
609
|
!this.opts.app &&
|
|
605
610
|
this.opts.bundleId &&
|
|
606
611
|
!this.isSafari() &&
|
|
607
|
-
|
|
608
|
-
!(await this.opts.device.isAppInstalled(this.opts.bundleId))
|
|
612
|
+
!(await this.device.isAppInstalled(this.opts.bundleId))
|
|
609
613
|
) {
|
|
610
614
|
this.log.errorAndThrow(`App with bundle identifier '${this.opts.bundleId}' unknown`);
|
|
611
615
|
}
|
|
@@ -614,8 +618,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
614
618
|
if (this.opts.permissions) {
|
|
615
619
|
this.log.debug('Setting the requested permissions before WDA is started');
|
|
616
620
|
for (const [bundleId, permissionsMapping] of _.toPairs(JSON.parse(this.opts.permissions))) {
|
|
617
|
-
|
|
618
|
-
await this.opts.device.setPermissions(bundleId, permissionsMapping);
|
|
621
|
+
await /** @type {Simulator} */ (this.device).setPermissions(bundleId, permissionsMapping);
|
|
619
622
|
}
|
|
620
623
|
}
|
|
621
624
|
|
|
@@ -628,15 +631,14 @@ class XCUITestDriver extends BaseDriver {
|
|
|
628
631
|
const methodName = `${
|
|
629
632
|
this.opts.calendarAccessAuthorized ? 'enable' : 'disable'
|
|
630
633
|
}CalendarAccess`;
|
|
631
|
-
|
|
632
|
-
await this.opts.device[methodName](this.opts.bundleId);
|
|
634
|
+
await this.device[methodName](this.opts.bundleId);
|
|
633
635
|
}
|
|
634
636
|
}
|
|
635
637
|
|
|
636
638
|
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
637
639
|
await this.startWda(this.opts.sessionId);
|
|
638
640
|
|
|
639
|
-
if (this.opts.orientation) {
|
|
641
|
+
if (_.isString(this.opts.orientation)) {
|
|
640
642
|
await this.setInitialOrientation(this.opts.orientation);
|
|
641
643
|
this.logEvent('orientationSet');
|
|
642
644
|
}
|
|
@@ -663,12 +665,11 @@ class XCUITestDriver extends BaseDriver {
|
|
|
663
665
|
* Start the simulator and initialize based on capabilities
|
|
664
666
|
*/
|
|
665
667
|
async initSimulator() {
|
|
666
|
-
|
|
667
|
-
const device = this.opts.device;
|
|
668
|
+
const device = /** @type {Simulator} */ (this.device);
|
|
668
669
|
|
|
669
670
|
if (this.opts.shutdownOtherSimulators) {
|
|
670
671
|
this.assertFeatureEnabled(SHUTDOWN_OTHER_FEAT_NAME);
|
|
671
|
-
await shutdownOtherSimulators(
|
|
672
|
+
await shutdownOtherSimulators.bind(this)();
|
|
672
673
|
}
|
|
673
674
|
|
|
674
675
|
await this.startSim();
|
|
@@ -679,17 +680,21 @@ class XCUITestDriver extends BaseDriver {
|
|
|
679
680
|
this.logEvent('customCertInstalled');
|
|
680
681
|
}
|
|
681
682
|
|
|
682
|
-
if (await setSafariPrefs(
|
|
683
|
+
if (await setSafariPrefs.bind(this)()) {
|
|
683
684
|
this.log.debug('Safari preferences have been updated');
|
|
684
685
|
}
|
|
685
686
|
|
|
686
|
-
if (await setLocalizationPrefs(
|
|
687
|
+
if (await setLocalizationPrefs.bind(this)()) {
|
|
687
688
|
this.log.debug('Localization preferences have been updated');
|
|
688
689
|
}
|
|
689
690
|
|
|
691
|
+
/** @type {Promise[]} */
|
|
690
692
|
const promises = ['reduceMotion', 'reduceTransparency', 'autoFillPasswords']
|
|
691
693
|
.filter((optName) => _.isBoolean(this.opts[optName]))
|
|
692
|
-
.map((optName) =>
|
|
694
|
+
.map((optName) => {
|
|
695
|
+
this.log.info(`Setting ${optName} to ${this.opts[optName]}`);
|
|
696
|
+
return device[`set${_.upperFirst(optName)}`](this.opts[optName]);
|
|
697
|
+
});
|
|
693
698
|
await B.all(promises);
|
|
694
699
|
|
|
695
700
|
if (this.opts.launchWithIDB) {
|
|
@@ -829,16 +834,20 @@ class XCUITestDriver extends BaseDriver {
|
|
|
829
834
|
errorMsg += `. Make sure you follow the tutorial at ${WDA_REAL_DEV_TUTORIAL_URL}`;
|
|
830
835
|
}
|
|
831
836
|
if (this.opts.usePreinstalledWDA) {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
837
|
+
try {
|
|
838
|
+
// In case the bundle id process start got failed because of
|
|
839
|
+
// auth popup in the device. Then, the bundle id process itself started. It is safe to stop it here.
|
|
840
|
+
await this.mobileKillApp(this.wda.bundleIdForXctest);
|
|
841
|
+
} catch (ign) {};
|
|
835
842
|
// Mostly it failed to start the WDA process as no the bundle id
|
|
836
843
|
// e.g. '<bundle id of WDA> not found on device <udid>'
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
844
|
+
|
|
845
|
+
errorMsg = `Unable to launch WebDriverAgent. Original error: ${err.message}. ` +
|
|
846
|
+
`Make sure the application ${this.wda.bundleIdForXctest} exists and it is launchable.`;
|
|
847
|
+
if (this.isRealDevice()) {
|
|
848
|
+
errorMsg += ` ${WDA_REAL_DEV_TUTORIAL_URL} may help to complete the preparation.`;
|
|
849
|
+
};
|
|
850
|
+
throw new Error(errorMsg);
|
|
842
851
|
} else {
|
|
843
852
|
await quitAndUninstall(errorMsg);
|
|
844
853
|
}
|
|
@@ -886,16 +895,14 @@ class XCUITestDriver extends BaseDriver {
|
|
|
886
895
|
|
|
887
896
|
/**
|
|
888
897
|
*
|
|
889
|
-
* @param {
|
|
898
|
+
* @param {boolean} [enforceSimulatorShutdown=false]
|
|
890
899
|
*/
|
|
891
|
-
async runReset(
|
|
900
|
+
async runReset(enforceSimulatorShutdown = false) {
|
|
892
901
|
this.logEvent('resetStarted');
|
|
893
902
|
if (this.isRealDevice()) {
|
|
894
|
-
|
|
895
|
-
await runRealDeviceReset(this.opts.device, opts || this.opts);
|
|
903
|
+
await runRealDeviceReset.bind(this)();
|
|
896
904
|
} else {
|
|
897
|
-
|
|
898
|
-
await runSimulatorReset(this.opts.device, opts || this.opts);
|
|
905
|
+
await runSimulatorReset.bind(this)(enforceSimulatorShutdown);
|
|
899
906
|
}
|
|
900
907
|
this.logEvent('resetComplete');
|
|
901
908
|
}
|
|
@@ -944,18 +951,13 @@ class XCUITestDriver extends BaseDriver {
|
|
|
944
951
|
}
|
|
945
952
|
|
|
946
953
|
if (this.opts.resetOnSessionStartOnly === false) {
|
|
947
|
-
await this.runReset(
|
|
948
|
-
Object.assign({}, this.opts, {
|
|
949
|
-
enforceSimulatorShutdown: true,
|
|
950
|
-
}),
|
|
951
|
-
);
|
|
954
|
+
await this.runReset(true);
|
|
952
955
|
}
|
|
953
956
|
|
|
954
|
-
|
|
955
|
-
const simulatorDevice = this.isSimulator() ? this.opts.device : null;
|
|
957
|
+
const simulatorDevice = this.isSimulator() ? /** @type {Simulator} */ (this.device) : null;
|
|
956
958
|
if (simulatorDevice && this.lifecycleData.createSim) {
|
|
957
959
|
this.log.debug(`Deleting simulator created for this run (udid: '${simulatorDevice.udid}')`);
|
|
958
|
-
await shutdownSimulator(
|
|
960
|
+
await shutdownSimulator.bind(this)();
|
|
959
961
|
await simulatorDevice.delete();
|
|
960
962
|
}
|
|
961
963
|
|
|
@@ -1168,19 +1170,16 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1168
1170
|
this.opts.deviceName = translateDeviceName(this.opts.platformVersion, this.opts.deviceName);
|
|
1169
1171
|
|
|
1170
1172
|
const setupVersionCaps = async () => {
|
|
1173
|
+
const iosSdkVersion = await getAndCheckIosSdkVersion();
|
|
1171
1174
|
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1172
|
-
this.opts.iosSdkVersion =
|
|
1173
|
-
|
|
1174
|
-
this.
|
|
1175
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1176
|
-
if (!this.opts.platformVersion && this.opts.iosSdkVersion) {
|
|
1175
|
+
this.opts.iosSdkVersion = iosSdkVersion;
|
|
1176
|
+
this.log.info(`iOS SDK Version set to '${iosSdkVersion}'`);
|
|
1177
|
+
if (!this.opts.platformVersion && iosSdkVersion) {
|
|
1177
1178
|
this.log.info(
|
|
1178
|
-
|
|
1179
|
-
`No platformVersion specified. Using the latest version Xcode supports: '${this.opts.iosSdkVersion}'. ` +
|
|
1179
|
+
`No platformVersion specified. Using the latest version Xcode supports: '${iosSdkVersion}'. ` +
|
|
1180
1180
|
`This may cause problems if a simulator does not exist for this platform version.`,
|
|
1181
1181
|
);
|
|
1182
|
-
|
|
1183
|
-
this.opts.platformVersion = normalizePlatformVersion(this.opts.iosSdkVersion);
|
|
1182
|
+
this.opts.platformVersion = normalizePlatformVersion(iosSdkVersion);
|
|
1184
1183
|
}
|
|
1185
1184
|
};
|
|
1186
1185
|
|
|
@@ -1195,11 +1194,10 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1195
1194
|
);
|
|
1196
1195
|
await setupVersionCaps();
|
|
1197
1196
|
|
|
1198
|
-
|
|
1199
|
-
const device = await getExistingSim(this.opts);
|
|
1197
|
+
const device = await getExistingSim.bind(this)();
|
|
1200
1198
|
if (!device) {
|
|
1201
1199
|
// No matching Simulator is found. Throw an error
|
|
1202
|
-
this.log.
|
|
1200
|
+
throw this.log.errorWithException(
|
|
1203
1201
|
`Cannot detect udid for ${this.opts.deviceName} Simulator running iOS ${this.opts.platformVersion}`,
|
|
1204
1202
|
);
|
|
1205
1203
|
}
|
|
@@ -1221,6 +1219,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1221
1219
|
try {
|
|
1222
1220
|
const device = await getSimulator(this.opts.udid, {
|
|
1223
1221
|
devicesSetPath: this.opts.simulatorDevicesSetPath,
|
|
1222
|
+
logger: this.log,
|
|
1224
1223
|
});
|
|
1225
1224
|
return {device, realDevice: false, udid: this.opts.udid};
|
|
1226
1225
|
} catch (ign) {
|
|
@@ -1230,7 +1229,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1230
1229
|
}
|
|
1231
1230
|
}
|
|
1232
1231
|
|
|
1233
|
-
const device = getRealDeviceObj(this
|
|
1232
|
+
const device = getRealDeviceObj.bind(this)();
|
|
1234
1233
|
return {device, realDevice: true, udid: this.opts.udid};
|
|
1235
1234
|
}
|
|
1236
1235
|
|
|
@@ -1245,8 +1244,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1245
1244
|
);
|
|
1246
1245
|
} else {
|
|
1247
1246
|
// figure out the correct simulator to use, given the desired capabilities
|
|
1248
|
-
|
|
1249
|
-
const device = await getExistingSim(this.opts);
|
|
1247
|
+
const device = await getExistingSim.bind(this)();
|
|
1250
1248
|
// check for an existing simulator
|
|
1251
1249
|
if (device) {
|
|
1252
1250
|
return {device, realDevice: false, udid: device.udid};
|
|
@@ -1260,20 +1258,21 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1260
1258
|
}
|
|
1261
1259
|
|
|
1262
1260
|
async startSim() {
|
|
1261
|
+
/** @type {import('appium-ios-simulator').DevicePreferences} */
|
|
1262
|
+
const devicePreferences = {};
|
|
1263
|
+
/** @type {import('appium-ios-simulator').RunOptions} */
|
|
1263
1264
|
const runOpts = {
|
|
1264
1265
|
scaleFactor: this.opts.scaleFactor,
|
|
1265
1266
|
connectHardwareKeyboard: !!this.opts.connectHardwareKeyboard,
|
|
1266
1267
|
pasteboardAutomaticSync: this.opts.simulatorPasteboardAutomaticSync ?? 'off',
|
|
1267
1268
|
isHeadless: !!this.opts.isHeadless,
|
|
1268
1269
|
tracePointer: this.opts.simulatorTracePointer,
|
|
1269
|
-
devicePreferences
|
|
1270
|
+
devicePreferences,
|
|
1270
1271
|
};
|
|
1271
1272
|
|
|
1272
1273
|
// add the window center, if it is specified
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1276
|
-
runOpts.devicePreferences.SimulatorWindowCenter = this.opts.SimulatorWindowCenter;
|
|
1274
|
+
if (this.opts.simulatorWindowCenter) {
|
|
1275
|
+
devicePreferences.SimulatorWindowCenter = this.opts.simulatorWindowCenter;
|
|
1277
1276
|
}
|
|
1278
1277
|
|
|
1279
1278
|
if (_.isInteger(this.opts.simulatorStartupTimeout)) {
|
|
@@ -1285,23 +1284,22 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1285
1284
|
const orientation = _.isString(this.opts.orientation) && this.opts.orientation.toUpperCase();
|
|
1286
1285
|
switch (orientation) {
|
|
1287
1286
|
case 'LANDSCAPE':
|
|
1288
|
-
|
|
1289
|
-
|
|
1287
|
+
devicePreferences.SimulatorWindowOrientation = 'LandscapeLeft';
|
|
1288
|
+
devicePreferences.SimulatorWindowRotationAngle = 90;
|
|
1290
1289
|
break;
|
|
1291
1290
|
case 'PORTRAIT':
|
|
1292
|
-
|
|
1293
|
-
|
|
1291
|
+
devicePreferences.SimulatorWindowOrientation = 'Portrait';
|
|
1292
|
+
devicePreferences.SimulatorWindowRotationAngle = 0;
|
|
1294
1293
|
break;
|
|
1295
1294
|
}
|
|
1296
1295
|
|
|
1297
|
-
|
|
1298
|
-
await this.opts.device.run(runOpts);
|
|
1296
|
+
await /** @type {Simulator} */ (this.device).run(runOpts);
|
|
1299
1297
|
}
|
|
1300
1298
|
|
|
1301
1299
|
async createSim() {
|
|
1302
1300
|
this.lifecycleData.createSim = true;
|
|
1303
1301
|
// create sim for caps
|
|
1304
|
-
const sim = await createSim(this
|
|
1302
|
+
const sim = await createSim.bind(this)();
|
|
1305
1303
|
this.log.info(`Created simulator with udid '${sim.udid}'.`);
|
|
1306
1304
|
return sim;
|
|
1307
1305
|
}
|
|
@@ -1670,15 +1668,13 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1670
1668
|
const {install, skipUninstall} = await this.checkAutInstallationState();
|
|
1671
1669
|
if (install) {
|
|
1672
1670
|
if (this.isRealDevice()) {
|
|
1673
|
-
|
|
1674
|
-
await installToRealDevice(this.opts.device, this.opts.app, this.opts.bundleId, {
|
|
1671
|
+
await installToRealDevice.bind(this)(this.opts.app, this.opts.bundleId, {
|
|
1675
1672
|
skipUninstall,
|
|
1676
1673
|
timeout: this.opts.appPushTimeout,
|
|
1677
1674
|
strategy: this.opts.appInstallStrategy,
|
|
1678
1675
|
});
|
|
1679
1676
|
} else {
|
|
1680
|
-
|
|
1681
|
-
await installToSimulator(this.opts.device, this.opts.app, this.opts.bundleId, {
|
|
1677
|
+
await installToSimulator.bind(this)(this.opts.app, this.opts.bundleId, {
|
|
1682
1678
|
skipUninstall,
|
|
1683
1679
|
newSimulator: this.lifecycleData?.createSim,
|
|
1684
1680
|
});
|
|
@@ -1693,6 +1689,10 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1693
1689
|
}
|
|
1694
1690
|
}
|
|
1695
1691
|
|
|
1692
|
+
/**
|
|
1693
|
+
* @param {string|string[]} otherApps
|
|
1694
|
+
* @returns {Promise<void>}
|
|
1695
|
+
*/
|
|
1696
1696
|
async installOtherApps(otherApps) {
|
|
1697
1697
|
/** @type {string[]|undefined} */
|
|
1698
1698
|
let appsList;
|
|
@@ -1712,9 +1712,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1712
1712
|
const appIds = await B.all(appPaths.map((appPath) => extractBundleId(appPath)));
|
|
1713
1713
|
for (const [appId, appPath] of _.zip(appIds, appPaths)) {
|
|
1714
1714
|
if (this.isRealDevice()) {
|
|
1715
|
-
await installToRealDevice(
|
|
1716
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1717
|
-
this.opts.device,
|
|
1715
|
+
await installToRealDevice.bind(this)(
|
|
1718
1716
|
appPath,
|
|
1719
1717
|
appId,
|
|
1720
1718
|
{
|
|
@@ -1724,10 +1722,7 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1724
1722
|
},
|
|
1725
1723
|
);
|
|
1726
1724
|
} else {
|
|
1727
|
-
await installToSimulator(
|
|
1728
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1729
|
-
this.opts.device,
|
|
1730
|
-
// @ts-ignore the path should always be defined
|
|
1725
|
+
await installToSimulator.bind(this)(
|
|
1731
1726
|
appPath,
|
|
1732
1727
|
appId,
|
|
1733
1728
|
{
|
|
@@ -1738,6 +1733,10 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1738
1733
|
}
|
|
1739
1734
|
}
|
|
1740
1735
|
|
|
1736
|
+
/**
|
|
1737
|
+
* @param {string} orientation
|
|
1738
|
+
* @returns {Promise<void>}
|
|
1739
|
+
*/
|
|
1741
1740
|
async setInitialOrientation(orientation) {
|
|
1742
1741
|
const dstOrientation = _.toUpper(orientation);
|
|
1743
1742
|
if (!SUPPORTED_ORIENATIONS.includes(dstOrientation)) {
|
|
@@ -1756,6 +1755,10 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1756
1755
|
}
|
|
1757
1756
|
}
|
|
1758
1757
|
|
|
1758
|
+
/**
|
|
1759
|
+
* @param {string} [cmdName]
|
|
1760
|
+
* @returns {number|undefined}
|
|
1761
|
+
*/
|
|
1759
1762
|
_getCommandTimeout(cmdName) {
|
|
1760
1763
|
if (this.opts.commandTimeouts) {
|
|
1761
1764
|
if (cmdName && _.has(this.opts.commandTimeouts, cmdName)) {
|
|
@@ -1792,14 +1795,11 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1792
1795
|
`Installing prebuilt WDA at '${this.opts.prebuiltWDAPath}'. ` +
|
|
1793
1796
|
`Bundle identifier: ${candidateBundleId}.`
|
|
1794
1797
|
);
|
|
1795
|
-
// @ts-expect-error - do not assign arbitrary properties to `this.opts`
|
|
1796
|
-
const device = this.opts.device;
|
|
1797
1798
|
|
|
1798
1799
|
// Note: The CFBundleVersion in the test bundle was always 1.
|
|
1799
1800
|
// It may not be able to compare with the installed versio.
|
|
1800
1801
|
if (this.isRealDevice()) {
|
|
1801
|
-
await installToRealDevice(
|
|
1802
|
-
device,
|
|
1802
|
+
await installToRealDevice.bind(this)(
|
|
1803
1803
|
this.opts.prebuiltWDAPath,
|
|
1804
1804
|
candidateBundleId,
|
|
1805
1805
|
{
|
|
@@ -1809,7 +1809,10 @@ class XCUITestDriver extends BaseDriver {
|
|
|
1809
1809
|
},
|
|
1810
1810
|
);
|
|
1811
1811
|
} else {
|
|
1812
|
-
await installToSimulator(
|
|
1812
|
+
await installToSimulator.bind(this)(
|
|
1813
|
+
this.opts.prebuiltWDAPath,
|
|
1814
|
+
candidateBundleId
|
|
1815
|
+
);
|
|
1813
1816
|
}
|
|
1814
1817
|
}
|
|
1815
1818
|
|
|
@@ -2266,4 +2269,6 @@ export {XCUITestDriver};
|
|
|
2266
2269
|
* @typedef {import('./commands/types').FullContext} FullContext
|
|
2267
2270
|
* @typedef {import('./types').WDACapabilities} WDACapabilities
|
|
2268
2271
|
* @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
|
|
2269
|
-
|
|
2272
|
+
* @typedef {import('appium-ios-simulator').Simulator} Simulator
|
|
2273
|
+
* @typedef {import('./real-device').RealDevice} RealDevice
|
|
2274
|
+
*/
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {utilities} from 'appium-ios-device';
|
|
2
2
|
import RealDevice from './real-device';
|
|
3
|
-
import log from './logger';
|
|
4
3
|
import {SAFARI_BUNDLE_ID} from './app-utils';
|
|
5
4
|
|
|
6
|
-
async function getConnectedDevices() {
|
|
5
|
+
export async function getConnectedDevices() {
|
|
7
6
|
return await utilities.getConnectedDevices();
|
|
8
7
|
}
|
|
9
8
|
|
|
@@ -11,24 +10,25 @@ async function getConnectedDevices() {
|
|
|
11
10
|
* @param {string} udid
|
|
12
11
|
* @returns {Promise<string>}
|
|
13
12
|
*/
|
|
14
|
-
async function getOSVersion(udid) {
|
|
13
|
+
export async function getOSVersion(udid) {
|
|
15
14
|
return await utilities.getOSVersion(udid);
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
|
-
* @
|
|
20
|
-
* @param {import('./driver').XCUITestDriverOpts} opts
|
|
18
|
+
* @this {import('./driver').XCUITestDriver}
|
|
21
19
|
* @returns {Promise<void>}
|
|
22
20
|
*/
|
|
23
|
-
async function resetRealDevice(
|
|
24
|
-
const {bundleId, fullReset} = opts;
|
|
21
|
+
export async function resetRealDevice() {
|
|
22
|
+
const {bundleId, fullReset} = this.opts;
|
|
25
23
|
if (!bundleId) {
|
|
26
24
|
return;
|
|
27
25
|
}
|
|
28
26
|
|
|
27
|
+
const device = /** @type {RealDevice} */ (this.device);
|
|
28
|
+
|
|
29
29
|
if (bundleId === SAFARI_BUNDLE_ID) {
|
|
30
|
-
log.debug('Reset requested. About to terminate Safari');
|
|
31
|
-
await device.terminateApp(bundleId, opts.platformVersion);
|
|
30
|
+
this.log.debug('Reset requested. About to terminate Safari');
|
|
31
|
+
await device.terminateApp(bundleId, String(this.opts.platformVersion));
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -36,33 +36,33 @@ async function resetRealDevice(device, opts) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
log.debug(`Reset: fullReset requested. Will try to uninstall the app '${bundleId}'.`);
|
|
39
|
+
this.log.debug(`Reset: fullReset requested. Will try to uninstall the app '${bundleId}'.`);
|
|
40
40
|
if (!(await device.isAppInstalled(bundleId))) {
|
|
41
|
-
log.debug('Reset: app not installed. No need to uninstall');
|
|
41
|
+
this.log.debug('Reset: app not installed. No need to uninstall');
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
+
|
|
44
45
|
try {
|
|
45
46
|
await device.remove(bundleId);
|
|
46
47
|
} catch (err) {
|
|
47
|
-
log.error(`Reset: could not remove '${bundleId}' from device: ${err.message}`);
|
|
48
|
+
this.log.error(`Reset: could not remove '${bundleId}' from device: ${err.message}`);
|
|
48
49
|
throw err;
|
|
49
50
|
}
|
|
50
|
-
log.debug(`Reset: removed '${bundleId}'`);
|
|
51
|
+
this.log.debug(`Reset: removed '${bundleId}'`);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
|
-
* @
|
|
55
|
-
* @param {import('./driver').XCUITestDriverOpts} opts
|
|
55
|
+
* @this {import('./driver').XCUITestDriver}
|
|
56
56
|
* @returns {Promise<void>}
|
|
57
57
|
*/
|
|
58
|
-
async function runRealDeviceReset(
|
|
59
|
-
if (!opts.noReset || opts.fullReset) {
|
|
60
|
-
log.debug('Reset: running ios real device reset flow');
|
|
61
|
-
if (!opts.noReset) {
|
|
62
|
-
await resetRealDevice(
|
|
58
|
+
export async function runRealDeviceReset() {
|
|
59
|
+
if (!this.opts.noReset || this.opts.fullReset) {
|
|
60
|
+
this.log.debug('Reset: running ios real device reset flow');
|
|
61
|
+
if (!this.opts.noReset) {
|
|
62
|
+
await resetRealDevice.bind(this)();
|
|
63
63
|
}
|
|
64
64
|
} else {
|
|
65
|
-
log.debug('Reset: fullReset not set. Leaving as is');
|
|
65
|
+
this.log.debug('Reset: fullReset not set. Leaving as is');
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -76,28 +76,30 @@ async function runRealDeviceReset(device, opts) {
|
|
|
76
76
|
*/
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* @
|
|
79
|
+
* @this {import('./driver').XCUITestDriver}
|
|
80
80
|
* @param {string} [app] The app to the path
|
|
81
81
|
* @param {string} [bundleId] The bundle id to ensure it is already installed and uninstall it
|
|
82
|
-
* @param {InstallOptions} [opts]
|
|
82
|
+
* @param {InstallOptions} [opts={}]
|
|
83
83
|
*/
|
|
84
|
-
async function installToRealDevice(
|
|
84
|
+
export async function installToRealDevice(app, bundleId, opts = {}) {
|
|
85
|
+
const device = /** @type {RealDevice} */ (this.device);
|
|
86
|
+
|
|
85
87
|
if (!device.udid || !app || !bundleId) {
|
|
86
|
-
log.debug('No device id, app or bundle id, not installing to real device.');
|
|
88
|
+
this.log.debug('No device id, app or bundle id, not installing to real device.');
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
const {skipUninstall, strategy, timeout} = opts
|
|
92
|
+
const {skipUninstall, strategy, timeout} = opts;
|
|
91
93
|
|
|
92
94
|
if (!skipUninstall) {
|
|
93
|
-
log.info(`Reset requested. Removing app with id '${bundleId}' from the device`);
|
|
95
|
+
this.log.info(`Reset requested. Removing app with id '${bundleId}' from the device`);
|
|
94
96
|
await device.remove(bundleId);
|
|
95
97
|
}
|
|
96
|
-
log.debug(`Installing '${app}' on device with UUID '${device.udid}'...`);
|
|
98
|
+
this.log.debug(`Installing '${app}' on device with UUID '${device.udid}'...`);
|
|
97
99
|
|
|
98
100
|
try {
|
|
99
101
|
await device.install(app, timeout, strategy);
|
|
100
|
-
log.debug('The app has been installed successfully.');
|
|
102
|
+
this.log.debug('The app has been installed successfully.');
|
|
101
103
|
} catch (e) {
|
|
102
104
|
// Want to clarify the device's application installation state in this situation.
|
|
103
105
|
|
|
@@ -113,29 +115,20 @@ async function installToRealDevice(device, app, bundleId, opts) {
|
|
|
113
115
|
// If the error was by below error case, we could recover the situation
|
|
114
116
|
// by uninstalling the device's app bundle id explicitly regard less the app exists on the device or not (e.g. offload app).
|
|
115
117
|
// [XCUITest] Error installing app '/path/to.app': Unexpected data: {"Error":"MismatchedApplicationIdentifierEntitlement","ErrorDescription":"Upgrade's application-identifier entitlement string (TEAM_ID.com.kazucocoa.example) does not match installed application's application-identifier string (ANOTHER_TEAM_ID.com.kazucocoa.example); rejecting upgrade."}
|
|
116
|
-
log.info(`The application identified by '${bundleId}' cannot be installed because it might ` +
|
|
118
|
+
this.log.info(`The application identified by '${bundleId}' cannot be installed because it might ` +
|
|
117
119
|
`be already cached on the device, probably with a different signature. ` +
|
|
118
120
|
`Will try to remove it and install a new copy. Original error: ${e.message}`);
|
|
119
121
|
await device.remove(bundleId);
|
|
120
122
|
await device.install(app, timeout, strategy);
|
|
121
|
-
log.debug('The app has been installed after one retrial.');
|
|
123
|
+
this.log.debug('The app has been installed after one retrial.');
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
/**
|
|
126
|
-
* @
|
|
127
|
-
* @param {import('@appium/types').AppiumLogger} logger
|
|
128
|
+
* @this {import('./driver').XCUITestDriver}
|
|
128
129
|
* @returns {RealDevice}
|
|
129
130
|
*/
|
|
130
|
-
function getRealDeviceObj(
|
|
131
|
-
log.debug(`Creating iDevice object with udid '${udid}'`);
|
|
132
|
-
return new RealDevice(udid,
|
|
131
|
+
export function getRealDeviceObj() {
|
|
132
|
+
this.log.debug(`Creating iDevice object with udid '${this.opts.udid}'`);
|
|
133
|
+
return new RealDevice(this.opts.udid, this.log);
|
|
133
134
|
}
|
|
134
|
-
|
|
135
|
-
export {
|
|
136
|
-
getConnectedDevices,
|
|
137
|
-
getOSVersion,
|
|
138
|
-
runRealDeviceReset,
|
|
139
|
-
installToRealDevice,
|
|
140
|
-
getRealDeviceObj,
|
|
141
|
-
};
|