appium-ios-simulator 8.1.2 → 8.2.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 (90) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/extensions/applications.d.ts.map +1 -1
  3. package/build/lib/extensions/applications.js +2 -3
  4. package/build/lib/extensions/applications.js.map +1 -1
  5. package/build/lib/extensions/biometric.js +2 -2
  6. package/build/lib/extensions/biometric.js.map +1 -1
  7. package/build/lib/extensions/keychain.d.ts.map +1 -1
  8. package/build/lib/extensions/keychain.js +5 -9
  9. package/build/lib/extensions/keychain.js.map +1 -1
  10. package/build/lib/extensions/permissions.js +2 -2
  11. package/build/lib/extensions/permissions.js.map +1 -1
  12. package/build/lib/extensions/settings.d.ts.map +1 -1
  13. package/build/lib/extensions/settings.js +10 -11
  14. package/build/lib/extensions/settings.js.map +1 -1
  15. package/build/lib/simulator-xcode-14.d.ts +2 -0
  16. package/build/lib/simulator-xcode-14.d.ts.map +1 -1
  17. package/build/lib/simulator-xcode-14.js +19 -22
  18. package/build/lib/simulator-xcode-14.js.map +1 -1
  19. package/build/lib/simulator-xcode-15.d.ts.map +1 -1
  20. package/build/lib/simulator-xcode-15.js +2 -16
  21. package/build/lib/simulator-xcode-15.js.map +1 -1
  22. package/build/lib/simulator-xcode-27.d.ts +6 -0
  23. package/build/lib/simulator-xcode-27.d.ts.map +1 -0
  24. package/build/lib/simulator-xcode-27.js +13 -0
  25. package/build/lib/simulator-xcode-27.js.map +1 -0
  26. package/build/lib/simulator.d.ts.map +1 -1
  27. package/build/lib/simulator.js +9 -8
  28. package/build/lib/simulator.js.map +1 -1
  29. package/build/lib/utils/constants.d.ts +7 -0
  30. package/build/lib/utils/constants.d.ts.map +1 -0
  31. package/build/lib/utils/constants.js +10 -0
  32. package/build/lib/utils/constants.js.map +1 -0
  33. package/build/lib/{defaults-utils.d.ts → utils/defaults.d.ts} +1 -1
  34. package/build/lib/utils/defaults.d.ts.map +1 -0
  35. package/build/lib/{defaults-utils.js → utils/defaults.js} +8 -8
  36. package/build/lib/utils/defaults.js.map +1 -0
  37. package/build/lib/utils/devices.d.ts +13 -0
  38. package/build/lib/utils/devices.d.ts.map +1 -0
  39. package/build/lib/utils/devices.js +24 -0
  40. package/build/lib/utils/devices.js.map +1 -0
  41. package/build/lib/utils/get-devices.d.ts +7 -0
  42. package/build/lib/utils/get-devices.d.ts.map +1 -0
  43. package/build/lib/utils/get-devices.js +12 -0
  44. package/build/lib/utils/get-devices.js.map +1 -0
  45. package/build/lib/utils/index.d.ts +9 -0
  46. package/build/lib/utils/index.d.ts.map +1 -0
  47. package/build/lib/utils/index.js +29 -0
  48. package/build/lib/utils/index.js.map +1 -0
  49. package/build/lib/utils/lifecycle.d.ts +6 -0
  50. package/build/lib/utils/lifecycle.d.ts.map +1 -0
  51. package/build/lib/utils/lifecycle.js +66 -0
  52. package/build/lib/utils/lifecycle.js.map +1 -0
  53. package/build/lib/utils/process.d.ts +11 -0
  54. package/build/lib/utils/process.d.ts.map +1 -0
  55. package/build/lib/utils/process.js +36 -0
  56. package/build/lib/utils/process.js.map +1 -0
  57. package/build/lib/utils/types.d.ts +4 -0
  58. package/build/lib/utils/types.d.ts.map +1 -0
  59. package/build/lib/utils/types.js +3 -0
  60. package/build/lib/utils/types.js.map +1 -0
  61. package/build/lib/utils/xcode.d.ts +27 -0
  62. package/build/lib/utils/xcode.d.ts.map +1 -0
  63. package/build/lib/utils/xcode.js +80 -0
  64. package/build/lib/utils/xcode.js.map +1 -0
  65. package/lib/extensions/applications.ts +8 -4
  66. package/lib/extensions/biometric.ts +2 -2
  67. package/lib/extensions/keychain.ts +6 -6
  68. package/lib/extensions/permissions.ts +2 -0
  69. package/lib/extensions/settings.ts +7 -8
  70. package/lib/simulator-xcode-14.ts +27 -22
  71. package/lib/simulator-xcode-15.ts +4 -15
  72. package/lib/simulator-xcode-27.ts +9 -0
  73. package/lib/simulator.ts +14 -10
  74. package/lib/utils/constants.ts +6 -0
  75. package/lib/{defaults-utils.ts → utils/defaults.ts} +7 -5
  76. package/lib/utils/devices.ts +25 -0
  77. package/lib/utils/get-devices.ts +10 -0
  78. package/lib/utils/index.ts +20 -0
  79. package/lib/utils/lifecycle.ts +78 -0
  80. package/lib/utils/process.ts +31 -0
  81. package/lib/utils/types.ts +3 -0
  82. package/lib/utils/xcode.ts +86 -0
  83. package/package.json +6 -2
  84. package/build/lib/defaults-utils.d.ts.map +0 -1
  85. package/build/lib/defaults-utils.js.map +0 -1
  86. package/build/lib/utils.d.ts +0 -52
  87. package/build/lib/utils.d.ts.map +0 -1
  88. package/build/lib/utils.js +0 -227
  89. package/build/lib/utils.js.map +0 -1
  90. package/lib/utils.ts +0 -205
