appium-ios-simulator 8.0.11 → 8.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/lib/defaults-utils.d.ts +1 -0
- package/build/lib/defaults-utils.d.ts.map +1 -1
- package/build/lib/defaults-utils.js +15 -7
- package/build/lib/defaults-utils.js.map +1 -1
- package/build/lib/extensions/applications.d.ts.map +1 -1
- package/build/lib/extensions/applications.js +2 -2
- package/build/lib/extensions/applications.js.map +1 -1
- package/build/lib/extensions/biometric.d.ts.map +1 -1
- package/build/lib/extensions/biometric.js +9 -13
- package/build/lib/extensions/biometric.js.map +1 -1
- package/build/lib/extensions/geolocation.d.ts.map +1 -1
- package/build/lib/extensions/geolocation.js.map +1 -1
- package/build/lib/extensions/keychain.d.ts.map +1 -1
- package/build/lib/extensions/keychain.js +14 -11
- package/build/lib/extensions/keychain.js.map +1 -1
- package/build/lib/extensions/misc.d.ts.map +1 -1
- package/build/lib/extensions/misc.js +2 -5
- package/build/lib/extensions/misc.js.map +1 -1
- package/build/lib/extensions/permissions.d.ts.map +1 -1
- package/build/lib/extensions/permissions.js +19 -11
- package/build/lib/extensions/permissions.js.map +1 -1
- package/build/lib/extensions/safari.d.ts.map +1 -1
- package/build/lib/extensions/safari.js +1 -1
- package/build/lib/extensions/safari.js.map +1 -1
- package/build/lib/extensions/settings.d.ts +2 -2
- package/build/lib/extensions/settings.d.ts.map +1 -1
- package/build/lib/extensions/settings.js +31 -30
- package/build/lib/extensions/settings.js.map +1 -1
- package/build/lib/index.d.ts +5 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/{index.js → lib/index.js} +2 -3
- package/build/lib/index.js.map +1 -0
- package/build/lib/logger.js.map +1 -1
- package/build/lib/simulator-xcode-14.d.ts.map +1 -1
- package/build/lib/simulator-xcode-14.js +7 -8
- package/build/lib/simulator-xcode-14.js.map +1 -1
- package/build/lib/simulator-xcode-15.d.ts.map +1 -1
- package/build/lib/simulator-xcode-15.js +4 -2
- package/build/lib/simulator-xcode-15.js.map +1 -1
- package/build/lib/simulator.d.ts.map +1 -1
- package/build/lib/simulator.js +3 -3
- package/build/lib/simulator.js.map +1 -1
- package/build/lib/types.d.ts.map +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +3 -3
- package/build/lib/utils.js.map +1 -1
- package/lib/defaults-utils.ts +32 -15
- package/lib/extensions/applications.ts +30 -24
- package/lib/extensions/biometric.ts +27 -21
- package/lib/extensions/geolocation.ts +6 -3
- package/lib/extensions/keychain.ts +22 -18
- package/lib/extensions/misc.ts +9 -12
- package/lib/extensions/permissions.ts +93 -52
- package/lib/extensions/safari.ts +61 -32
- package/lib/extensions/settings.ts +153 -81
- package/lib/index.ts +6 -0
- package/lib/logger.ts +1 -1
- package/lib/simulator-xcode-14.ts +65 -45
- package/lib/simulator-xcode-15.ts +7 -6
- package/lib/simulator.ts +13 -17
- package/lib/types.ts +14 -14
- package/lib/utils.ts +25 -18
- package/package.json +6 -6
- package/build/index.d.ts +0 -5
- package/build/index.d.ts.map +0 -1
- package/build/index.js.map +0 -1
- package/index.ts +0 -8
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import {fs, timing, util} from '@appium/support';
|
|
2
|
+
import {waitForCondition, retryInterval} from 'asyncbox';
|
|
3
|
+
import {getDeveloperRoot, SIMULATOR_APP_NAME} from './utils';
|
|
4
|
+
import {exec} from 'teen_process';
|
|
5
|
+
import {log as defaultLog} from './logger';
|
|
6
6
|
import EventEmitter from 'node:events';
|
|
7
7
|
import AsyncLock from 'async-lock';
|
|
8
8
|
import _ from 'lodash';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import B from 'bluebird';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import {getPath as getXcodePath} from 'appium-xcode';
|
|
12
|
+
import {Simctl} from 'node-simctl';
|
|
13
13
|
import * as appExtensions from './extensions/applications';
|
|
14
14
|
import * as biometricExtensions from './extensions/biometric';
|
|
15
15
|
import * as safariExtensions from './extensions/safari';
|
|
@@ -34,23 +34,26 @@ import type {
|
|
|
34
34
|
KillUiClientOptions,
|
|
35
35
|
ProcessInfo,
|
|
36
36
|
} from './types';
|
|
37
|
-
import type {
|
|
38
|
-
import type {
|
|
37
|
+
import type {XcodeVersion} from 'appium-xcode';
|
|
38
|
+
import type {AppiumLogger, StringRecord} from '@appium/types';
|
|
39
39
|
|
|
40
40
|
const SIMULATOR_SHUTDOWN_TIMEOUT = 15 * 1000;
|
|
41
41
|
const STARTUP_LOCK = new AsyncLock();
|
|
42
42
|
const UI_CLIENT_BUNDLE_ID = 'com.apple.iphonesimulator';
|
|
43
43
|
const STARTUP_TIMEOUT_MS = 120 * 1000;
|
|
44
44
|
|
|
45
|
-
export class SimulatorXcode14
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
export class SimulatorXcode14
|
|
46
|
+
extends EventEmitter
|
|
47
|
+
implements
|
|
48
|
+
CoreSimulator,
|
|
49
|
+
HasSettings,
|
|
50
|
+
InteractsWithApps,
|
|
51
|
+
InteractsWithKeychain,
|
|
52
|
+
SupportsGeolocation,
|
|
53
|
+
HasMiscFeatures,
|
|
54
|
+
InteractsWithSafariBrowser,
|
|
55
|
+
SupportsBiometric
|
|
56
|
+
{
|
|
54
57
|
_keychainsBackupPath: string | null | undefined;
|
|
55
58
|
_platformVersion: string | null | undefined;
|
|
56
59
|
_webInspectorSocket: string | null | undefined;
|
|
@@ -410,8 +413,11 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
410
413
|
try {
|
|
411
414
|
await exec('open', args, {timeout: opts.startupTimeout});
|
|
412
415
|
} catch (err: any) {
|
|
413
|
-
throw new Error(
|
|
414
|
-
|
|
416
|
+
throw new Error(
|
|
417
|
+
`Got an unexpected error while opening Simulator UI: ` + err.stderr ||
|
|
418
|
+
err.stdout ||
|
|
419
|
+
err.message,
|
|
420
|
+
);
|
|
415
421
|
}
|
|
416
422
|
}
|
|
417
423
|
|
|
@@ -428,7 +434,8 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
428
434
|
startupTimeout: this.startupTimeout,
|
|
429
435
|
});
|
|
430
436
|
|
|
431
|
-
const [devicePreferences, commonPreferences] =
|
|
437
|
+
const [devicePreferences, commonPreferences] =
|
|
438
|
+
settingsExtensions.compileSimulatorPreferences.bind(this)(opts);
|
|
432
439
|
await settingsExtensions.updatePreferences.bind(this)(devicePreferences, commonPreferences);
|
|
433
440
|
|
|
434
441
|
const timer = new timing.Timer().start();
|
|
@@ -441,7 +448,9 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
441
448
|
return false;
|
|
442
449
|
}
|
|
443
450
|
if (await this.killUIClient({pid: uiClientPid})) {
|
|
444
|
-
this.log.info(
|
|
451
|
+
this.log.info(
|
|
452
|
+
`Detected the Simulator UI client was running and killed it. Verifying the current Simulator state`,
|
|
453
|
+
);
|
|
445
454
|
}
|
|
446
455
|
try {
|
|
447
456
|
// Stopping the UI client kills all running servers for some early XCode versions. This is a known bug
|
|
@@ -450,22 +459,30 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
450
459
|
intervalMs: 100,
|
|
451
460
|
});
|
|
452
461
|
} catch {
|
|
453
|
-
if (!await this.isRunning()) {
|
|
454
|
-
throw new Error(
|
|
462
|
+
if (!(await this.isRunning())) {
|
|
463
|
+
throw new Error(
|
|
464
|
+
`Simulator with UDID '${this.udid}' cannot be transitioned to headless mode`,
|
|
465
|
+
);
|
|
455
466
|
}
|
|
456
467
|
return false;
|
|
457
468
|
}
|
|
458
|
-
this.log.info(
|
|
459
|
-
`
|
|
469
|
+
this.log.info(
|
|
470
|
+
`Booting Simulator with UDID '${this.udid}' in headless mode. ` +
|
|
471
|
+
`All UI-related capabilities are going to be ignored`,
|
|
472
|
+
);
|
|
460
473
|
await this.boot();
|
|
461
474
|
} else {
|
|
462
475
|
if (isServerRunning && uiClientPid) {
|
|
463
|
-
this.log.info(
|
|
476
|
+
this.log.info(
|
|
477
|
+
`Both Simulator with UDID '${this.udid}' and the UI client are currently running`,
|
|
478
|
+
);
|
|
464
479
|
return false;
|
|
465
480
|
}
|
|
466
481
|
if (isServerRunning) {
|
|
467
|
-
this.log.info(
|
|
468
|
-
`
|
|
482
|
+
this.log.info(
|
|
483
|
+
`Simulator '${this.udid}' is booted while its UI is not visible. ` +
|
|
484
|
+
`Trying to restart it with the Simulator window visible`,
|
|
485
|
+
);
|
|
469
486
|
await this.shutdown({timeout: SIMULATOR_SHUTDOWN_TIMEOUT});
|
|
470
487
|
}
|
|
471
488
|
await this.launchWindow(Boolean(uiClientPid), opts);
|
|
@@ -475,14 +492,18 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
475
492
|
|
|
476
493
|
if (shouldWaitForBoot && opts.startupTimeout) {
|
|
477
494
|
await this.waitForBoot(opts.startupTimeout);
|
|
478
|
-
this.log.info(
|
|
495
|
+
this.log.info(
|
|
496
|
+
`Simulator with UDID ${this.udid} booted in ${timer.getDuration().asSeconds.toFixed(3)}s`,
|
|
497
|
+
);
|
|
479
498
|
}
|
|
480
499
|
|
|
481
500
|
(async () => {
|
|
482
501
|
try {
|
|
483
502
|
await this.disableKeyboardIntroduction();
|
|
484
503
|
} catch (e: any) {
|
|
485
|
-
this.log.info(
|
|
504
|
+
this.log.info(
|
|
505
|
+
`Cannot disable Simulator keyboard introduction. Original error: ${e.message}`,
|
|
506
|
+
);
|
|
486
507
|
}
|
|
487
508
|
})();
|
|
488
509
|
}
|
|
@@ -496,11 +517,8 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
496
517
|
* @throws {Error} If sending the signal to the client process fails.
|
|
497
518
|
*/
|
|
498
519
|
async killUIClient(opts: KillUiClientOptions = {}): Promise<boolean> {
|
|
499
|
-
const {
|
|
500
|
-
|
|
501
|
-
signal = 2,
|
|
502
|
-
} = opts;
|
|
503
|
-
const clientPid = pid || await this.getUIClientPid();
|
|
520
|
+
const {pid, signal = 2} = opts;
|
|
521
|
+
const clientPid = pid || (await this.getUIClientPid());
|
|
504
522
|
if (!clientPid) {
|
|
505
523
|
return false;
|
|
506
524
|
}
|
|
@@ -526,9 +544,7 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
526
544
|
* @throws {Error} If no process information could be retrieved.
|
|
527
545
|
*/
|
|
528
546
|
async ps(): Promise<ProcessInfo[]> {
|
|
529
|
-
const {stdout} = await this.simctl.spawnProcess([
|
|
530
|
-
'launchctl', 'list'
|
|
531
|
-
]);
|
|
547
|
+
const {stdout} = await this.simctl.spawnProcess(['launchctl', 'list']);
|
|
532
548
|
/*
|
|
533
549
|
Example match:
|
|
534
550
|
PID Status Label
|
|
@@ -540,7 +556,8 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
540
556
|
- 0 com.apple.DragUI.druid
|
|
541
557
|
22076 0 UIKitApplication:com.apple.mobilesafari[2b0f][rb-legacy]
|
|
542
558
|
*/
|
|
543
|
-
const extractGroup = (lbl: string): string | null =>
|
|
559
|
+
const extractGroup = (lbl: string): string | null =>
|
|
560
|
+
lbl.includes(':') ? lbl.split(':')[0] : null;
|
|
544
561
|
const extractName = (lbl: string): string => {
|
|
545
562
|
let res = lbl;
|
|
546
563
|
const colonIdx = res.indexOf(':');
|
|
@@ -561,7 +578,7 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
561
578
|
continue;
|
|
562
579
|
}
|
|
563
580
|
|
|
564
|
-
const [pidStr
|
|
581
|
+
const [pidStr, , label] = trimmedLine.split(/\s+/);
|
|
565
582
|
const pid = parseInt(pidStr, 10);
|
|
566
583
|
if (!pid || !label) {
|
|
567
584
|
continue;
|
|
@@ -596,7 +613,7 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
596
613
|
'RuntimeRoot',
|
|
597
614
|
'System',
|
|
598
615
|
'Library',
|
|
599
|
-
'LaunchDaemons'
|
|
616
|
+
'LaunchDaemons',
|
|
600
617
|
);
|
|
601
618
|
}
|
|
602
619
|
|
|
@@ -613,14 +630,18 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
613
630
|
openUrl = safariExtensions.openUrl;
|
|
614
631
|
scrubSafari = safariExtensions.scrubSafari;
|
|
615
632
|
updateSafariSettings = safariExtensions.updateSafariSettings;
|
|
616
|
-
getWebInspectorSocket = safariExtensions.getWebInspectorSocket as unknown as () => Promise<
|
|
633
|
+
getWebInspectorSocket = safariExtensions.getWebInspectorSocket as unknown as () => Promise<
|
|
634
|
+
string | null
|
|
635
|
+
>;
|
|
617
636
|
|
|
618
637
|
isBiometricEnrolled = biometricExtensions.isBiometricEnrolled;
|
|
619
638
|
enrollBiometric = biometricExtensions.enrollBiometric;
|
|
620
639
|
sendBiometricMatch = biometricExtensions.sendBiometricMatch;
|
|
621
640
|
|
|
622
641
|
backupKeychains = keychainExtensions.backupKeychains as unknown as () => Promise<boolean>;
|
|
623
|
-
restoreKeychains = keychainExtensions.restoreKeychains as unknown as (
|
|
642
|
+
restoreKeychains = keychainExtensions.restoreKeychains as unknown as (
|
|
643
|
+
excludePatterns: string[],
|
|
644
|
+
) => Promise<boolean>;
|
|
624
645
|
clearKeychains = keychainExtensions.clearKeychains;
|
|
625
646
|
|
|
626
647
|
setGeolocation = geolocationExtensions.setGeolocation;
|
|
@@ -646,4 +667,3 @@ export class SimulatorXcode14 extends EventEmitter implements
|
|
|
646
667
|
setReduceTransparency = settingsExtensions.setReduceTransparency;
|
|
647
668
|
disableKeyboardIntroduction = settingsExtensions.disableKeyboardIntroduction;
|
|
648
669
|
}
|
|
649
|
-
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {fs} from '@appium/support';
|
|
2
|
+
import {exec} from 'teen_process';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import _ from 'lodash';
|
|
5
5
|
import B from 'bluebird';
|
|
6
|
-
import {
|
|
6
|
+
import {SimulatorXcode14} from './simulator-xcode-14';
|
|
7
7
|
|
|
8
8
|
export class SimulatorXcode15 extends SimulatorXcode14 {
|
|
9
9
|
private _systemAppBundleIds?: Set<string>;
|
|
@@ -18,7 +18,7 @@ export class SimulatorXcode15 extends SimulatorXcode14 {
|
|
|
18
18
|
isAppInstalled = async (bundleId: string): Promise<boolean> => {
|
|
19
19
|
try {
|
|
20
20
|
const appContainer = await this.simctl.getAppContainer(bundleId);
|
|
21
|
-
return appContainer.endsWith('.app') && await fs.exists(appContainer);
|
|
21
|
+
return appContainer.endsWith('.app') && (await fs.exists(appContainer));
|
|
22
22
|
} catch {
|
|
23
23
|
// get_app_container subcommand fails for system applications,
|
|
24
24
|
// as well as the hidden appinfo command
|
|
@@ -120,7 +120,9 @@ export class SimulatorXcode15 extends SimulatorXcode14 {
|
|
|
120
120
|
const infoPlistPath = path.resolve(appRoot, 'Info.plist');
|
|
121
121
|
try {
|
|
122
122
|
const {stdout} = await exec('/usr/libexec/PlistBuddy', [
|
|
123
|
-
'-c',
|
|
123
|
+
'-c',
|
|
124
|
+
'print CFBundleIdentifier',
|
|
125
|
+
infoPlistPath,
|
|
124
126
|
]);
|
|
125
127
|
return _.trim(stdout);
|
|
126
128
|
} catch {
|
|
@@ -135,4 +137,3 @@ export class SimulatorXcode15 extends SimulatorXcode14 {
|
|
|
135
137
|
return this._systemAppBundleIds;
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
|
-
|
package/lib/simulator.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {SimulatorXcode14} from './simulator-xcode-14';
|
|
2
|
+
import {SimulatorXcode15} from './simulator-xcode-15';
|
|
3
|
+
import {getSimulatorInfo, assertXcodeVersion, MIN_SUPPORTED_XCODE_VERSION} from './utils';
|
|
4
4
|
import * as xcode from 'appium-xcode';
|
|
5
|
-
import {
|
|
6
|
-
import type {
|
|
5
|
+
import {log} from './logger';
|
|
6
|
+
import type {Simulator, SimulatorLookupOptions} from './types';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Finds and returns the corresponding Simulator instance for the given ID.
|
|
@@ -15,20 +15,17 @@ import type { Simulator, SimulatorLookupOptions } from './types';
|
|
|
15
15
|
* [node-simctl](github.com/appium/node-simctl).
|
|
16
16
|
* @return Simulator object associated with the udid passed in.
|
|
17
17
|
*/
|
|
18
|
-
export async function getSimulator(
|
|
18
|
+
export async function getSimulator(
|
|
19
|
+
udid: string,
|
|
20
|
+
opts: SimulatorLookupOptions = {},
|
|
21
|
+
): Promise<Simulator> {
|
|
19
22
|
let platform = opts.platform ?? 'iOS';
|
|
20
|
-
const {
|
|
21
|
-
checkExistence = true,
|
|
22
|
-
devicesSetPath,
|
|
23
|
-
logger,
|
|
24
|
-
} = opts;
|
|
23
|
+
const {checkExistence = true, devicesSetPath, logger} = opts;
|
|
25
24
|
|
|
26
|
-
const xcodeVersion = assertXcodeVersion(
|
|
27
|
-
await xcode.getVersion(true) as xcode.XcodeVersion
|
|
28
|
-
);
|
|
25
|
+
const xcodeVersion = assertXcodeVersion((await xcode.getVersion(true)) as xcode.XcodeVersion);
|
|
29
26
|
if (checkExistence) {
|
|
30
27
|
const simulatorInfo = await getSimulatorInfo(udid, {
|
|
31
|
-
devicesSetPath
|
|
28
|
+
devicesSetPath,
|
|
32
29
|
});
|
|
33
30
|
|
|
34
31
|
if (!simulatorInfo) {
|
|
@@ -39,7 +36,7 @@ export async function getSimulator(udid: string, opts: SimulatorLookupOptions =
|
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
(logger ?? log).info(
|
|
42
|
-
`Constructing ${platform} simulator for Xcode version ${xcodeVersion.versionString} with udid '${udid}'
|
|
39
|
+
`Constructing ${platform} simulator for Xcode version ${xcodeVersion.versionString} with udid '${udid}'`,
|
|
43
40
|
);
|
|
44
41
|
let SimClass: typeof SimulatorXcode14 | typeof SimulatorXcode15;
|
|
45
42
|
switch (xcodeVersion.major) {
|
|
@@ -58,4 +55,3 @@ export async function getSimulator(udid: string, opts: SimulatorLookupOptions =
|
|
|
58
55
|
}
|
|
59
56
|
return result;
|
|
60
57
|
}
|
|
61
|
-
|
package/lib/types.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
1
|
+
import type {EventEmitter} from 'node:events';
|
|
2
|
+
import type {Simctl} from 'node-simctl';
|
|
3
|
+
import type {XcodeVersion} from 'appium-xcode';
|
|
4
|
+
import type {AppiumLogger, StringRecord} from '@appium/types';
|
|
5
5
|
|
|
6
6
|
export interface ProcessInfo {
|
|
7
7
|
/**
|
|
@@ -288,13 +288,13 @@ export interface SimulatorLookupOptions {
|
|
|
288
288
|
logger?: AppiumLogger;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
export type Simulator = CoreSimulator
|
|
292
|
-
&
|
|
293
|
-
&
|
|
294
|
-
&
|
|
295
|
-
&
|
|
296
|
-
&
|
|
297
|
-
&
|
|
298
|
-
&
|
|
299
|
-
&
|
|
300
|
-
|
|
291
|
+
export type Simulator = CoreSimulator &
|
|
292
|
+
InteractsWithSafariBrowser &
|
|
293
|
+
InteractsWithApps &
|
|
294
|
+
HasSettings &
|
|
295
|
+
InteractsWithApps &
|
|
296
|
+
SupportsBiometric &
|
|
297
|
+
SupportsGeolocation &
|
|
298
|
+
InteractsWithKeychain &
|
|
299
|
+
SupportsAppPermissions &
|
|
300
|
+
HasMiscFeatures;
|
package/lib/utils.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {log} from './logger';
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import type {
|
|
3
|
+
import {exec} from 'teen_process';
|
|
4
|
+
import {waitForCondition} from 'asyncbox';
|
|
5
|
+
import {getVersion} from 'appium-xcode';
|
|
6
|
+
import type {XcodeVersion} from 'appium-xcode';
|
|
7
7
|
import path from 'node:path';
|
|
8
|
-
import {
|
|
9
|
-
import type {
|
|
8
|
+
import {Simctl} from 'node-simctl';
|
|
9
|
+
import type {StringRecord} from '@appium/types';
|
|
10
10
|
// it's a hack needed to stub getDevices in tests
|
|
11
11
|
import * as utilsModule from './utils';
|
|
12
12
|
|
|
@@ -45,7 +45,9 @@ async function pkill(appName: string, forceKill: boolean = false): Promise<numbe
|
|
|
45
45
|
* @param timeout - Timeout in milliseconds (default: DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS).
|
|
46
46
|
* @returns Promise that resolves when all simulators are killed.
|
|
47
47
|
*/
|
|
48
|
-
export async function killAllSimulators(
|
|
48
|
+
export async function killAllSimulators(
|
|
49
|
+
timeout: number = DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS,
|
|
50
|
+
): Promise<void> {
|
|
49
51
|
log.debug('Killing all iOS Simulators');
|
|
50
52
|
const xcodeVersion = await getVersion(true);
|
|
51
53
|
if (_.isString(xcodeVersion)) {
|
|
@@ -65,7 +67,7 @@ export async function killAllSimulators(timeout: number = DEFAULT_SIM_SHUTDOWN_T
|
|
|
65
67
|
try {
|
|
66
68
|
const {stdout} = await exec('pgrep', ['-f', `${appName}.app/Contents/MacOS/`]);
|
|
67
69
|
if (stdout.trim()) {
|
|
68
|
-
pids.push(...
|
|
70
|
+
pids.push(...stdout.trim().split(/\s+/));
|
|
69
71
|
}
|
|
70
72
|
} catch (e: any) {
|
|
71
73
|
if (e.code === 1) {
|
|
@@ -73,13 +75,15 @@ export async function killAllSimulators(timeout: number = DEFAULT_SIM_SHUTDOWN_T
|
|
|
73
75
|
return;
|
|
74
76
|
}
|
|
75
77
|
if (_.isEmpty(pids)) {
|
|
76
|
-
log.warn(
|
|
78
|
+
log.warn(
|
|
79
|
+
`pgrep error ${e.code} while detecting whether ${appName} is running. Trying to kill anyway.`,
|
|
80
|
+
);
|
|
77
81
|
}
|
|
78
82
|
}
|
|
79
83
|
if (!_.isEmpty(pids)) {
|
|
80
84
|
log.debug(`Killing processes: ${pids.join(', ')}`);
|
|
81
85
|
try {
|
|
82
|
-
await exec('kill', ['-9', ...
|
|
86
|
+
await exec('kill', ['-9', ...pids.map((pid) => `${pid}`)]);
|
|
83
87
|
} catch {}
|
|
84
88
|
}
|
|
85
89
|
|
|
@@ -99,7 +103,9 @@ export async function killAllSimulators(timeout: number = DEFAULT_SIM_SHUTDOWN_T
|
|
|
99
103
|
const state = sim.state.toLowerCase();
|
|
100
104
|
const done = ['shutdown', 'unavailable', 'disconnected'].includes(state);
|
|
101
105
|
if (!done) {
|
|
102
|
-
remainingDevices.push(
|
|
106
|
+
remainingDevices.push(
|
|
107
|
+
`${sim.name} (${sim.sdk}, udid: ${sim.udid}) is still in state '${state}'`,
|
|
108
|
+
);
|
|
103
109
|
}
|
|
104
110
|
return done;
|
|
105
111
|
});
|
|
@@ -107,7 +113,7 @@ export async function killAllSimulators(timeout: number = DEFAULT_SIM_SHUTDOWN_T
|
|
|
107
113
|
try {
|
|
108
114
|
await waitForCondition(allSimsAreDown, {
|
|
109
115
|
waitMs: timeout,
|
|
110
|
-
intervalMs: 200
|
|
116
|
+
intervalMs: 200,
|
|
111
117
|
});
|
|
112
118
|
} catch (err) {
|
|
113
119
|
if (remainingDevices.length > 0) {
|
|
@@ -129,10 +135,11 @@ export interface SimulatorInfoOptions {
|
|
|
129
135
|
* @param opts - Options including devicesSetPath.
|
|
130
136
|
* @returns Promise that resolves to simulator info or undefined if not found.
|
|
131
137
|
*/
|
|
132
|
-
export async function getSimulatorInfo(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
138
|
+
export async function getSimulatorInfo(
|
|
139
|
+
udid: string,
|
|
140
|
+
opts: SimulatorInfoOptions = {},
|
|
141
|
+
): Promise<any> {
|
|
142
|
+
const {devicesSetPath} = opts;
|
|
136
143
|
// see the README for github.com/appium/node-simctl for example output of getDevices()
|
|
137
144
|
const devices = _.toPairs(await utilsModule.getDevices({devicesSetPath}))
|
|
138
145
|
.map((pair) => pair[1])
|
|
@@ -168,7 +175,7 @@ export function assertXcodeVersion<V extends XcodeVersion>(xcodeVersion: V): V {
|
|
|
168
175
|
if (xcodeVersion.major < MIN_SUPPORTED_XCODE_VERSION) {
|
|
169
176
|
throw new Error(
|
|
170
177
|
`Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` +
|
|
171
|
-
|
|
178
|
+
`${MIN_SUPPORTED_XCODE_VERSION} and up are supported`,
|
|
172
179
|
);
|
|
173
180
|
}
|
|
174
181
|
return xcodeVersion;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"ios",
|
|
8
8
|
"simctl"
|
|
9
9
|
],
|
|
10
|
-
"version": "8.0.
|
|
10
|
+
"version": "8.0.13",
|
|
11
11
|
"author": "Appium Contributors",
|
|
12
12
|
"license": "Apache-2.0",
|
|
13
13
|
"repository": {
|
|
@@ -21,15 +21,13 @@
|
|
|
21
21
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
22
22
|
"npm": ">=10"
|
|
23
23
|
},
|
|
24
|
-
"main": "./build/index.js",
|
|
24
|
+
"main": "./build/lib/index.js",
|
|
25
25
|
"bin": {},
|
|
26
26
|
"directories": {
|
|
27
27
|
"lib": "lib"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
|
-
"index.ts",
|
|
31
30
|
"lib",
|
|
32
|
-
"build/index.*",
|
|
33
31
|
"build/lib",
|
|
34
32
|
"CHANGELOG.md"
|
|
35
33
|
],
|
|
@@ -52,6 +50,8 @@
|
|
|
52
50
|
"dev": "npm run build -- --watch",
|
|
53
51
|
"lint": "eslint .",
|
|
54
52
|
"lint:fix": "npm run lint -- --fix",
|
|
53
|
+
"format": "prettier -w ./lib ./test",
|
|
54
|
+
"format:check": "prettier --check ./lib ./test",
|
|
55
55
|
"prepare": "npm run build",
|
|
56
56
|
"test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.ts\"",
|
|
57
57
|
"e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.ts\""
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"semantic-release": "^25.0.2",
|
|
82
82
|
"sinon": "^21.0.0",
|
|
83
83
|
"ts-node": "^10.9.1",
|
|
84
|
-
"typescript": "^
|
|
84
|
+
"typescript": "^6.0.2"
|
|
85
85
|
},
|
|
86
|
-
"types": "./build/index.d.ts"
|
|
86
|
+
"types": "./build/lib/index.d.ts"
|
|
87
87
|
}
|
package/build/index.d.ts
DELETED
package/build/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC;AAEtD,mBAAmB,aAAa,CAAC"}
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA,iBAAiB;;;AAEjB,+CAA+C;AAGtC,6FAHA,wBAAY,OAGA;AAFrB,uCAA2D;AAEpC,kGAFd,yBAAiB,OAEc;AAAE,0FAFd,iBAAS,OAEc"}
|