node-simctl 8.0.8 → 8.1.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.
- package/CHANGELOG.md +12 -0
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/build/lib/helpers.d.ts +17 -9
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +50 -4
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/logger.d.ts +2 -3
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +3 -5
- package/build/lib/logger.js.map +1 -1
- package/build/lib/simctl.d.ts +82 -188
- package/build/lib/simctl.d.ts.map +1 -1
- package/build/lib/simctl.js +98 -150
- package/build/lib/simctl.js.map +1 -1
- package/build/lib/subcommands/addmedia.d.ts +14 -16
- package/build/lib/subcommands/addmedia.d.ts.map +1 -1
- package/build/lib/subcommands/addmedia.js +5 -7
- package/build/lib/subcommands/addmedia.js.map +1 -1
- package/build/lib/subcommands/appinfo.d.ts +13 -45
- package/build/lib/subcommands/appinfo.d.ts.map +1 -1
- package/build/lib/subcommands/appinfo.js +31 -42
- package/build/lib/subcommands/appinfo.js.map +1 -1
- package/build/lib/subcommands/boot.d.ts +9 -12
- package/build/lib/subcommands/boot.d.ts.map +1 -1
- package/build/lib/subcommands/boot.js +5 -40
- package/build/lib/subcommands/boot.js.map +1 -1
- package/build/lib/subcommands/bootstatus.d.ts +16 -56
- package/build/lib/subcommands/bootstatus.d.ts.map +1 -1
- package/build/lib/subcommands/bootstatus.js +8 -22
- package/build/lib/subcommands/bootstatus.js.map +1 -1
- package/build/lib/subcommands/create.d.ts +15 -34
- package/build/lib/subcommands/create.d.ts.map +1 -1
- package/build/lib/subcommands/create.js +23 -66
- package/build/lib/subcommands/create.js.map +1 -1
- package/build/lib/subcommands/delete.d.ts +9 -12
- package/build/lib/subcommands/delete.d.ts.map +1 -1
- package/build/lib/subcommands/delete.js +3 -5
- package/build/lib/subcommands/delete.js.map +1 -1
- package/build/lib/subcommands/erase.d.ts +12 -15
- package/build/lib/subcommands/erase.d.ts.map +1 -1
- package/build/lib/subcommands/erase.js +4 -6
- package/build/lib/subcommands/erase.js.map +1 -1
- package/build/lib/subcommands/get_app_container.d.ts +19 -22
- package/build/lib/subcommands/get_app_container.d.ts.map +1 -1
- package/build/lib/subcommands/get_app_container.js +6 -8
- package/build/lib/subcommands/get_app_container.js.map +1 -1
- package/build/lib/subcommands/getenv.d.ts +11 -14
- package/build/lib/subcommands/getenv.d.ts.map +1 -1
- package/build/lib/subcommands/getenv.js +5 -7
- package/build/lib/subcommands/getenv.js.map +1 -1
- package/build/lib/subcommands/install.d.ts +12 -15
- package/build/lib/subcommands/install.d.ts.map +1 -1
- package/build/lib/subcommands/install.js +4 -6
- package/build/lib/subcommands/install.js.map +1 -1
- package/build/lib/subcommands/io.d.ts +12 -15
- package/build/lib/subcommands/io.d.ts.map +1 -1
- package/build/lib/subcommands/io.js +4 -6
- package/build/lib/subcommands/io.js.map +1 -1
- package/build/lib/subcommands/keychain.d.ts +37 -55
- package/build/lib/subcommands/keychain.d.ts.map +1 -1
- package/build/lib/subcommands/keychain.js +16 -25
- package/build/lib/subcommands/keychain.js.map +1 -1
- package/build/lib/subcommands/launch.d.ts +16 -19
- package/build/lib/subcommands/launch.d.ts.map +1 -1
- package/build/lib/subcommands/launch.js +9 -11
- package/build/lib/subcommands/launch.js.map +1 -1
- package/build/lib/subcommands/list.d.ts +94 -125
- package/build/lib/subcommands/list.d.ts.map +1 -1
- package/build/lib/subcommands/list.js +34 -92
- package/build/lib/subcommands/list.js.map +1 -1
- package/build/lib/subcommands/location.d.ts +18 -22
- package/build/lib/subcommands/location.d.ts.map +1 -1
- package/build/lib/subcommands/location.js +11 -13
- package/build/lib/subcommands/location.js.map +1 -1
- package/build/lib/subcommands/openurl.d.ts +15 -17
- package/build/lib/subcommands/openurl.d.ts.map +1 -1
- package/build/lib/subcommands/openurl.js +5 -7
- package/build/lib/subcommands/openurl.js.map +1 -1
- package/build/lib/subcommands/pbcopy.d.ts +14 -17
- package/build/lib/subcommands/pbcopy.d.ts.map +1 -1
- package/build/lib/subcommands/pbcopy.js +5 -7
- package/build/lib/subcommands/pbcopy.js.map +1 -1
- package/build/lib/subcommands/pbpaste.d.ts +14 -17
- package/build/lib/subcommands/pbpaste.d.ts.map +1 -1
- package/build/lib/subcommands/pbpaste.js +5 -7
- package/build/lib/subcommands/pbpaste.js.map +1 -1
- package/build/lib/subcommands/privacy.d.ts +52 -57
- package/build/lib/subcommands/privacy.d.ts.map +1 -1
- package/build/lib/subcommands/privacy.js +15 -17
- package/build/lib/subcommands/privacy.js.map +1 -1
- package/build/lib/subcommands/push.d.ts +22 -25
- package/build/lib/subcommands/push.d.ts.map +1 -1
- package/build/lib/subcommands/push.js +5 -7
- package/build/lib/subcommands/push.js.map +1 -1
- package/build/lib/subcommands/shutdown.d.ts +9 -12
- package/build/lib/subcommands/shutdown.d.ts.map +1 -1
- package/build/lib/subcommands/shutdown.js +5 -40
- package/build/lib/subcommands/shutdown.js.map +1 -1
- package/build/lib/subcommands/spawn.d.ts +24 -27
- package/build/lib/subcommands/spawn.d.ts.map +1 -1
- package/build/lib/subcommands/spawn.js +12 -14
- package/build/lib/subcommands/spawn.js.map +1 -1
- package/build/lib/subcommands/terminate.d.ts +12 -15
- package/build/lib/subcommands/terminate.d.ts.map +1 -1
- package/build/lib/subcommands/terminate.js +4 -6
- package/build/lib/subcommands/terminate.js.map +1 -1
- package/build/lib/subcommands/ui.d.ts +97 -105
- package/build/lib/subcommands/ui.d.ts.map +1 -1
- package/build/lib/subcommands/ui.js +24 -26
- package/build/lib/subcommands/ui.js.map +1 -1
- package/build/lib/subcommands/uninstall.d.ts +13 -16
- package/build/lib/subcommands/uninstall.d.ts.map +1 -1
- package/build/lib/subcommands/uninstall.js +4 -6
- package/build/lib/subcommands/uninstall.js.map +1 -1
- package/build/lib/types.d.ts +231 -0
- package/build/lib/types.d.ts.map +1 -0
- package/build/lib/types.js +3 -0
- package/build/lib/types.js.map +1 -0
- package/index.ts +13 -0
- package/lib/helpers.ts +81 -0
- package/lib/{logger.js → logger.ts} +2 -5
- package/lib/simctl.ts +221 -0
- package/lib/subcommands/{addmedia.js → addmedia.ts} +6 -8
- package/lib/subcommands/appinfo.ts +39 -0
- package/lib/subcommands/{boot.js → boot.ts} +5 -10
- package/lib/subcommands/bootstatus.ts +108 -0
- package/lib/subcommands/{create.js → create.ts} +29 -35
- package/lib/subcommands/{delete.js → delete.ts} +3 -5
- package/lib/subcommands/{erase.js → erase.ts} +4 -7
- package/lib/subcommands/{get_app_container.js → get_app_container.ts} +10 -8
- package/lib/subcommands/{getenv.js → getenv.ts} +5 -7
- package/lib/subcommands/{install.js → install.ts} +4 -6
- package/lib/subcommands/{io.js → io.ts} +4 -7
- package/lib/subcommands/{keychain.js → keychain.ts} +30 -32
- package/lib/subcommands/{launch.js → launch.ts} +9 -12
- package/lib/subcommands/{list.js → list.ts} +67 -60
- package/lib/subcommands/{location.js → location.ts} +15 -14
- package/lib/subcommands/{openurl.js → openurl.ts} +6 -7
- package/lib/subcommands/{pbcopy.js → pbcopy.ts} +11 -8
- package/lib/subcommands/{pbpaste.js → pbpaste.ts} +5 -7
- package/lib/subcommands/{privacy.js → privacy.ts} +13 -17
- package/lib/subcommands/{push.js → push.ts} +5 -8
- package/lib/subcommands/{shutdown.js → shutdown.ts} +5 -8
- package/lib/subcommands/{spawn.js → spawn.ts} +21 -17
- package/lib/subcommands/{terminate.js → terminate.ts} +4 -6
- package/lib/subcommands/{ui.js → ui.ts} +19 -28
- package/lib/subcommands/{uninstall.js → uninstall.ts} +4 -6
- package/lib/types.ts +243 -0
- package/package.json +3 -3
- package/index.js +0 -4
- package/lib/helpers.js +0 -37
- package/lib/simctl.js +0 -299
- package/lib/subcommands/appinfo.js +0 -51
- package/lib/subcommands/bootstatus.js +0 -119
package/index.js
DELETED
package/lib/helpers.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as semver from 'semver';
|
|
2
|
-
|
|
3
|
-
export const DEFAULT_EXEC_TIMEOUT = 10 * 60 * 1000; // ms
|
|
4
|
-
export const SIM_RUNTIME_NAME = 'com.apple.CoreSimulator.SimRuntime.';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* "Normalize" the version, since iOS uses 'major.minor' but the runtimes can
|
|
8
|
-
* be 'major.minor.patch'
|
|
9
|
-
*
|
|
10
|
-
* @param {string} version - the string version
|
|
11
|
-
* @return {string} The version in 'major.minor' form
|
|
12
|
-
* @throws {Error} If the version not parseable by the `semver` package
|
|
13
|
-
*/
|
|
14
|
-
export function normalizeVersion (version) {
|
|
15
|
-
const semverVersion = semver.coerce(version);
|
|
16
|
-
if (!semverVersion) {
|
|
17
|
-
throw new Error(`Unable to parse version '${version}'`);
|
|
18
|
-
}
|
|
19
|
-
return `${semverVersion.major}.${semverVersion.minor}`;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @returns {string}
|
|
24
|
-
*/
|
|
25
|
-
export function getXcrunBinary () {
|
|
26
|
-
return process.env.XCRUN_BINARY || 'xcrun';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Generate a UUID v4
|
|
31
|
-
*
|
|
32
|
-
* @returns {Promise<string>}
|
|
33
|
-
*/
|
|
34
|
-
export async function uuidV4 () {
|
|
35
|
-
const uuidLib = await import('uuid');
|
|
36
|
-
return uuidLib.v4();
|
|
37
|
-
}
|
package/lib/simctl.js
DELETED
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import which from 'which';
|
|
3
|
-
import log, { LOG_PREFIX } from './logger';
|
|
4
|
-
import {
|
|
5
|
-
DEFAULT_EXEC_TIMEOUT, getXcrunBinary,
|
|
6
|
-
} from './helpers';
|
|
7
|
-
import { exec as tpExec, SubProcess } from 'teen_process';
|
|
8
|
-
import addmediaCommands from './subcommands/addmedia';
|
|
9
|
-
import appinfoCommands from './subcommands/appinfo';
|
|
10
|
-
import bootCommands from './subcommands/boot';
|
|
11
|
-
import bootstatusCommands from './subcommands/bootstatus';
|
|
12
|
-
import createCommands from './subcommands/create';
|
|
13
|
-
import deleteCommands from './subcommands/delete';
|
|
14
|
-
import eraseCommands from './subcommands/erase';
|
|
15
|
-
import getappcontainerCommands from './subcommands/get_app_container';
|
|
16
|
-
import installCommands from './subcommands/install';
|
|
17
|
-
import ioCommands from './subcommands/io';
|
|
18
|
-
import keychainCommands from './subcommands/keychain';
|
|
19
|
-
import launchCommands from './subcommands/launch';
|
|
20
|
-
import listCommands from './subcommands/list';
|
|
21
|
-
import openurlCommands from './subcommands/openurl';
|
|
22
|
-
import pbcopyCommands from './subcommands/pbcopy';
|
|
23
|
-
import pbpasteCommands from './subcommands/pbpaste';
|
|
24
|
-
import privacyCommands from './subcommands/privacy';
|
|
25
|
-
import pushCommands from './subcommands/push';
|
|
26
|
-
import envCommands from './subcommands/getenv';
|
|
27
|
-
import shutdownCommands from './subcommands/shutdown';
|
|
28
|
-
import spawnCommands from './subcommands/spawn';
|
|
29
|
-
import terminateCommands from './subcommands/terminate';
|
|
30
|
-
import uiCommands from './subcommands/ui';
|
|
31
|
-
import uninstallCommands from './subcommands/uninstall';
|
|
32
|
-
import locationCommands from './subcommands/location';
|
|
33
|
-
|
|
34
|
-
const SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_';
|
|
35
|
-
const DEFAULT_OPTS = {
|
|
36
|
-
xcrun: {
|
|
37
|
-
path: null,
|
|
38
|
-
},
|
|
39
|
-
execTimeout: DEFAULT_EXEC_TIMEOUT,
|
|
40
|
-
logErrors: true,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {Object} XCRun
|
|
45
|
-
* @property {string?} path Full path to the xcrun script
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @typedef {{asynchronous: true}} TAsyncOpts
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* @typedef {Object} ExecOpts
|
|
54
|
-
* @property {string[]} [args=[]] - The list of additional subcommand arguments.
|
|
55
|
-
* It's empty by default.
|
|
56
|
-
* @property {Record<string, any>} [env={}] - Environment variables mapping. All these variables
|
|
57
|
-
* will be passed Simulator and used in the executing function.
|
|
58
|
-
* @property {boolean} [logErrors=true] - Set it to _false_ to throw execution errors
|
|
59
|
-
* immediately without logging any additional information.
|
|
60
|
-
* @property {boolean} [asynchronous=false] - Whether to execute the given command
|
|
61
|
-
* 'synchronously' or 'asynchronously'. Affects the returned result of the function.
|
|
62
|
-
* @property {string} [encoding] - Explicitly sets streams encoding for the executed
|
|
63
|
-
* command input and outputs.
|
|
64
|
-
* @property {string|string[]} [architectures] - One or more architecture names to be enforced while
|
|
65
|
-
* executing xcrun. See https://github.com/appium/appium/issues/18966 for more details.
|
|
66
|
-
* @property {number} [timeout] - The maximum number of milliseconds
|
|
67
|
-
* to wait for single synchronous xcrun command. If not provided explicitly, then
|
|
68
|
-
* the value of execTimeout property is used by default.
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @typedef {Object} SimctlOpts
|
|
73
|
-
* @property {XCRun} [xcrun] - The xcrun properties. Currently only one property
|
|
74
|
-
* is supported, which is `path` and it by default contains `null`, which enforces
|
|
75
|
-
* the instance to automatically detect the full path to `xcrun` tool and to throw
|
|
76
|
-
* an exception if it cannot be detected. If the path is set upon instance creation
|
|
77
|
-
* then it is going to be used by `exec` and no autodetection will happen.
|
|
78
|
-
* @property {number} [execTimeout=600000] - The default maximum number of milliseconds
|
|
79
|
-
* to wait for single synchronous xcrun command.
|
|
80
|
-
* @property {boolean} [logErrors=true] - Whether to wire xcrun error messages
|
|
81
|
-
* into debug log before throwing them.
|
|
82
|
-
* @property {string?} [udid] - The unique identifier of the current device, which is
|
|
83
|
-
* going to be implicitly passed to all methods, which require it. It can either be set
|
|
84
|
-
* upon instance creation if it is already known in advance or later when/if needed via the
|
|
85
|
-
* corresponding instance setter.
|
|
86
|
-
* @property {string?} [devicesSetPath] - Full path to the set of devices that you want to manage.
|
|
87
|
-
* By default this path usually equals to ~/Library/Developer/CoreSimulator/Devices
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class Simctl {
|
|
92
|
-
/** @type {XCRun} */
|
|
93
|
-
xcrun;
|
|
94
|
-
|
|
95
|
-
/** @type {number} */
|
|
96
|
-
execTimeout;
|
|
97
|
-
|
|
98
|
-
/** @type {boolean} */
|
|
99
|
-
logErrors;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @param {SimctlOpts} [opts={}]
|
|
103
|
-
*/
|
|
104
|
-
constructor (opts = {}) {
|
|
105
|
-
opts = _.cloneDeep(opts);
|
|
106
|
-
_.defaultsDeep(opts, DEFAULT_OPTS);
|
|
107
|
-
for (const key of _.keys(DEFAULT_OPTS)) {
|
|
108
|
-
this[key] = opts[key];
|
|
109
|
-
}
|
|
110
|
-
/** @type {string?} */
|
|
111
|
-
this._udid = _.isNil(opts.udid) ? null : opts.udid;
|
|
112
|
-
/** @type {string?} */
|
|
113
|
-
this._devicesSetPath = _.isNil(opts.devicesSetPath) ? null : opts.devicesSetPath;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
set udid (value) {
|
|
117
|
-
this._udid = value;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
get udid () {
|
|
121
|
-
return this._udid;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
set devicesSetPath (value) {
|
|
125
|
-
this._devicesSetPath = value;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
get devicesSetPath () {
|
|
129
|
-
return this._devicesSetPath;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @param {string?} [commandName=null]
|
|
134
|
-
* @returns {string}
|
|
135
|
-
*/
|
|
136
|
-
requireUdid (commandName = null) {
|
|
137
|
-
if (!this.udid) {
|
|
138
|
-
throw new Error(`udid is required to be set for ` +
|
|
139
|
-
(commandName ? `the '${commandName}' command` : 'this simctl command'));
|
|
140
|
-
}
|
|
141
|
-
return this.udid;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @returns {Promise<string>}
|
|
146
|
-
*/
|
|
147
|
-
async requireXcrun () {
|
|
148
|
-
const xcrunBinary = getXcrunBinary();
|
|
149
|
-
|
|
150
|
-
if (!this.xcrun.path) {
|
|
151
|
-
try {
|
|
152
|
-
this.xcrun.path = await which(xcrunBinary);
|
|
153
|
-
} catch {
|
|
154
|
-
throw new Error(`${xcrunBinary} tool has not been found in PATH. ` +
|
|
155
|
-
`Are Xcode developers tools installed?`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return /** @type {string} */ (this.xcrun.path);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Execute the particular simctl command.
|
|
163
|
-
*
|
|
164
|
-
* @template {ExecOpts} TExecOpts
|
|
165
|
-
* @param {string} subcommand - One of available simctl subcommands.
|
|
166
|
-
* Execute `xcrun simctl` in Terminal to see the full list of available subcommands.
|
|
167
|
-
* @param {TExecOpts} [opts]
|
|
168
|
-
* @return {Promise<TExecOpts extends TAsyncOpts ? import('teen_process').SubProcess : import('teen_process').TeenProcessExecResult>}
|
|
169
|
-
* Either the result of teen process's `exec` or
|
|
170
|
-
* `SubProcess` instance depending of `opts.asynchronous` value.
|
|
171
|
-
* @throws {Error} If the simctl subcommand command returns non-zero return code.
|
|
172
|
-
*/
|
|
173
|
-
async exec (subcommand, opts) {
|
|
174
|
-
let {
|
|
175
|
-
args = [],
|
|
176
|
-
env = {},
|
|
177
|
-
asynchronous = false,
|
|
178
|
-
encoding,
|
|
179
|
-
logErrors = true,
|
|
180
|
-
architectures,
|
|
181
|
-
timeout,
|
|
182
|
-
} = opts ?? {};
|
|
183
|
-
// run a particular simctl command
|
|
184
|
-
args = [
|
|
185
|
-
'simctl',
|
|
186
|
-
...(this.devicesSetPath ? ['--set', this.devicesSetPath] : []),
|
|
187
|
-
subcommand,
|
|
188
|
-
...args
|
|
189
|
-
];
|
|
190
|
-
// Prefix all passed in environment variables with 'SIMCTL_CHILD_', simctl
|
|
191
|
-
// will then pass these to the child (spawned) process.
|
|
192
|
-
env = _.defaults(
|
|
193
|
-
_.mapKeys(env,
|
|
194
|
-
(value, key) => _.startsWith(key, SIMCTL_ENV_PREFIX) ? key : `${SIMCTL_ENV_PREFIX}${key}`),
|
|
195
|
-
process.env
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
const execOpts = {
|
|
199
|
-
env,
|
|
200
|
-
encoding,
|
|
201
|
-
};
|
|
202
|
-
if (!asynchronous) {
|
|
203
|
-
execOpts.timeout = timeout || this.execTimeout;
|
|
204
|
-
}
|
|
205
|
-
const xcrun = await this.requireXcrun();
|
|
206
|
-
try {
|
|
207
|
-
let execArgs = [xcrun, args, execOpts];
|
|
208
|
-
if (architectures?.length) {
|
|
209
|
-
const archArgs = _.flatMap(
|
|
210
|
-
(_.isArray(architectures) ? architectures : [architectures]).map((arch) => ['-arch', arch])
|
|
211
|
-
);
|
|
212
|
-
execArgs = ['arch', [...archArgs, xcrun, ...args], execOpts];
|
|
213
|
-
}
|
|
214
|
-
// @ts-ignore We know what we are doing here
|
|
215
|
-
return asynchronous ? new SubProcess(...execArgs) : await tpExec(...execArgs);
|
|
216
|
-
} catch (e) {
|
|
217
|
-
if (!this.logErrors || !logErrors) {
|
|
218
|
-
// if we don't want to see the errors, just throw and allow the calling
|
|
219
|
-
// code do what it wants
|
|
220
|
-
} else if (e.stderr) {
|
|
221
|
-
const msg = `Error running '${subcommand}': ${e.stderr.trim()}`;
|
|
222
|
-
log.debug(LOG_PREFIX, msg);
|
|
223
|
-
e.message = msg;
|
|
224
|
-
} else {
|
|
225
|
-
log.debug(LOG_PREFIX, e.message);
|
|
226
|
-
}
|
|
227
|
-
throw e;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
addMedia = addmediaCommands.addMedia;
|
|
232
|
-
|
|
233
|
-
appInfo = appinfoCommands.appInfo;
|
|
234
|
-
|
|
235
|
-
bootDevice = bootCommands.bootDevice;
|
|
236
|
-
|
|
237
|
-
startBootMonitor = bootstatusCommands.startBootMonitor;
|
|
238
|
-
|
|
239
|
-
createDevice = createCommands.createDevice;
|
|
240
|
-
|
|
241
|
-
deleteDevice = deleteCommands.deleteDevice;
|
|
242
|
-
|
|
243
|
-
eraseDevice = eraseCommands.eraseDevice;
|
|
244
|
-
|
|
245
|
-
getAppContainer = getappcontainerCommands.getAppContainer;
|
|
246
|
-
|
|
247
|
-
getEnv = envCommands.getEnv;
|
|
248
|
-
|
|
249
|
-
installApp = installCommands.installApp;
|
|
250
|
-
|
|
251
|
-
getScreenshot = ioCommands.getScreenshot;
|
|
252
|
-
|
|
253
|
-
addRootCertificate = keychainCommands.addRootCertificate;
|
|
254
|
-
addCertificate = keychainCommands.addCertificate;
|
|
255
|
-
resetKeychain = keychainCommands.resetKeychain;
|
|
256
|
-
|
|
257
|
-
launchApp = launchCommands.launchApp;
|
|
258
|
-
|
|
259
|
-
getDevicesByParsing = listCommands.getDevicesByParsing;
|
|
260
|
-
getDevices = listCommands.getDevices;
|
|
261
|
-
getRuntimeForPlatformVersionViaJson = listCommands.getRuntimeForPlatformVersionViaJson;
|
|
262
|
-
getRuntimeForPlatformVersion = listCommands.getRuntimeForPlatformVersion;
|
|
263
|
-
getDeviceTypes = listCommands.getDeviceTypes;
|
|
264
|
-
list = listCommands.list;
|
|
265
|
-
|
|
266
|
-
setLocation = locationCommands.setLocation;
|
|
267
|
-
clearLocation = locationCommands.clearLocation;
|
|
268
|
-
|
|
269
|
-
openUrl = openurlCommands.openUrl;
|
|
270
|
-
|
|
271
|
-
setPasteboard = pbcopyCommands.setPasteboard;
|
|
272
|
-
|
|
273
|
-
getPasteboard = pbpasteCommands.getPasteboard;
|
|
274
|
-
|
|
275
|
-
grantPermission = privacyCommands.grantPermission;
|
|
276
|
-
revokePermission = privacyCommands.revokePermission;
|
|
277
|
-
resetPermission = privacyCommands.resetPermission;
|
|
278
|
-
|
|
279
|
-
pushNotification = pushCommands.pushNotification;
|
|
280
|
-
|
|
281
|
-
shutdownDevice = shutdownCommands.shutdownDevice;
|
|
282
|
-
|
|
283
|
-
spawnProcess = spawnCommands.spawnProcess;
|
|
284
|
-
spawnSubProcess = spawnCommands.spawnSubProcess;
|
|
285
|
-
|
|
286
|
-
terminateApp = terminateCommands.terminateApp;
|
|
287
|
-
|
|
288
|
-
getAppearance = uiCommands.getAppearance;
|
|
289
|
-
setAppearance = uiCommands.setAppearance;
|
|
290
|
-
getIncreaseContrast = uiCommands.getIncreaseContrast;
|
|
291
|
-
setIncreaseContrast = uiCommands.setIncreaseContrast;
|
|
292
|
-
getContentSize = uiCommands.getContentSize;
|
|
293
|
-
setContentSize = uiCommands.setContentSize;
|
|
294
|
-
|
|
295
|
-
removeApp = uninstallCommands.removeApp;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export default Simctl;
|
|
299
|
-
export { Simctl };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
const commands = {};
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Invoke hidden appinfo subcommand to get the information
|
|
5
|
-
* about applications installed on Simulator, including
|
|
6
|
-
* system applications ({@link getAppContainer} does not "see" such apps).
|
|
7
|
-
* Simulator server should be in 'booted' state for this call to work properly.
|
|
8
|
-
* The tool is only available since Xcode SDK 8.1
|
|
9
|
-
*
|
|
10
|
-
* @this {import('../simctl').Simctl}
|
|
11
|
-
* @param {string} bundleId - The bundle identifier of the target application.
|
|
12
|
-
* @return {Promise<string>} The information about installed application.
|
|
13
|
-
*
|
|
14
|
-
* Example output for non-existing application container:
|
|
15
|
-
* <pre>
|
|
16
|
-
* {
|
|
17
|
-
* CFBundleIdentifier = "com.apple.MobileSafari";
|
|
18
|
-
* GroupContainers = {
|
|
19
|
-
* };
|
|
20
|
-
* SBAppTags = (
|
|
21
|
-
* );
|
|
22
|
-
* }
|
|
23
|
-
* </pre>
|
|
24
|
-
*
|
|
25
|
-
* Example output for an existing system application container:
|
|
26
|
-
* <pre>
|
|
27
|
-
* {
|
|
28
|
-
* ApplicationType = Hidden;
|
|
29
|
-
* Bundle = "file:///Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/CoreServices/SpringBoard.app";
|
|
30
|
-
* CFBundleDisplayName = SpringBoard;
|
|
31
|
-
* CFBundleExecutable = SpringBoard;
|
|
32
|
-
* CFBundleIdentifier = "com.apple.springboard";
|
|
33
|
-
* CFBundleName = SpringBoard;
|
|
34
|
-
* CFBundleVersion = 50;
|
|
35
|
-
* GroupContainers = {
|
|
36
|
-
* };
|
|
37
|
-
* Path = "/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/CoreServices/SpringBoard.app";
|
|
38
|
-
* SBAppTags = (
|
|
39
|
-
* );
|
|
40
|
-
* }
|
|
41
|
-
* </pre>
|
|
42
|
-
* @throws {Error} If the `udid` instance property is unset
|
|
43
|
-
*/
|
|
44
|
-
commands.appInfo = async function appInfo (bundleId) {
|
|
45
|
-
const {stdout} = await this.exec('appinfo', {
|
|
46
|
-
args: [this.requireUdid('appinfo'), bundleId],
|
|
47
|
-
});
|
|
48
|
-
return (stdout || '').trim();
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export default commands;
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import log from '../logger';
|
|
2
|
-
import { waitForCondition } from 'asyncbox';
|
|
3
|
-
import _ from 'lodash';
|
|
4
|
-
|
|
5
|
-
const commands = {};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {Object} BootMonitorOptions
|
|
9
|
-
* @property {number} [timeout=240000] - Simulator booting timeout in ms.
|
|
10
|
-
* @property {Function} [onWaitingDataMigration] - This event is fired when data migration stage starts.
|
|
11
|
-
* @property {Function} [onWaitingSystemApp] - This event is fired when system app wait stage starts.
|
|
12
|
-
* @property {Function} [onFinished] - This event is fired when Simulator is fully booted.
|
|
13
|
-
* @property {Function} [onError] - This event is fired when there was an error while monitoring the booting process
|
|
14
|
-
* or when the timeout has expired.
|
|
15
|
-
* @property {boolean} [shouldPreboot=false] Whether to preboot the Simulator
|
|
16
|
-
* if this command is called and it is not already in booted or booting state.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Start monitoring for boot status of the particular Simulator.
|
|
21
|
-
* If onFinished property is not set then the method will block
|
|
22
|
-
* until Simulator booting is completed.
|
|
23
|
-
* The method is only available since Xcode8.
|
|
24
|
-
*
|
|
25
|
-
* @this {import('../simctl').Simctl}
|
|
26
|
-
* @param {BootMonitorOptions} [opts={}] - Monitoring options.
|
|
27
|
-
* @returns {Promise<import('teen_process').SubProcess>} The instance of the corresponding monitoring process.
|
|
28
|
-
* @throws {Error} If the Simulator fails to finish booting within the given timeout and onFinished
|
|
29
|
-
* property is not set.
|
|
30
|
-
* @throws {Error} If the `udid` instance property is unset
|
|
31
|
-
*/
|
|
32
|
-
commands.startBootMonitor = async function startBootMonitor (opts = {}) {
|
|
33
|
-
const {
|
|
34
|
-
timeout = 240000,
|
|
35
|
-
onWaitingDataMigration,
|
|
36
|
-
onWaitingSystemApp,
|
|
37
|
-
onFinished,
|
|
38
|
-
onError,
|
|
39
|
-
shouldPreboot,
|
|
40
|
-
} = opts;
|
|
41
|
-
const udid = this.requireUdid('bootstatus');
|
|
42
|
-
|
|
43
|
-
/** @type {string[]} */
|
|
44
|
-
const status = [];
|
|
45
|
-
let isBootingFinished = false;
|
|
46
|
-
let error = null;
|
|
47
|
-
let timeoutHandler = null;
|
|
48
|
-
const args = [udid];
|
|
49
|
-
if (shouldPreboot) {
|
|
50
|
-
args.push('-b');
|
|
51
|
-
}
|
|
52
|
-
const bootMonitor = await this.exec('bootstatus', {
|
|
53
|
-
args,
|
|
54
|
-
asynchronous: true,
|
|
55
|
-
});
|
|
56
|
-
const onStreamLine = (/** @type {string} */ line) => {
|
|
57
|
-
status.push(line);
|
|
58
|
-
if (onWaitingDataMigration && line.includes('Waiting on Data Migration')) {
|
|
59
|
-
onWaitingDataMigration();
|
|
60
|
-
} else if (onWaitingSystemApp && line.includes('Waiting on System App')) {
|
|
61
|
-
onWaitingSystemApp();
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
for (const streamName of ['stdout', 'stderr']) {
|
|
65
|
-
bootMonitor.on(`line-${streamName}`, onStreamLine);
|
|
66
|
-
}
|
|
67
|
-
bootMonitor.once('exit', (code, signal) => {
|
|
68
|
-
if (timeoutHandler) {
|
|
69
|
-
clearTimeout(timeoutHandler);
|
|
70
|
-
}
|
|
71
|
-
if (code === 0) {
|
|
72
|
-
if (onFinished) {
|
|
73
|
-
onFinished();
|
|
74
|
-
}
|
|
75
|
-
isBootingFinished = true;
|
|
76
|
-
} else {
|
|
77
|
-
const errMessage = _.isEmpty(status)
|
|
78
|
-
? `The simulator booting process has exited with code ${code} by signal ${signal}`
|
|
79
|
-
: status.join('\n');
|
|
80
|
-
error = new Error(errMessage);
|
|
81
|
-
if (onError) {
|
|
82
|
-
onError(error);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
await bootMonitor.start(0);
|
|
87
|
-
const stopMonitor = async () => {
|
|
88
|
-
if (bootMonitor.isRunning) {
|
|
89
|
-
try {
|
|
90
|
-
await bootMonitor.stop();
|
|
91
|
-
} catch (e) {
|
|
92
|
-
log.warn(e.message);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
const start = process.hrtime();
|
|
97
|
-
if (onFinished) {
|
|
98
|
-
timeoutHandler = setTimeout(stopMonitor, timeout);
|
|
99
|
-
} else {
|
|
100
|
-
try {
|
|
101
|
-
await waitForCondition(() => {
|
|
102
|
-
if (error) {
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
return isBootingFinished;
|
|
106
|
-
}, {waitMs: timeout, intervalMs: 500});
|
|
107
|
-
} catch {
|
|
108
|
-
await stopMonitor();
|
|
109
|
-
const [seconds] = process.hrtime(start);
|
|
110
|
-
throw new Error(
|
|
111
|
-
`The simulator ${udid} has failed to finish booting after ${seconds}s. ` +
|
|
112
|
-
`Original status: ${status.join('\n')}`
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return bootMonitor;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
export default commands;
|