@@ -0,0 +1,86 @@
1
+ import {fs} from '@appium/support';
2
+ import {exec} from 'teen_process';
3
+ import path from 'node:path';
4
+ import type {XcodeVersion} from 'appium-xcode';
5
+ import {MIN_DEVICE_HUB_XCODE_VERSION, MIN_SUPPORTED_XCODE_VERSION} from './constants';
6
+
7
+ /**
8
+ * @returns Promise that resolves to the developer root path.
9
+ */
10
+ export async function getDeveloperRoot(): Promise<string> {
11
+ const {stdout} = await exec('xcode-select', ['-p']);
12
+ return stdout.trim();
13
+ }
14
+
15
+ /**
16
+ * @param bundleId - The bundle identifier of the Simulator UI client.
17
+ * @param xcodeVersion - The active Xcode version.
18
+ * @returns The full path to the UI client app in the active Xcode installation.
19
+ * @throws {Error} If no matching app is found in the active Xcode folder.
20
+ */
21
+ export async function getUiClientAppPath(
22
+ bundleId: string,
23
+ xcodeVersion: XcodeVersion,
24
+ ): Promise<string> {
25
+ const devRoot = await getDeveloperRoot();
26
+ const applicationsDir =
27
+ xcodeVersion.major >= MIN_DEVICE_HUB_XCODE_VERSION
28
+ ? path.resolve(devRoot, '..', 'Applications')
29
+ : path.resolve(devRoot, 'Applications');
30
+
31
+ if (await fs.exists(applicationsDir)) {
32
+ const appPaths = (await fs.readdir(applicationsDir))
33
+ .filter((entry) => entry.endsWith('.app'))
34
+ .map((entry) => path.resolve(applicationsDir, entry));
35
+ const apps = await Promise.all(
36
+ appPaths.map(async (appPath) => ({
37
+ appPath,
38
+ bundleId: await readBundleIdFromPlist(path.resolve(appPath, 'Contents', 'Info.plist')),
39
+ })),
40
+ );
41
+ const match = apps.find((app) => app.bundleId === bundleId);
42
+ if (match) {
43
+ return match.appPath;
44
+ }
45
+ }
46
+
47
+ throw new Error(
48
+ `Could not find UI client app with bundle id '${bundleId}' under '${applicationsDir}' ` +
49
+ `(active Xcode developer root: ${devRoot})`,
50
+ );
51
+ }
52
+
53
+ /**
54
+ * Asserts that the Xcode version meets the minimum supported version requirement.
55
+ *
56
+ * @template V - The Xcode version type.
57
+ * @param xcodeVersion - The Xcode version to check.
58
+ * @returns The same Xcode version if it meets the requirement.
59
+ * @throws {Error} If the Xcode version is below the minimum supported version.
60
+ */
61
+ export function assertXcodeVersion<V extends XcodeVersion>(xcodeVersion: V): V {
62
+ if (xcodeVersion.major < MIN_SUPPORTED_XCODE_VERSION) {
63
+ throw new Error(
64
+ `Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` +
65
+ `${MIN_SUPPORTED_XCODE_VERSION} and up are supported`,
66
+ );
67
+ }
68
+ return xcodeVersion;
69
+ }
70
+
71
+ /**
72
+ * @param infoPlistPath - The full path to an Info.plist file.
73
+ * @returns The bundle identifier or null if it cannot be read.
74
+ */
75
+ export async function readBundleIdFromPlist(infoPlistPath: string): Promise<string | null> {
76
+ try {
77
+ const {stdout} = await exec('/usr/libexec/PlistBuddy', [
78
+ '-c',
79
+ 'print CFBundleIdentifier',
80
+ infoPlistPath,
81
+ ]);
82
+ return stdout.trim() || null;
83
+ } catch {
84
+ return null;
85
+ }
86
+ }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "ios",
8
8
  "simctl"
