node-simctl 8.1.5 → 8.1.7
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/helpers.d.ts.map +1 -1
- package/build/lib/helpers.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} +1 -1
- package/build/lib/index.js.map +1 -0
- package/build/lib/logger.js.map +1 -1
- package/build/lib/simctl.d.ts.map +1 -1
- package/build/lib/simctl.js +5 -2
- package/build/lib/simctl.js.map +1 -1
- package/build/lib/subcommands/addmedia.d.ts.map +1 -1
- package/build/lib/subcommands/addmedia.js.map +1 -1
- package/build/lib/subcommands/appinfo.d.ts.map +1 -1
- package/build/lib/subcommands/appinfo.js.map +1 -1
- package/build/lib/subcommands/boot.d.ts.map +1 -1
- package/build/lib/subcommands/boot.js +1 -1
- package/build/lib/subcommands/boot.js.map +1 -1
- package/build/lib/subcommands/bootstatus.d.ts.map +1 -1
- package/build/lib/subcommands/bootstatus.js.map +1 -1
- package/build/lib/subcommands/create.d.ts.map +1 -1
- package/build/lib/subcommands/create.js +2 -2
- package/build/lib/subcommands/create.js.map +1 -1
- package/build/lib/subcommands/delete.d.ts.map +1 -1
- package/build/lib/subcommands/delete.js +1 -1
- package/build/lib/subcommands/erase.d.ts.map +1 -1
- package/build/lib/subcommands/erase.js +1 -1
- package/build/lib/subcommands/erase.js.map +1 -1
- package/build/lib/subcommands/get_app_container.d.ts.map +1 -1
- package/build/lib/subcommands/getenv.d.ts.map +1 -1
- package/build/lib/subcommands/getenv.js.map +1 -1
- package/build/lib/subcommands/install.d.ts.map +1 -1
- package/build/lib/subcommands/install.js.map +1 -1
- package/build/lib/subcommands/io.d.ts.map +1 -1
- package/build/lib/subcommands/io.js.map +1 -1
- package/build/lib/subcommands/keychain.d.ts.map +1 -1
- package/build/lib/subcommands/keychain.js +2 -2
- package/build/lib/subcommands/keychain.js.map +1 -1
- package/build/lib/subcommands/launch.d.ts.map +1 -1
- package/build/lib/subcommands/launch.js.map +1 -1
- package/build/lib/subcommands/list.d.ts.map +1 -1
- package/build/lib/subcommands/list.js +4 -3
- package/build/lib/subcommands/list.js.map +1 -1
- package/build/lib/subcommands/location.d.ts.map +1 -1
- package/build/lib/subcommands/location.js.map +1 -1
- package/build/lib/subcommands/openurl.d.ts.map +1 -1
- package/build/lib/subcommands/openurl.js.map +1 -1
- package/build/lib/subcommands/pbcopy.d.ts.map +1 -1
- package/build/lib/subcommands/pbcopy.js +2 -2
- package/build/lib/subcommands/pbcopy.js.map +1 -1
- package/build/lib/subcommands/pbpaste.d.ts.map +1 -1
- package/build/lib/subcommands/pbpaste.js.map +1 -1
- package/build/lib/subcommands/privacy.d.ts.map +1 -1
- package/build/lib/subcommands/privacy.js.map +1 -1
- package/build/lib/subcommands/push.d.ts.map +1 -1
- package/build/lib/subcommands/push.js.map +1 -1
- package/build/lib/subcommands/shutdown.d.ts.map +1 -1
- package/build/lib/subcommands/shutdown.js.map +1 -1
- package/build/lib/subcommands/spawn.d.ts.map +1 -1
- package/build/lib/subcommands/spawn.js +2 -2
- package/build/lib/subcommands/spawn.js.map +1 -1
- package/build/lib/subcommands/terminate.d.ts.map +1 -1
- package/build/lib/subcommands/terminate.js.map +1 -1
- package/build/lib/subcommands/ui.d.ts.map +1 -1
- package/build/lib/subcommands/ui.js.map +1 -1
- package/build/lib/subcommands/uninstall.d.ts.map +1 -1
- package/build/lib/subcommands/uninstall.js.map +1 -1
- package/build/lib/types.d.ts.map +1 -1
- package/lib/helpers.ts +9 -8
- package/{index.ts → lib/index.ts} +3 -3
- package/lib/logger.ts +2 -2
- package/lib/simctl.ts +34 -32
- package/lib/subcommands/addmedia.ts +6 -3
- package/lib/subcommands/appinfo.ts +5 -5
- package/lib/subcommands/boot.ts +4 -4
- package/lib/subcommands/bootstatus.ts +82 -80
- package/lib/subcommands/create.ts +22 -20
- package/lib/subcommands/delete.ts +3 -4
- package/lib/subcommands/erase.ts +10 -8
- package/lib/subcommands/get_app_container.ts +3 -4
- package/lib/subcommands/getenv.ts +2 -3
- package/lib/subcommands/install.ts +2 -3
- package/lib/subcommands/io.ts +4 -5
- package/lib/subcommands/keychain.ts +21 -24
- package/lib/subcommands/launch.ts +7 -4
- package/lib/subcommands/list.ts +48 -38
- package/lib/subcommands/location.ts +5 -6
- package/lib/subcommands/openurl.ts +3 -3
- package/lib/subcommands/pbcopy.ts +6 -7
- package/lib/subcommands/pbpaste.ts +5 -3
- package/lib/subcommands/privacy.ts +8 -5
- package/lib/subcommands/push.ts +4 -5
- package/lib/subcommands/shutdown.ts +3 -4
- package/lib/subcommands/spawn.ts +8 -9
- package/lib/subcommands/terminate.ts +2 -3
- package/lib/subcommands/ui.ts +7 -8
- package/lib/subcommands/uninstall.ts +2 -3
- package/lib/types.ts +1 -2
- 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
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
2
|
+
import {log, LOG_PREFIX} from '../logger';
|
|
3
|
+
import {retryInterval} from 'asyncbox';
|
|
4
|
+
import {SIM_RUNTIME_NAME, normalizeVersion} from '../helpers';
|
|
5
|
+
import type {Simctl} from '../simctl';
|
|
6
|
+
import type {SimCreationOpts} from '../types';
|
|
7
7
|
|
|
8
8
|
const SIM_RUNTIME_NAME_SUFFIX_IOS = 'iOS';
|
|
9
9
|
const DEFAULT_CREATE_SIMULATOR_TIMEOUT = 10000;
|
|
@@ -20,17 +20,14 @@ const DEFAULT_CREATE_SIMULATOR_TIMEOUT = 10000;
|
|
|
20
20
|
* @throws {Error} If the corresponding simctl subcommand command
|
|
21
21
|
* returns non-zero return code.
|
|
22
22
|
*/
|
|
23
|
-
export async function createDevice
|
|
23
|
+
export async function createDevice(
|
|
24
24
|
this: Simctl,
|
|
25
25
|
name: string,
|
|
26
26
|
deviceTypeId: string,
|
|
27
27
|
platformVersion: string,
|
|
28
|
-
opts: SimCreationOpts = {}
|
|
28
|
+
opts: SimCreationOpts = {},
|
|
29
29
|
): Promise<string> {
|
|
30
|
-
const {
|
|
31
|
-
platform = SIM_RUNTIME_NAME_SUFFIX_IOS,
|
|
32
|
-
timeout = DEFAULT_CREATE_SIMULATOR_TIMEOUT
|
|
33
|
-
} = opts;
|
|
30
|
+
const {platform = SIM_RUNTIME_NAME_SUFFIX_IOS, timeout = DEFAULT_CREATE_SIMULATOR_TIMEOUT} = opts;
|
|
34
31
|
|
|
35
32
|
const runtimeIds: string[] = [];
|
|
36
33
|
|
|
@@ -62,19 +59,23 @@ export async function createDevice (
|
|
|
62
59
|
// add modified versions, since modern Xcodes use this, then the bare
|
|
63
60
|
// versions, to accomodate older Xcodes
|
|
64
61
|
runtimeIds.push(
|
|
65
|
-
...
|
|
66
|
-
|
|
62
|
+
...potentialRuntimeIds.map(
|
|
63
|
+
(id) => `${SIM_RUNTIME_NAME}${platform}-${id.replace(/\./g, '-')}`,
|
|
64
|
+
),
|
|
65
|
+
...potentialRuntimeIds,
|
|
67
66
|
);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
// go through the runtime ids and try to create a simulator with each
|
|
71
70
|
let udid: string | undefined;
|
|
72
71
|
for (const runtimeId of runtimeIds) {
|
|
73
|
-
log.debug(
|
|
74
|
-
|
|
72
|
+
log.debug(
|
|
73
|
+
LOG_PREFIX,
|
|
74
|
+
`Creating simulator with name '${name}', device type id '${deviceTypeId}' and runtime id '${runtimeId}'`,
|
|
75
|
+
);
|
|
75
76
|
try {
|
|
76
77
|
const {stdout} = await this.exec('create', {
|
|
77
|
-
args: [name, deviceTypeId, runtimeId]
|
|
78
|
+
args: [name, deviceTypeId, runtimeId],
|
|
78
79
|
});
|
|
79
80
|
udid = stdout.trim();
|
|
80
81
|
break;
|
|
@@ -84,9 +85,11 @@ export async function createDevice (
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
if (!udid) {
|
|
87
|
-
throw new Error(
|
|
88
|
-
`
|
|
89
|
-
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Could not create simulator with name '${name}', device ` +
|
|
90
|
+
`type id '${deviceTypeId}', with runtime ids ` +
|
|
91
|
+
`${runtimeIds.map((id) => `'${id}'`).join(', ')}`,
|
|
92
|
+
);
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
// make sure that it gets out of the "Creating" state
|
|
@@ -109,4 +112,3 @@ export async function createDevice (
|
|
|
109
112
|
|
|
110
113
|
return udid;
|
|
111
114
|
}
|
|
112
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Delete the particular Simulator from available devices list.
|
|
@@ -7,9 +7,8 @@ import type { Simctl } from '../simctl';
|
|
|
7
7
|
* returns non-zero return code.
|
|
8
8
|
* @throws {Error} If the `udid` instance property is unset
|
|
9
9
|
*/
|
|
10
|
-
export async function deleteDevice
|
|
10
|
+
export async function deleteDevice(this: Simctl): Promise<void> {
|
|
11
11
|
await this.exec('delete', {
|
|
12
|
-
args: [this.requireUdid('delete')]
|
|
12
|
+
args: [this.requireUdid('delete')],
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
|
package/lib/subcommands/erase.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
1
|
+
import {retryInterval} from 'asyncbox';
|
|
2
|
+
import type {Simctl} from '../simctl';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Reset the content and settings of the particular Simulator.
|
|
@@ -11,13 +11,15 @@ import type { Simctl } from '../simctl';
|
|
|
11
11
|
* returns non-zero return code.
|
|
12
12
|
* @throws {Error} If the `udid` instance property is unset
|
|
13
13
|
*/
|
|
14
|
-
export async function eraseDevice
|
|
14
|
+
export async function eraseDevice(this: Simctl, timeout: number = 1000): Promise<void> {
|
|
15
15
|
// retry erase with a sleep in between because it's flakey
|
|
16
16
|
const retries = parseInt(`${timeout / 200}`, 10);
|
|
17
|
-
await retryInterval(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
await retryInterval(
|
|
18
|
+
retries,
|
|
19
|
+
200,
|
|
20
|
+
async () =>
|
|
21
|
+
await this.exec('erase', {
|
|
22
|
+
args: [this.requireUdid('erase')],
|
|
23
|
+
}),
|
|
21
24
|
);
|
|
22
25
|
}
|
|
23
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Get the full path to the particular application container
|
|
@@ -17,10 +17,10 @@ import type { Simctl } from '../simctl';
|
|
|
17
17
|
* returns non-zero return code.
|
|
18
18
|
* @throws {Error} If the `udid` instance property is unset
|
|
19
19
|
*/
|
|
20
|
-
export async function getAppContainer
|
|
20
|
+
export async function getAppContainer(
|
|
21
21
|
this: Simctl,
|
|
22
22
|
bundleId: string,
|
|
23
|
-
containerType: string | null = null
|
|
23
|
+
containerType: string | null = null,
|
|
24
24
|
): Promise<string> {
|
|
25
25
|
const args = [this.requireUdid('get_app_container'), bundleId];
|
|
26
26
|
if (containerType) {
|
|
@@ -29,4 +29,3 @@ export async function getAppContainer (
|
|
|
29
29
|
const {stdout} = await this.exec('get_app_container', {args});
|
|
30
30
|
return (stdout || '').trim();
|
|
31
31
|
}
|
|
32
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Retrieves the value of a Simulator environment variable
|
|
@@ -9,11 +9,10 @@ import type { Simctl } from '../simctl';
|
|
|
9
9
|
* @throws {Error} If there was an error while running the command
|
|
10
10
|
* @throws {Error} If the `udid` instance property is unset
|
|
11
11
|
*/
|
|
12
|
-
export async function getEnv
|
|
12
|
+
export async function getEnv(this: Simctl, varName: string): Promise<string | null> {
|
|
13
13
|
const {stdout, stderr} = await this.exec('getenv', {
|
|
14
14
|
args: [this.requireUdid('getenv'), varName],
|
|
15
15
|
logErrors: false,
|
|
16
16
|
});
|
|
17
17
|
return stderr ? null : stdout;
|
|
18
18
|
}
|
|
19
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Install the particular application package on Simulator.
|
|
@@ -10,9 +10,8 @@ import type { Simctl } from '../simctl';
|
|
|
10
10
|
* returns non-zero return code.
|
|
11
11
|
* @throws {Error} If the `udid` instance property is unset
|
|
12
12
|
*/
|
|
13
|
-
export async function installApp
|
|
13
|
+
export async function installApp(this: Simctl, appPath: string): Promise<void> {
|
|
14
14
|
await this.exec('install', {
|
|
15
15
|
args: [this.requireUdid('install'), appPath],
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
|
package/lib/subcommands/io.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {rimraf} from 'rimraf';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import fs from 'node:fs/promises';
|
|
5
|
-
import {
|
|
6
|
-
import type {
|
|
5
|
+
import {uuidV4} from '../helpers';
|
|
6
|
+
import type {Simctl} from '../simctl';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Gets base64 screenshot for device
|
|
@@ -15,7 +15,7 @@ import type { Simctl } from '../simctl';
|
|
|
15
15
|
* returns non-zero return code.
|
|
16
16
|
* @throws {Error} If the `udid` instance property is unset
|
|
17
17
|
*/
|
|
18
|
-
export async function getScreenshot
|
|
18
|
+
export async function getScreenshot(this: Simctl): Promise<string> {
|
|
19
19
|
const udid = this.requireUdid('io screenshot');
|
|
20
20
|
const pathToScreenshotPng = path.resolve(os.tmpdir(), `${await uuidV4()}.png`);
|
|
21
21
|
try {
|
|
@@ -27,4 +27,3 @@ export async function getScreenshot (this: Simctl): Promise<string> {
|
|
|
27
27
|
await rimraf(pathToScreenshotPng);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
|
-
import {
|
|
3
|
+
import {uuidV4} from '../helpers';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import _ from 'lodash';
|
|
6
|
-
import {
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
6
|
+
import {rimraf} from 'rimraf';
|
|
7
|
+
import type {Simctl} from '../simctl';
|
|
8
|
+
import type {CertOptions} from '../types';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @param payload - Certificate payload (string or Buffer)
|
|
12
12
|
* @param onPayloadStored - Callback function to execute with the file path
|
|
13
13
|
*/
|
|
14
|
-
async function handleRawPayload
|
|
14
|
+
async function handleRawPayload(
|
|
15
15
|
payload: string | Buffer,
|
|
16
|
-
onPayloadStored: (filePath: string) => Promise<any
|
|
16
|
+
onPayloadStored: (filePath: string) => Promise<any>,
|
|
17
17
|
): Promise<void> {
|
|
18
18
|
const filePath = path.resolve(os.tmpdir(), `${await uuidV4()}.pem`);
|
|
19
19
|
try {
|
|
@@ -40,17 +40,16 @@ async function handleRawPayload (
|
|
|
40
40
|
* or there was an error while adding the certificate
|
|
41
41
|
* @throws {Error} If the `udid` instance property is unset
|
|
42
42
|
*/
|
|
43
|
-
export async function addRootCertificate
|
|
43
|
+
export async function addRootCertificate(
|
|
44
44
|
this: Simctl,
|
|
45
45
|
cert: string | Buffer,
|
|
46
|
-
opts: CertOptions = {}
|
|
46
|
+
opts: CertOptions = {},
|
|
47
47
|
): Promise<void> {
|
|
48
|
-
const {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
48
|
+
const {raw = false} = opts;
|
|
49
|
+
const execMethod = async (certPath: string) =>
|
|
50
|
+
await this.exec('keychain', {
|
|
51
|
+
args: [this.requireUdid('keychain add-root-cert'), 'add-root-cert', certPath],
|
|
52
|
+
});
|
|
54
53
|
if (raw) {
|
|
55
54
|
await handleRawPayload(cert, execMethod);
|
|
56
55
|
} else {
|
|
@@ -70,17 +69,16 @@ export async function addRootCertificate (
|
|
|
70
69
|
* or there was an error while adding the certificate
|
|
71
70
|
* @throws {Error} If the `udid` instance property is unset
|
|
72
71
|
*/
|
|
73
|
-
export async function addCertificate
|
|
72
|
+
export async function addCertificate(
|
|
74
73
|
this: Simctl,
|
|
75
74
|
cert: string | Buffer,
|
|
76
|
-
opts: CertOptions = {}
|
|
75
|
+
opts: CertOptions = {},
|
|
77
76
|
): Promise<void> {
|
|
78
|
-
const {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
});
|
|
77
|
+
const {raw = false} = opts;
|
|
78
|
+
const execMethod = async (certPath: string) =>
|
|
79
|
+
await this.exec('keychain', {
|
|
80
|
+
args: [this.requireUdid('keychain add-cert'), 'add-cert', certPath],
|
|
81
|
+
});
|
|
84
82
|
if (raw) {
|
|
85
83
|
await handleRawPayload(cert, execMethod);
|
|
86
84
|
} else {
|
|
@@ -96,9 +94,8 @@ export async function addCertificate (
|
|
|
96
94
|
* or there was an error while resetting the keychain
|
|
97
95
|
* @throws {Error} If the `udid` instance property is unset
|
|
98
96
|
*/
|
|
99
|
-
export async function resetKeychain
|
|
97
|
+
export async function resetKeychain(this: Simctl): Promise<void> {
|
|
100
98
|
await this.exec('keychain', {
|
|
101
99
|
args: [this.requireUdid('keychain reset'), 'reset'],
|
|
102
100
|
});
|
|
103
101
|
}
|
|
104
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
2
|
+
import {retryInterval} from 'asyncbox';
|
|
3
|
+
import type {Simctl} from '../simctl';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Execute the particular application package on Simulator.
|
|
@@ -16,7 +16,11 @@ import type { Simctl } from '../simctl';
|
|
|
16
16
|
* returns non-zero return code.
|
|
17
17
|
* @throws {Error} If the `udid` instance property is unset
|
|
18
18
|
*/
|
|
19
|
-
export async function launchApp
|
|
19
|
+
export async function launchApp(
|
|
20
|
+
this: Simctl,
|
|
21
|
+
bundleId: string,
|
|
22
|
+
tries: number = 5,
|
|
23
|
+
): Promise<string> {
|
|
20
24
|
const result = await retryInterval(tries, 1000, async () => {
|
|
21
25
|
const {stdout} = await this.exec('launch', {
|
|
22
26
|
args: [this.requireUdid('launch'), bundleId],
|
|
@@ -25,4 +29,3 @@ export async function launchApp (this: Simctl, bundleId: string, tries: number =
|
|
|
25
29
|
});
|
|
26
30
|
return result || '';
|
|
27
31
|
}
|
|
28
|
-
|
package/lib/subcommands/list.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
2
|
+
import {SIM_RUNTIME_NAME, normalizeVersion} from '../helpers';
|
|
3
|
+
import {log, LOG_PREFIX} from '../logger';
|
|
4
|
+
import type {Simctl} from '../simctl';
|
|
5
|
+
import type {DeviceInfo} from '../types';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parse the list of existing Simulator devices to represent
|
|
@@ -15,9 +15,9 @@ import type { DeviceInfo } from '../types';
|
|
|
15
15
|
* @throws {Error} If the corresponding simctl subcommand command
|
|
16
16
|
* returns non-zero return code.
|
|
17
17
|
*/
|
|
18
|
-
export async function getDevicesByParsing
|
|
18
|
+
export async function getDevicesByParsing(
|
|
19
19
|
this: Simctl,
|
|
20
|
-
platform?: string | null
|
|
20
|
+
platform?: string | null,
|
|
21
21
|
): Promise<Record<string, DeviceInfo[]>> {
|
|
22
22
|
const {stdout} = await this.exec('list', {
|
|
23
23
|
args: ['devices'],
|
|
@@ -32,9 +32,13 @@ export async function getDevicesByParsing (
|
|
|
32
32
|
// ...
|
|
33
33
|
// so, get the `-- iOS X.X --` line to find the sdk (X.X)
|
|
34
34
|
// and the rest of the listing in order to later find the devices
|
|
35
|
-
const deviceSectionRe =
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const deviceSectionRe =
|
|
36
|
+
_.isEmpty(platform) || !platform
|
|
37
|
+
? new RegExp(`\\-\\-\\s+(\\S+)\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`, 'mgi')
|
|
38
|
+
: new RegExp(
|
|
39
|
+
`\\-\\-\\s+${_.escapeRegExp(platform)}\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`,
|
|
40
|
+
'mgi',
|
|
41
|
+
);
|
|
38
42
|
const matches: RegExpExecArray[] = [];
|
|
39
43
|
let match: RegExpExecArray | null;
|
|
40
44
|
// make an entry for each sdk version
|
|
@@ -95,20 +99,20 @@ export async function getDevicesByParsing (
|
|
|
95
99
|
* returns non-zero return code or if no matching
|
|
96
100
|
* platform version is found in the system.
|
|
97
101
|
*/
|
|
98
|
-
export async function getDevices
|
|
102
|
+
export async function getDevices(
|
|
99
103
|
this: Simctl,
|
|
100
104
|
forSdk: string,
|
|
101
|
-
platform?: string | null
|
|
105
|
+
platform?: string | null,
|
|
102
106
|
): Promise<DeviceInfo[]>;
|
|
103
|
-
export async function getDevices
|
|
107
|
+
export async function getDevices(
|
|
104
108
|
this: Simctl,
|
|
105
109
|
forSdk?: undefined | null,
|
|
106
|
-
platform?: string | null
|
|
110
|
+
platform?: string | null,
|
|
107
111
|
): Promise<Record<string, DeviceInfo[]>>;
|
|
108
|
-
export async function getDevices
|
|
112
|
+
export async function getDevices(
|
|
109
113
|
this: Simctl,
|
|
110
114
|
forSdk?: string | null,
|
|
111
|
-
platform?: string | null
|
|
115
|
+
platform?: string | null,
|
|
112
116
|
): Promise<Record<string, DeviceInfo[]> | DeviceInfo[]> {
|
|
113
117
|
let devices: Record<string, DeviceInfo[]> = {};
|
|
114
118
|
try {
|
|
@@ -131,9 +135,10 @@ export async function getDevices (
|
|
|
131
135
|
* }
|
|
132
136
|
* }
|
|
133
137
|
*/
|
|
134
|
-
const versionMatchRe =
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
const versionMatchRe =
|
|
139
|
+
_.isEmpty(platform) || !platform
|
|
140
|
+
? new RegExp(`^([^\\s-]+)[\\s-](\\S+)`, 'i')
|
|
141
|
+
: new RegExp(`^${_.escapeRegExp(platform)}[\\s-](\\S+)`, 'i');
|
|
137
142
|
for (const [sdkNameRaw, entries] of _.toPairs(JSON.parse(stdout).devices)) {
|
|
138
143
|
// there could be a longer name, so remove it
|
|
139
144
|
const sdkName = sdkNameRaw.replace(SIM_RUNTIME_NAME, '');
|
|
@@ -145,15 +150,17 @@ export async function getDevices (
|
|
|
145
150
|
// the sdk can have dashes (`12-2`) or dots (`12.1`)
|
|
146
151
|
const sdk = (platform ? versionMatch[1] : versionMatch[2]).replace('-', '.');
|
|
147
152
|
devices[sdk] = devices[sdk] || [];
|
|
148
|
-
devices[sdk].push(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
devices[sdk].push(
|
|
154
|
+
...(entries as any[])
|
|
155
|
+
.filter((el) => _.isUndefined(el.isAvailable) || el.isAvailable)
|
|
156
|
+
.map((el: any) => {
|
|
157
|
+
delete el.availability;
|
|
158
|
+
return {
|
|
159
|
+
sdk,
|
|
160
|
+
...el,
|
|
161
|
+
platform: platform || versionMatch[1],
|
|
162
|
+
};
|
|
163
|
+
}),
|
|
157
164
|
);
|
|
158
165
|
}
|
|
159
166
|
} catch (err: any) {
|
|
@@ -187,17 +194,19 @@ export async function getDevices (
|
|
|
187
194
|
* @return The corresponding runtime name for the given
|
|
188
195
|
* platform version.
|
|
189
196
|
*/
|
|
190
|
-
export async function getRuntimeForPlatformVersionViaJson
|
|
197
|
+
export async function getRuntimeForPlatformVersionViaJson(
|
|
191
198
|
this: Simctl,
|
|
192
199
|
platformVersion: string,
|
|
193
|
-
platform: string = 'iOS'
|
|
200
|
+
platform: string = 'iOS',
|
|
194
201
|
): Promise<string> {
|
|
195
202
|
const {stdout} = await this.exec('list', {
|
|
196
203
|
args: ['runtimes', '--json'],
|
|
197
204
|
});
|
|
198
205
|
for (const {version, identifier, name} of JSON.parse(stdout).runtimes) {
|
|
199
|
-
if (
|
|
200
|
-
|
|
206
|
+
if (
|
|
207
|
+
normalizeVersion(version) === normalizeVersion(platformVersion) &&
|
|
208
|
+
name.toLowerCase().startsWith(platform.toLowerCase())
|
|
209
|
+
) {
|
|
201
210
|
return identifier;
|
|
202
211
|
}
|
|
203
212
|
}
|
|
@@ -213,10 +222,10 @@ export async function getRuntimeForPlatformVersionViaJson (
|
|
|
213
222
|
* @return The corresponding runtime name for the given
|
|
214
223
|
* platform version.
|
|
215
224
|
*/
|
|
216
|
-
export async function getRuntimeForPlatformVersion
|
|
225
|
+
export async function getRuntimeForPlatformVersion(
|
|
217
226
|
this: Simctl,
|
|
218
227
|
platformVersion: string,
|
|
219
|
-
platform: string = 'iOS'
|
|
228
|
+
platform: string = 'iOS',
|
|
220
229
|
): Promise<string> {
|
|
221
230
|
// Try with parsing
|
|
222
231
|
try {
|
|
@@ -224,8 +233,10 @@ export async function getRuntimeForPlatformVersion (
|
|
|
224
233
|
args: ['runtimes'],
|
|
225
234
|
});
|
|
226
235
|
// https://regex101.com/r/UykjQZ/1
|
|
227
|
-
const runtimeRe =
|
|
228
|
-
|
|
236
|
+
const runtimeRe = new RegExp(
|
|
237
|
+
`${_.escapeRegExp(platform)}\\s+(\\d+\\.\\d+)\\s+\\((\\d+\\.\\d+\\.*\\d*)`,
|
|
238
|
+
'i',
|
|
239
|
+
);
|
|
229
240
|
for (const line of stdout.split('\n')) {
|
|
230
241
|
const match = runtimeRe.exec(line);
|
|
231
242
|
if (match && match[1] === platformVersion) {
|
|
@@ -244,7 +255,7 @@ export async function getRuntimeForPlatformVersion (
|
|
|
244
255
|
* @return List of the types of devices available
|
|
245
256
|
* @throws {Error} If the corresponding simctl command fails
|
|
246
257
|
*/
|
|
247
|
-
export async function getDeviceTypes
|
|
258
|
+
export async function getDeviceTypes(this: Simctl): Promise<string[]> {
|
|
248
259
|
const {stdout} = await this.exec('list', {
|
|
249
260
|
args: ['devicetypes', '-j'],
|
|
250
261
|
});
|
|
@@ -301,7 +312,7 @@ export async function getDeviceTypes (this: Simctl): Promise<string[]> {
|
|
|
301
312
|
* }
|
|
302
313
|
* @throws {Error} If the corresponding simctl command fails
|
|
303
314
|
*/
|
|
304
|
-
export async function list
|
|
315
|
+
export async function list(this: Simctl): Promise<any> {
|
|
305
316
|
const {stdout} = await this.exec('list', {
|
|
306
317
|
args: ['-j'],
|
|
307
318
|
});
|
|
@@ -311,4 +322,3 @@ export async function list (this: Simctl): Promise<any> {
|
|
|
311
322
|
throw new Error(`Unable to parse simctl list: ${e.message}`);
|
|
312
323
|
}
|
|
313
324
|
}
|
|
314
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Formats the given location argument for simctl usage
|
|
@@ -7,7 +7,7 @@ import type { Simctl } from '../simctl';
|
|
|
7
7
|
* @param value Location argument value
|
|
8
8
|
* @returns Formatted value, for example -73.768254
|
|
9
9
|
*/
|
|
10
|
-
function formatArg
|
|
10
|
+
function formatArg(name: string, value: string | number): string {
|
|
11
11
|
const flt = parseFloat(`${value}`);
|
|
12
12
|
if (isNaN(flt)) {
|
|
13
13
|
throw new TypeError(`${name} must be a valid number, got '${value}' instead`);
|
|
@@ -25,10 +25,10 @@ function formatArg (name: string, value: string | number): string {
|
|
|
25
25
|
* returns non-zero return code.
|
|
26
26
|
* @throws {TypeError} If any of the arguments is not a valid value.
|
|
27
27
|
*/
|
|
28
|
-
export async function setLocation
|
|
28
|
+
export async function setLocation(
|
|
29
29
|
this: Simctl,
|
|
30
30
|
latitude: string | number,
|
|
31
|
-
longitude: string | number
|
|
31
|
+
longitude: string | number,
|
|
32
32
|
): Promise<void> {
|
|
33
33
|
const lat = formatArg('latitude', latitude);
|
|
34
34
|
const lon = formatArg('longitude', longitude);
|
|
@@ -42,9 +42,8 @@ export async function setLocation (
|
|
|
42
42
|
*
|
|
43
43
|
* @since Xcode 14.
|
|
44
44
|
*/
|
|
45
|
-
export async function clearLocation
|
|
45
|
+
export async function clearLocation(this: Simctl): Promise<void> {
|
|
46
46
|
await this.exec('location', {
|
|
47
47
|
args: [this.requireUdid('location'), 'clear'],
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
|
+
import type {TeenProcessExecResult} from 'teen_process';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Open URL scheme on Simulator. iOS will automatically try
|
|
@@ -13,7 +13,7 @@ import type { TeenProcessExecResult } from 'teen_process';
|
|
|
13
13
|
* returns non-zero return code.
|
|
14
14
|
* @throws {Error} If the `udid` instance property is unset
|
|
15
15
|
*/
|
|
16
|
-
export async function openUrl
|
|
16
|
+
export async function openUrl(this: Simctl, url: string): Promise<TeenProcessExecResult<string>> {
|
|
17
17
|
return await this.exec('openurl', {
|
|
18
18
|
args: [this.requireUdid('openurl'), url],
|
|
19
19
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
|
+
import type {SubProcess} from 'teen_process';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Set the content of Simulator pasteboard.
|
|
@@ -13,15 +13,15 @@ import type { SubProcess } from 'teen_process';
|
|
|
13
13
|
* returns non-zero return code.
|
|
14
14
|
* @throws {Error} If the `udid` instance property is unset
|
|
15
15
|
*/
|
|
16
|
-
export async function setPasteboard
|
|
16
|
+
export async function setPasteboard(
|
|
17
17
|
this: Simctl,
|
|
18
18
|
content: string,
|
|
19
|
-
encoding: BufferEncoding = 'utf8'
|
|
19
|
+
encoding: BufferEncoding = 'utf8',
|
|
20
20
|
): Promise<void> {
|
|
21
|
-
const pbCopySubprocess = await this.exec('pbcopy', {
|
|
21
|
+
const pbCopySubprocess = (await this.exec('pbcopy', {
|
|
22
22
|
args: [this.requireUdid('pbcopy')],
|
|
23
23
|
asynchronous: true,
|
|
24
|
-
}) as SubProcess;
|
|
24
|
+
})) as SubProcess;
|
|
25
25
|
await pbCopySubprocess.start(0);
|
|
26
26
|
const exitCodeVerifier = pbCopySubprocess.join();
|
|
27
27
|
const stdin = pbCopySubprocess.proc?.stdin;
|
|
@@ -32,4 +32,3 @@ export async function setPasteboard (
|
|
|
32
32
|
}
|
|
33
33
|
await exitCodeVerifier;
|
|
34
34
|
}
|
|
35
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Get the content of Simulator pasteboard.
|
|
@@ -12,11 +12,13 @@ import type { Simctl } from '../simctl';
|
|
|
12
12
|
* returns non-zero return code.
|
|
13
13
|
* @throws {Error} If the `udid` instance property is unset
|
|
14
14
|
*/
|
|
15
|
-
export async function getPasteboard
|
|
15
|
+
export async function getPasteboard(
|
|
16
|
+
this: Simctl,
|
|
17
|
+
encoding: BufferEncoding = 'utf8',
|
|
18
|
+
): Promise<string> {
|
|
16
19
|
const {stdout} = await this.exec('pbpaste', {
|
|
17
20
|
args: [this.requireUdid('pbpaste')],
|
|
18
21
|
encoding,
|
|
19
22
|
});
|
|
20
23
|
return stdout;
|
|
21
24
|
}
|
|
22
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {Simctl} from '../simctl';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Grants the given permission on the app with the given bundle identifier
|
|
@@ -24,7 +24,7 @@ import type { Simctl } from '../simctl';
|
|
|
24
24
|
* or there was an error while granting the permission
|
|
25
25
|
* @throws {Error} If the `udid` instance property is unset
|
|
26
26
|
*/
|
|
27
|
-
export async function grantPermission
|
|
27
|
+
export async function grantPermission(this: Simctl, bundleId: string, perm: string): Promise<void> {
|
|
28
28
|
await this.exec('privacy', {
|
|
29
29
|
args: [this.requireUdid('privacy grant'), 'grant', perm, bundleId],
|
|
30
30
|
});
|
|
@@ -42,7 +42,11 @@ export async function grantPermission (this: Simctl, bundleId: string, perm: str
|
|
|
42
42
|
* or there was an error while revoking the permission
|
|
43
43
|
* @throws {Error} If the `udid` instance property is unset
|
|
44
44
|
*/
|
|
45
|
-
export async function revokePermission
|
|
45
|
+
export async function revokePermission(
|
|
46
|
+
this: Simctl,
|
|
47
|
+
bundleId: string,
|
|
48
|
+
perm: string,
|
|
49
|
+
): Promise<void> {
|
|
46
50
|
await this.exec('privacy', {
|
|
47
51
|
args: [this.requireUdid('privacy revoke'), 'revoke', perm, bundleId],
|
|
48
52
|
});
|
|
@@ -60,9 +64,8 @@ export async function revokePermission (this: Simctl, bundleId: string, perm: st
|
|
|
60
64
|
* or there was an error while resetting the permission
|
|
61
65
|
* @throws {Error} If the `udid` instance property is unset
|
|
62
66
|
*/
|
|
63
|
-
export async function resetPermission
|
|
67
|
+
export async function resetPermission(this: Simctl, bundleId: string, perm: string): Promise<void> {
|
|
64
68
|
await this.exec('privacy', {
|
|
65
69
|
args: [this.requireUdid('private reset'), 'reset', perm, bundleId],
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
|
-
|