9
9
  ],
10
- "version": "8.1.2",
10
+ "version": "8.2.0",
11
11
  "author": "Appium Contributors",
12
12
  "license": "Apache-2.0",
13
13
  "repository": {
@@ -32,7 +32,7 @@
32
32
  "CHANGELOG.md"
33
33
  ],
34
34
  "dependencies": {
35
- "@appium/support": "^7.0.0-rc.1",
35
+ "@appium/support": "^7.2.2",
36
36
  "@xmldom/xmldom": "^0.x",
37
37
  "appium-xcode": "^6.0.0",
38
38
  "async-lock": "^1.0.0",
@@ -66,8 +66,12 @@
66
66
  "@colors/colors": "^1.5.0",
67
67
  "@semantic-release/changelog": "^6.0.1",
68
68
  "@semantic-release/git": "^10.0.1",
69
+ "@types/async-lock": "^1.4.2",
70
+ "@types/chai": "^5.2.3",
71
+ "@types/chai-as-promised": "^8.0.2",
69
72
  "@types/mocha": "^10.0.1",
70
73
  "@types/node": "^25.0.0",
74
+ "@types/sinon": "^21.0.1",
71
75
  "chai": "^6.0.0",
72
76
  "chai-as-promised": "^8.0.2",
73
77
  "conventional-changelog-conventionalcommits": "^9.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults-utils.d.ts","sourceRoot":"","sources":["../../lib/defaults-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,OAAO,EAAC,MAAM,gBAAgB,CAAC;AAKrF,qBAAa,cAAc;IACzB,KAAK,EAAE,MAAM,CAAC;gBAEF,KAAK,EAAE,MAAM;IAIzB;;;;;;OAMG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAW5C;;;;;;;;;;OAUG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAmB5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,GAAE,OAAc,GAAG,MAAM,GAAG,OAAO,CA0ChF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,OAAO,GAAE,OAAe,GACvB,MAAM,EAAE,EAAE,CA4BZ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults-utils.js","sourceRoot":"","sources":["../../lib/defaults-utils.ts"],"names":[],"mappings":"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"}
@@ -1,52 +0,0 @@
1
- import type { XcodeVersion } from 'appium-xcode';
2
- import type { StringRecord } from '@appium/types';
3
- export declare const SAFARI_STARTUP_TIMEOUT_MS: number;
4
- export declare const MOBILE_SAFARI_BUNDLE_ID = "com.apple.mobilesafari";
5
- export declare const SIMULATOR_APP_NAME = "Simulator.app";
6
- export declare const MIN_SUPPORTED_XCODE_VERSION = 14;
7
- export interface SimulatorInfoOptions {
8
- devicesSetPath?: string | null;
9
- }
10
- /**
11
- * @param timeout - Timeout in milliseconds (default: DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS).
12
- * @returns Promise that resolves when all simulators are killed.
13
- */
14
- export declare function killAllSimulators(timeout?: number): Promise<void>;
15
- /**
16
- * @param udid - The simulator UDID.
17
- * @param opts - Options including devicesSetPath.
18
- * @returns Promise that resolves to simulator info or undefined if not found.
19
- */
20
- export declare function getSimulatorInfo(udid: string, opts?: SimulatorInfoOptions): Promise<any>;
21
- /**
22
- * @param udid - The simulator UDID.
23
- * @returns Promise that resolves to true if simulator exists, false otherwise.
24
- */
25
- export declare function simExists(udid: string): Promise<boolean>;
26
- /**
27
- * @returns Promise that resolves to the developer root path.
28
- */
29
- export declare function getDeveloperRoot(): Promise<string>;
30
- /**
31
- * Asserts that the Xcode version meets the minimum supported version requirement.
32
- *
33
- * @template V - The Xcode version type.
34
- * @param xcodeVersion - The Xcode version to check.
35
- * @returns The same Xcode version if it meets the requirement.
36
- * @throws {Error} If the Xcode version is below the minimum supported version.
37
- */
38
- export declare function assertXcodeVersion<V extends XcodeVersion>(xcodeVersion: V): V;
39
- /**
40
- * @param simctlOpts - Optional simctl options
41
- * @returns Promise that resolves to a record of devices grouped by SDK version
42
- */
43
- export declare function getDevices(simctlOpts?: StringRecord): Promise<Record<string, any[]>>;
44
- /**
45
- * Checks whether the given value is a plain object.
46
- */
47
- export declare function isPlainObject(value: unknown): value is Record<string, any>;
48
- /**
49
- * Escapes regexp control characters in a string.
50
- */
51
- export declare function escapeRegExp(value: string): string;
52
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAG/C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,eAAe,CAAC;AAKhD,eAAO,MAAM,yBAAyB,QAAY,CAAC;AACnD,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,MAAwC,GAChD,OAAO,CAAC,IAAI,CAAC,CA6Ef;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,GAAG,CAAC,CAKd;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGxD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,YAAY,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAQ7E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAE1F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAM1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD"}
@@ -1,227 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.MIN_SUPPORTED_XCODE_VERSION = exports.SIMULATOR_APP_NAME = exports.MOBILE_SAFARI_BUNDLE_ID = exports.SAFARI_STARTUP_TIMEOUT_MS = void 0;
40
- exports.killAllSimulators = killAllSimulators;
41
- exports.getSimulatorInfo = getSimulatorInfo;
42
- exports.simExists = simExists;
43
- exports.getDeveloperRoot = getDeveloperRoot;
44
- exports.assertXcodeVersion = assertXcodeVersion;
45
- exports.getDevices = getDevices;
46
- exports.isPlainObject = isPlainObject;
47
- exports.escapeRegExp = escapeRegExp;
48
- const logger_1 = require("./logger");
49
- const teen_process_1 = require("teen_process");
50
- const asyncbox_1 = require("asyncbox");
51
- const appium_xcode_1 = require("appium-xcode");
52
- const node_path_1 = __importDefault(require("node:path"));
53
- const node_simctl_1 = require("node-simctl");
54
- // it's a hack needed to stub getDevices in tests
55
- const utilsModule = __importStar(require("./utils"));
56
- const DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS = 30000;
57
- exports.SAFARI_STARTUP_TIMEOUT_MS = 25 * 1000;
58
- exports.MOBILE_SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
59
- exports.SIMULATOR_APP_NAME = 'Simulator.app';
60
- exports.MIN_SUPPORTED_XCODE_VERSION = 14;
61
- /**
62
- * @param timeout - Timeout in milliseconds (default: DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS).
63
- * @returns Promise that resolves when all simulators are killed.
64
- */
65
- async function killAllSimulators(timeout = DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS) {
66
- logger_1.log.debug('Killing all iOS Simulators');
67
- const xcodeVersion = await (0, appium_xcode_1.getVersion)(true);
68
- if (typeof xcodeVersion === 'string') {
69
- return;
70
- }
71
- const appName = node_path_1.default.parse(exports.SIMULATOR_APP_NAME).name;
72
- const version = xcodeVersion;
73
- // later versions are slower to close
74
- timeout = timeout * (version.major >= 8 ? 2 : 1);
75
- try {
76
- await (0, teen_process_1.exec)('xcrun', ['simctl', 'shutdown', version.major > 8 ? 'all' : 'booted'], { timeout });
77
- }
78
- catch { }
79
- const pids = [];
80
- try {
81
- const { stdout } = await (0, teen_process_1.exec)('pgrep', ['-f', `${appName}.app/Contents/MacOS/`]);
82
- if (stdout.trim()) {
83
- pids.push(...stdout.trim().split(/\s+/));
84
- }
85
- }
86
- catch (e) {
87
- if (e.code === 1) {
88
- logger_1.log.debug(`${appName} is not running. Continuing...`);
89
- return;
90
- }
91
- if (pids.length === 0) {
92
- logger_1.log.warn(`pgrep error ${e.code} while detecting whether ${appName} is running. Trying to kill anyway.`);
93
- }
94
- }
95
- if (pids.length > 0) {
96
- logger_1.log.debug(`Killing processes: ${pids.join(', ')}`);
97
- try {
98
- await (0, teen_process_1.exec)('kill', ['-9', ...pids.map((pid) => `${pid}`)]);
99
- }
100
- catch { }
101
- }
102
- logger_1.log.debug(`Using pkill to kill application: ${appName}`);
103
- try {
104
- await pkill(appName, true);
105
- }
106
- catch { }
107
- // wait for all the devices to be shutdown before Continuing
108
- // but only print out the failed ones when they are actually fully failed
109
- let remainingDevices = [];
110
- async function allSimsAreDown() {
111
- remainingDevices = [];
112
- const devicesRecord = await utilsModule.getDevices();
113
- const devices = Object.values(devicesRecord).flat();
114
- return devices.every((sim) => {
115
- const state = sim.state.toLowerCase();
116
- const done = ['shutdown', 'unavailable', 'disconnected'].includes(state);
117
- if (!done) {
118
- remainingDevices.push(`${sim.name} (${sim.sdk}, udid: ${sim.udid}) is still in state '${state}'`);
119
- }
120
- return done;
121
- });
122
- }
123
- try {
124
- await (0, asyncbox_1.waitForCondition)(allSimsAreDown, {
125
- waitMs: timeout,
126
- intervalMs: 200,
127
- });
128
- }
129
- catch (err) {
130
- if (remainingDevices.length > 0) {
131
- logger_1.log.warn(`The following devices are still not in the correct state after ${timeout} ms:`);
132
- for (const device of remainingDevices) {
133
- logger_1.log.warn(` ${device}`);
134
- }
135
- }
136
- throw err;
137
- }
138
- }
139
- /**
140
- * @param udid - The simulator UDID.
141
- * @param opts - Options including devicesSetPath.
142
- * @returns Promise that resolves to simulator info or undefined if not found.
143
- */
144
- async function getSimulatorInfo(udid, opts = {}) {
145
- const { devicesSetPath } = opts;
146
- // see the README for github.com/appium/node-simctl for example output of getDevices()
147
- const devices = Object.values(await utilsModule.getDevices({ devicesSetPath })).flat();
148
- return devices.find((sim) => sim.udid === udid);
149
- }
150
- /**
151
- * @param udid - The simulator UDID.
152
- * @returns Promise that resolves to true if simulator exists, false otherwise.
153
- */
154
- async function simExists(udid) {
155
- return !!(await getSimulatorInfo(udid));
156
- }
157
- /**
158
- * @returns Promise that resolves to the developer root path.
159
- */
160
- async function getDeveloperRoot() {
161
- const { stdout } = await (0, teen_process_1.exec)('xcode-select', ['-p']);
162
- return stdout.trim();
163
- }
164
- /**
165
- * Asserts that the Xcode version meets the minimum supported version requirement.
166
- *
167
- * @template V - The Xcode version type.
168
- * @param xcodeVersion - The Xcode version to check.
169
- * @returns The same Xcode version if it meets the requirement.
170
- * @throws {Error} If the Xcode version is below the minimum supported version.
171
- */
172
- function assertXcodeVersion(xcodeVersion) {
173
- if (xcodeVersion.major < exports.MIN_SUPPORTED_XCODE_VERSION) {
174
- throw new Error(`Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` +
175
- `${exports.MIN_SUPPORTED_XCODE_VERSION} and up are supported`);
176
- }
177
- return xcodeVersion;
178
- }
179
- /**
180
- * @param simctlOpts - Optional simctl options
181
- * @returns Promise that resolves to a record of devices grouped by SDK version
182
- */
183
- async function getDevices(simctlOpts) {
184
- return await new node_simctl_1.Simctl(simctlOpts).getDevices();
185
- }
186
- /**
187
- * Checks whether the given value is a plain object.
188
- */
189
- function isPlainObject(value) {
190
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
191
- return false;
192
- }
193
- const proto = Object.getPrototypeOf(value);
194
- return proto === null || proto === Object.prototype;
195
- }
196
- /**
197
- * Escapes regexp control characters in a string.
198
- */
199
- function escapeRegExp(value) {
200
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
201
- }
202
- /**
203
- * @param appName - The application name to kill.
204
- * @param forceKill - Whether to force kill the process.
205
- * @returns Promise that resolves to 0 on success.
206
- */
207
- async function pkill(appName, forceKill = false) {
208
- const args = forceKill ? ['-9'] : [];
209
- args.push('-x', appName);
210
- try {
211
- await (0, teen_process_1.exec)('pkill', args);
212
- return 0;
213
- }
214
- catch (err) {
215
- // pgrep/pkill exit codes:
216
- // 0 One or more processes were matched.
217
- // 1 No processes were matched.
218
- // 2 Invalid options were specified on the command line.
219
- // 3 An internal error occurred.
220
- if (err.code !== undefined) {
221
- throw new Error(`Cannot forcefully terminate ${appName}. pkill error code: ${err.code}`);
222
- }
223
- logger_1.log.error(`Received unexpected error while trying to kill ${appName}: ${err.message}`);
224
- throw err;
225
- }
226
- }
227
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,8CA+EC;AAOD,4CAQC;AAMD,8BAEC;AAKD,4CAGC;AAUD,gDAQC;AAMD,gCAEC;AAKD,sCAMC;AAKD,oCAEC;AAnLD,qCAA6B;AAC7B,+CAAkC;AAClC,uCAA0C;AAC1C,+CAAwC;AAExC,0DAA6B;AAC7B,6CAAmC;AAEnC,iDAAiD;AACjD,qDAAuC;AAEvC,MAAM,+BAA+B,GAAG,KAAK,CAAC;AACjC,QAAA,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AACtC,QAAA,uBAAuB,GAAG,wBAAwB,CAAC;AACnD,QAAA,kBAAkB,GAAG,eAAe,CAAC;AACrC,QAAA,2BAA2B,GAAG,EAAE,CAAC;AAM9C;;;GAGG;AACI,KAAK,UAAU,iBAAiB,CACrC,UAAkB,+BAA+B;IAEjD,YAAG,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,MAAM,IAAA,yBAAU,EAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,mBAAI,CAAC,KAAK,CAAC,0BAAkB,CAAC,CAAC,IAAI,CAAC;IACpD,MAAM,OAAO,GAAG,YAA4B,CAAC;IAE7C,qCAAqC;IACrC,OAAO,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,IAAA,mBAAI,EAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAC,OAAO,EAAC,CAAC,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAA,mBAAI,EAAC,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,OAAO,sBAAsB,CAAC,CAAC,CAAC;QAC/E,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACjB,YAAG,CAAC,KAAK,CAAC,GAAG,OAAO,gCAAgC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,YAAG,CAAC,IAAI,CACN,eAAe,CAAC,CAAC,IAAI,4BAA4B,OAAO,qCAAqC,CAC9F,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,YAAG,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,IAAA,mBAAI,EAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,YAAG,CAAC,KAAK,CAAC,oCAAoC,OAAO,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,4DAA4D;IAC5D,yEAAyE;IACzE,IAAI,gBAAgB,GAAa,EAAE,CAAC;IACpC,KAAK,UAAU,cAAc;QAC3B,gBAAgB,GAAG,EAAE,CAAC;QACtB,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;YAChC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzE,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,gBAAgB,CAAC,IAAI,CACnB,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,IAAI,wBAAwB,KAAK,GAAG,CAC3E,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAA,2BAAgB,EAAC,cAAc,EAAE;YACrC,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,YAAG,CAAC,IAAI,CAAC,kEAAkE,OAAO,MAAM,CAAC,CAAC;YAC1F,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBACtC,YAAG,CAAC,IAAI,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,OAA6B,EAAE;IAE/B,MAAM,EAAC,cAAc,EAAC,GAAG,IAAI,CAAC;IAC9B,sFAAsF;IACtF,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,WAAW,CAAC,UAAU,CAAC,EAAC,cAAc,EAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,OAAO,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB;IACpC,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,IAAA,mBAAI,EAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAyB,YAAe;IACxE,IAAI,YAAY,CAAC,KAAK,GAAG,mCAA2B,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,oDAAoD,YAAY,CAAC,aAAa,0BAA0B;YACtG,GAAG,mCAA2B,uBAAuB,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,UAAU,CAAC,UAAyB;IACxD,OAAO,MAAM,IAAI,oBAAM,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,KAAK,CAAC,OAAe,EAAE,YAAqB,KAAK;IAC9D,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,IAAA,mBAAI,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,0BAA0B;QAC1B,8CAA8C;QAC9C,qCAAqC;QACrC,8DAA8D;QAC9D,sCAAsC;QACtC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,uBAAuB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,YAAG,CAAC,KAAK,CAAC,kDAAkD,OAAO,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvF,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
package/lib/utils.ts DELETED
@@ -1,205 +0,0 @@
1
- import {log} from './logger';
2
- import {exec} from 'teen_process';
3
- import {waitForCondition} from 'asyncbox';
4
- import {getVersion} from 'appium-xcode';
5
- import type {XcodeVersion} from 'appium-xcode';
6
- import path from 'node:path';
7
- import {Simctl} from 'node-simctl';
8
- import type {StringRecord} from '@appium/types';
9
- // it's a hack needed to stub getDevices in tests
10
- import * as utilsModule from './utils';
11
-
12
- const DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS = 30000;
13
- export const SAFARI_STARTUP_TIMEOUT_MS = 25 * 1000;
14
- export const MOBILE_SAFARI_BUNDLE_ID = 'com.apple.mobilesafari';
15
- export const SIMULATOR_APP_NAME = 'Simulator.app';
16
- export const MIN_SUPPORTED_XCODE_VERSION = 14;
17
-
18
- export interface SimulatorInfoOptions {
19
- devicesSetPath?: string | null;
20
- }
21
-
22
- /**
23
- * @param timeout - Timeout in milliseconds (default: DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS).
24
- * @returns Promise that resolves when all simulators are killed.
25
- */
26
- export async function killAllSimulators(
27
- timeout: number = DEFAULT_SIM_SHUTDOWN_TIMEOUT_MS,
28
- ): Promise<void> {
29
- log.debug('Killing all iOS Simulators');
30
- const xcodeVersion = await getVersion(true);
31
- if (typeof xcodeVersion === 'string') {
32
- return;
33
- }
34
- const appName = path.parse(SIMULATOR_APP_NAME).name;
35
- const version = xcodeVersion as XcodeVersion;
36
-
37
- // later versions are slower to close
38
- timeout = timeout * (version.major >= 8 ? 2 : 1);
39
-
40
- try {
41
- await exec('xcrun', ['simctl', 'shutdown', version.major > 8 ? 'all' : 'booted'], {timeout});
42
- } catch {}
43
-
44
- const pids: string[] = [];
45
- try {
46
- const {stdout} = await exec('pgrep', ['-f', `${appName}.app/Contents/MacOS/`]);
47
- if (stdout.trim()) {
48
- pids.push(...stdout.trim().split(/\s+/));
49
- }
50
- } catch (e: any) {
51
- if (e.code === 1) {
52
- log.debug(`${appName} is not running. Continuing...`);
53
- return;
54
- }
55
- if (pids.length === 0) {
56
- log.warn(
57
- `pgrep error ${e.code} while detecting whether ${appName} is running. Trying to kill anyway.`,
58
- );
59
- }
60
- }
61
- if (pids.length > 0) {
62
- log.debug(`Killing processes: ${pids.join(', ')}`);
63
- try {
64
- await exec('kill', ['-9', ...pids.map((pid) => `${pid}`)]);
65
- } catch {}
66
- }
67
-
68
- log.debug(`Using pkill to kill application: ${appName}`);
69
- try {
70
- await pkill(appName, true);
71
- } catch {}
72
-
73
- // wait for all the devices to be shutdown before Continuing
74
- // but only print out the failed ones when they are actually fully failed
75
- let remainingDevices: string[] = [];
76
- async function allSimsAreDown(): Promise<boolean> {
77
- remainingDevices = [];
78
- const devicesRecord = await utilsModule.getDevices();
79
- const devices = Object.values(devicesRecord).flat();
80
- return devices.every((sim: any) => {
81
- const state = sim.state.toLowerCase();
82
- const done = ['shutdown', 'unavailable', 'disconnected'].includes(state);
83
- if (!done) {
84
- remainingDevices.push(
85
- `${sim.name} (${sim.sdk}, udid: ${sim.udid}) is still in state '${state}'`,
86
- );
87
- }
88
- return done;
89
- });
90
- }
91
- try {
92
- await waitForCondition(allSimsAreDown, {
93
- waitMs: timeout,
94
- intervalMs: 200,
95
- });
96
- } catch (err) {
97
- if (remainingDevices.length > 0) {
98
- log.warn(`The following devices are still not in the correct state after ${timeout} ms:`);
99
- for (const device of remainingDevices) {
100
- log.warn(` ${device}`);
101
- }
102
- }
103
- throw err;
104
- }
105
- }
106
-
107
- /**
108
- * @param udid - The simulator UDID.
109
- * @param opts - Options including devicesSetPath.
110
- * @returns Promise that resolves to simulator info or undefined if not found.
111
- */
112
- export async function getSimulatorInfo(
113
- udid: string,
114
- opts: SimulatorInfoOptions = {},
115
- ): Promise<any> {
116
- const {devicesSetPath} = opts;
117
- // see the README for github.com/appium/node-simctl for example output of getDevices()
118
- const devices = Object.values(await utilsModule.getDevices({devicesSetPath})).flat();
119
- return devices.find((sim: any) => sim.udid === udid);
120
- }
121
-
122
- /**
123
- * @param udid - The simulator UDID.
124
- * @returns Promise that resolves to true if simulator exists, false otherwise.
125
- */
126
- export async function simExists(udid: string): Promise<boolean> {
127
- return !!(await getSimulatorInfo(udid));
128
- }
129
-
130
- /**
131
- * @returns Promise that resolves to the developer root path.
132
- */
133
- export async function getDeveloperRoot(): Promise<string> {
134
- const {stdout} = await exec('xcode-select', ['-p']);
135
- return stdout.trim();
136
- }
137
-
138
- /**
139
- * Asserts that the Xcode version meets the minimum supported version requirement.
140
- *
141
- * @template V - The Xcode version type.
142
- * @param xcodeVersion - The Xcode version to check.
143
- * @returns The same Xcode version if it meets the requirement.
144
- * @throws {Error} If the Xcode version is below the minimum supported version.
145
- */
146
- export function assertXcodeVersion<V extends XcodeVersion>(xcodeVersion: V): V {
147
- if (xcodeVersion.major < MIN_SUPPORTED_XCODE_VERSION) {
148
- throw new Error(
149
- `Tried to use an iOS simulator with xcode version ${xcodeVersion.versionString} but only Xcode version ` +
150
- `${MIN_SUPPORTED_XCODE_VERSION} and up are supported`,
151
- );
152
- }
153
- return xcodeVersion;
154
- }
155
-
156
- /**
157
- * @param simctlOpts - Optional simctl options
158
- * @returns Promise that resolves to a record of devices grouped by SDK version
159
- */
160
- export async function getDevices(simctlOpts?: StringRecord): Promise<Record<string, any[]>> {
161
- return await new Simctl(simctlOpts).getDevices();
162
- }
163
-
164
- /**
165
- * Checks whether the given value is a plain object.
166
- */
167
- export function isPlainObject(value: unknown): value is Record<string, any> {
168
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
169
- return false;
170
- }
171
- const proto = Object.getPrototypeOf(value);
172
- return proto === null || proto === Object.prototype;
173
- }
174
-
175
- /**
176
- * Escapes regexp control characters in a string.
177
- */
178
- export function escapeRegExp(value: string): string {
179
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
180
- }
181
-
182
- /**
183
- * @param appName - The application name to kill.
184
- * @param forceKill - Whether to force kill the process.
185
- * @returns Promise that resolves to 0 on success.
186
- */
187
- async function pkill(appName: string, forceKill: boolean = false): Promise<number> {
188
- const args = forceKill ? ['-9'] : [];
189
- args.push('-x', appName);
190
- try {
191
- await exec('pkill', args);
192
- return 0;
193
- } catch (err: any) {
194
- // pgrep/pkill exit codes:
195
- // 0 One or more processes were matched.
196
- // 1 No processes were matched.
197
- // 2 Invalid options were specified on the command line.
198
- // 3 An internal error occurred.
199
- if (err.code !== undefined) {
200
- throw new Error(`Cannot forcefully terminate ${appName}. pkill error code: ${err.code}`);
201
- }
202
- log.error(`Received unexpected error while trying to kill ${appName}: ${err.message}`);
203
- throw err;
204
- }
205
- }