@react-native-harness/cli 1.0.0-alpha.19 → 1.0.0-alpha.20
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/dist/bundlers/metro.d.ts +2 -2
- package/dist/bundlers/metro.d.ts.map +1 -1
- package/dist/bundlers/metro.js +47 -24
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +140 -0
- package/dist/discovery/index.d.ts +3 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +1 -0
- package/dist/discovery/testDiscovery.d.ts +11 -0
- package/dist/discovery/testDiscovery.d.ts.map +1 -0
- package/dist/discovery/testDiscovery.js +29 -0
- package/dist/errors/appNotInstalledError.d.ts +7 -0
- package/dist/errors/appNotInstalledError.d.ts.map +1 -0
- package/dist/errors/appNotInstalledError.js +12 -0
- package/dist/errors/bridgeTimeoutError.d.ts +7 -0
- package/dist/errors/bridgeTimeoutError.d.ts.map +1 -0
- package/dist/errors/bridgeTimeoutError.js +12 -0
- package/dist/errors/errorHandler.d.ts +2 -0
- package/dist/errors/errorHandler.d.ts.map +1 -0
- package/dist/errors/errorHandler.js +152 -0
- package/dist/errors/errors.d.ts +45 -0
- package/dist/errors/errors.d.ts.map +1 -0
- package/dist/errors/errors.js +89 -0
- package/dist/jest.d.ts +2 -0
- package/dist/jest.d.ts.map +1 -0
- package/dist/jest.js +7 -0
- package/dist/platforms/android/build.d.ts +3 -2
- package/dist/platforms/android/build.d.ts.map +1 -1
- package/dist/platforms/android/build.js +24 -49
- package/dist/platforms/android/device.d.ts +5 -0
- package/dist/platforms/android/device.d.ts.map +1 -0
- package/dist/platforms/android/device.js +36 -0
- package/dist/platforms/android/emulator.d.ts +0 -1
- package/dist/platforms/android/emulator.d.ts.map +1 -1
- package/dist/platforms/android/emulator.js +101 -132
- package/dist/platforms/android/index.d.ts.map +1 -1
- package/dist/platforms/android/index.js +23 -19
- package/dist/platforms/ios/build.d.ts +5 -7
- package/dist/platforms/ios/build.d.ts.map +1 -1
- package/dist/platforms/ios/build.js +41 -116
- package/dist/platforms/ios/device.d.ts +11 -0
- package/dist/platforms/ios/device.d.ts.map +1 -0
- package/dist/platforms/ios/device.js +51 -0
- package/dist/platforms/ios/index.d.ts.map +1 -1
- package/dist/platforms/ios/index.js +24 -32
- package/dist/platforms/ios/simulator.d.ts +4 -4
- package/dist/platforms/ios/simulator.d.ts.map +1 -1
- package/dist/platforms/ios/simulator.js +104 -131
- package/dist/platforms/platform-adapter.d.ts +2 -4
- package/dist/platforms/platform-adapter.d.ts.map +1 -1
- package/dist/platforms/platform-registry.d.ts.map +1 -1
- package/dist/platforms/platform-registry.js +5 -1
- package/dist/platforms/vega/build.d.ts +23 -0
- package/dist/platforms/vega/build.d.ts.map +1 -0
- package/dist/platforms/vega/build.js +55 -0
- package/dist/platforms/vega/device.d.ts +57 -0
- package/dist/platforms/vega/device.d.ts.map +1 -0
- package/dist/platforms/vega/device.js +206 -0
- package/dist/platforms/vega/index.d.ts +4 -0
- package/dist/platforms/vega/index.d.ts.map +1 -0
- package/dist/platforms/vega/index.js +75 -0
- package/dist/platforms/web/index.d.ts +3 -1
- package/dist/platforms/web/index.d.ts.map +1 -1
- package/dist/platforms/web/index.js +9 -50
- package/dist/process.js +1 -1
- package/dist/reporters/default-reporter.d.ts.map +1 -1
- package/dist/reporters/default-reporter.js +22 -17
- package/dist/reporters/junit-reporter.d.ts +3 -0
- package/dist/reporters/junit-reporter.d.ts.map +1 -0
- package/dist/reporters/junit-reporter.js +119 -0
- package/dist/reporters/live-reporter.d.ts +20 -0
- package/dist/reporters/live-reporter.d.ts.map +1 -0
- package/dist/reporters/live-reporter.js +176 -0
- package/dist/src/reporters/default-reporter.js +135 -0
- package/dist/test-reporter-demo.js +95 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/utils/status-formatter.d.ts +27 -0
- package/dist/utils/status-formatter.d.ts.map +1 -0
- package/dist/utils/status-formatter.js +54 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +26 -0
- package/package.json +3 -3
|
@@ -1,123 +1,48 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { spawn, spawnAndForget } from '@react-native-harness/tools';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
3
|
export const listDevices = async () => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
export const getDeviceByName = async (simulatorName) => {
|
|
21
|
-
try {
|
|
22
|
-
const devices = await listDevices();
|
|
23
|
-
for (const runtime in devices.devices) {
|
|
24
|
-
const runtimeDevices = devices.devices[runtime];
|
|
25
|
-
for (const device of runtimeDevices) {
|
|
26
|
-
if (device.name === simulatorName && device.isAvailable) {
|
|
27
|
-
return device;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
4
|
+
const { stdout } = await spawn('xcrun', [
|
|
5
|
+
'simctl',
|
|
6
|
+
'list',
|
|
7
|
+
'devices',
|
|
8
|
+
'--json',
|
|
9
|
+
]);
|
|
10
|
+
return JSON.parse(stdout);
|
|
11
|
+
};
|
|
12
|
+
export const getDeviceByName = async (simulatorName, systemVersion
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
) => {
|
|
15
|
+
const devices = await listDevices();
|
|
16
|
+
const expectedRuntimeId = `com.apple.CoreSimulator.SimRuntime.iOS-${systemVersion.replace(/\./, '-')}`;
|
|
17
|
+
const runtime = devices.devices[expectedRuntimeId];
|
|
18
|
+
if (!runtime) {
|
|
31
19
|
return null;
|
|
32
20
|
}
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
const runtimeDevices = devices.devices[runtime];
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
const device = runtimeDevices.find((d) => d.name === simulatorName);
|
|
24
|
+
if (device) {
|
|
25
|
+
return device;
|
|
35
26
|
}
|
|
36
|
-
|
|
37
|
-
export const installPods = async () => {
|
|
38
|
-
return new Promise((resolve, reject) => {
|
|
39
|
-
exec('cd ios && bundle exec pod install', (error) => {
|
|
40
|
-
if (error) {
|
|
41
|
-
console.warn('CocoaPods install failed:', error.message);
|
|
42
|
-
reject(error);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
resolve();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
27
|
+
return null;
|
|
48
28
|
};
|
|
49
29
|
export const listApps = async (udid) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
export const buildIOSApp = async (simulatorName, maxRetries = 2) => {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
let attempts = 0;
|
|
76
|
-
const attemptBuild = async () => {
|
|
77
|
-
attempts++;
|
|
78
|
-
try {
|
|
79
|
-
await installPods();
|
|
80
|
-
}
|
|
81
|
-
catch { }
|
|
82
|
-
exec(`npx react-native run-ios --simulator="${simulatorName}" --no-packager`, async (error) => {
|
|
83
|
-
if (error) {
|
|
84
|
-
if (attempts <= maxRetries) {
|
|
85
|
-
try {
|
|
86
|
-
await reloadApp(8081);
|
|
87
|
-
setTimeout(attemptBuild, 3000);
|
|
88
|
-
}
|
|
89
|
-
catch (reloadError) {
|
|
90
|
-
setTimeout(attemptBuild, 3000);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
reject(error);
|
|
95
|
-
}
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
resolve();
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
attemptBuild();
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
export const runApp = async (simulatorName, appName) => {
|
|
105
|
-
return new Promise((resolve, reject) => {
|
|
106
|
-
exec(`xcrun simctl terminate "${simulatorName}" ${appName}`, () => {
|
|
107
|
-
exec(`xcrun simctl launch "${simulatorName}" ${appName}`, (error) => {
|
|
108
|
-
if (error) {
|
|
109
|
-
reject(error);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
resolve();
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
export const killApp = async (simulatorName, appName) => {
|
|
118
|
-
return new Promise((resolve) => {
|
|
119
|
-
exec(`xcrun simctl terminate "${simulatorName}" ${appName}`, () => {
|
|
120
|
-
resolve();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
30
|
+
const { stdout: plistOutput } = await spawn('xcrun', [
|
|
31
|
+
'simctl',
|
|
32
|
+
'listapps',
|
|
33
|
+
udid,
|
|
34
|
+
]);
|
|
35
|
+
const { stdout: jsonOutput } = await spawn('plutil', ['-convert', 'json', '-o', '-', '-'], { stdin: { string: plistOutput } });
|
|
36
|
+
return Object.keys(JSON.parse(jsonOutput));
|
|
37
|
+
};
|
|
38
|
+
export const isAppInstalled = async (udid, bundleId) => {
|
|
39
|
+
const appList = await listApps(udid);
|
|
40
|
+
return appList.includes(bundleId);
|
|
41
|
+
};
|
|
42
|
+
export const runApp = async (udid, appName) => {
|
|
43
|
+
await killApp(udid, appName);
|
|
44
|
+
await spawn('xcrun', ['simctl', 'launch', udid, appName]);
|
|
45
|
+
};
|
|
46
|
+
export const killApp = async (udid, appName) => {
|
|
47
|
+
await spawnAndForget('xcrun', ['simctl', 'terminate', udid, appName]);
|
|
123
48
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Device = any;
|
|
2
|
+
export declare const listDevices: () => Promise<{
|
|
3
|
+
devices: Device[];
|
|
4
|
+
}>;
|
|
5
|
+
export declare const getDeviceByName: (simulatorName: string) => Promise<Device | null>;
|
|
6
|
+
export declare const listApps: (udid: string) => Promise<string[]>;
|
|
7
|
+
export declare const isAppInstalled: (simulatorName: string, bundleId: string) => Promise<boolean>;
|
|
8
|
+
export declare const runApp: (simulatorName: string, appName: string) => Promise<void>;
|
|
9
|
+
export declare const killApp: (simulatorName: string, appName: string) => Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/device.ts"],"names":[],"mappings":"AAGA,KAAK,MAAM,GAAG,GAAG,CAAC;AAElB,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAQjE,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAavB,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAY7D,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,eAAe,MAAM,EACrB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CASjB,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,OAAO,CAAC,IAAI,CAGd,CAAC;AAEF,eAAO,MAAM,OAAO,GAClB,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,OAAO,CAAC,IAAI,CAOd,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { spawn, spawnAndForget } from '@react-native-harness/tools';
|
|
2
|
+
export const listDevices = async () => {
|
|
3
|
+
const { stdout } = await spawn('xcrun', [
|
|
4
|
+
'simctl',
|
|
5
|
+
'list',
|
|
6
|
+
'devices',
|
|
7
|
+
'--json',
|
|
8
|
+
]);
|
|
9
|
+
return JSON.parse(stdout);
|
|
10
|
+
};
|
|
11
|
+
export const getDeviceByName = async (simulatorName) => {
|
|
12
|
+
const devices = await listDevices();
|
|
13
|
+
for (const runtime in devices.devices) {
|
|
14
|
+
const runtimeDevices = devices.devices[runtime];
|
|
15
|
+
for (const device of runtimeDevices) {
|
|
16
|
+
if (device.name === simulatorName && device.isAvailable) {
|
|
17
|
+
return device;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
};
|
|
23
|
+
export const listApps = async (udid) => {
|
|
24
|
+
const { stdout: plistOutput } = await spawn('xcrun', [
|
|
25
|
+
'simctl',
|
|
26
|
+
'listapps',
|
|
27
|
+
udid,
|
|
28
|
+
]);
|
|
29
|
+
const { stdout: jsonOutput } = await spawn('plutil', ['-convert', 'json', '-o', '-', '-'], { stdin: { string: plistOutput } });
|
|
30
|
+
return Object.keys(JSON.parse(jsonOutput));
|
|
31
|
+
};
|
|
32
|
+
export const isAppInstalled = async (simulatorName, bundleId) => {
|
|
33
|
+
const device = await getDeviceByName(simulatorName);
|
|
34
|
+
if (!device) {
|
|
35
|
+
throw new Error(`Simulator ${simulatorName} not found`);
|
|
36
|
+
}
|
|
37
|
+
const appList = await listApps(device.udid);
|
|
38
|
+
return appList.includes(bundleId);
|
|
39
|
+
};
|
|
40
|
+
export const runApp = async (simulatorName, appName) => {
|
|
41
|
+
await killApp(simulatorName, appName);
|
|
42
|
+
await spawn('xcrun', ['simctl', 'launch', simulatorName, appName]);
|
|
43
|
+
};
|
|
44
|
+
export const killApp = async (simulatorName, appName) => {
|
|
45
|
+
await spawnAndForget('xcrun', [
|
|
46
|
+
'simctl',
|
|
47
|
+
'terminate',
|
|
48
|
+
simulatorName,
|
|
49
|
+
appName,
|
|
50
|
+
]);
|
|
51
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAa9D,QAAA,MAAM,kBAAkB,EAAE,eA8CzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,50 +1,42 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { buildIOSApp, isAppInstalled, runApp, killApp } from './build.js';
|
|
1
|
+
import { assertIOSRunnerConfig, } from '@react-native-harness/config';
|
|
2
|
+
import { getSimulatorDeviceId, getSimulatorStatus, runSimulator, stopSimulator, } from './simulator.js';
|
|
3
|
+
import { isAppInstalled, runApp, killApp } from './build.js';
|
|
5
4
|
import { killWithAwait } from '../../process.js';
|
|
6
5
|
import { runMetro } from '../../bundlers/metro.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const result = await fn();
|
|
10
|
-
const end = performance.now();
|
|
11
|
-
console.log(`${name} took ${end - start}ms`);
|
|
12
|
-
return result;
|
|
13
|
-
};
|
|
6
|
+
import { AppNotInstalledError } from '../../errors/errors.js';
|
|
7
|
+
import { assert } from '../../utils.js';
|
|
14
8
|
const iosPlatformAdapter = {
|
|
15
9
|
name: 'ios',
|
|
16
|
-
getEnvironment: async (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
10
|
+
getEnvironment: async (runner) => {
|
|
11
|
+
assertIOSRunnerConfig(runner);
|
|
12
|
+
// TODO: system version is also important as there may be two emulators with the same name
|
|
13
|
+
// but different system versions
|
|
14
|
+
let shouldStopSimulator = false;
|
|
15
|
+
const udid = await getSimulatorDeviceId(runner.deviceId, runner.systemVersion);
|
|
16
|
+
assert(!!udid, 'Simulator not found');
|
|
17
|
+
const simulatorStatus = await getSimulatorStatus(udid);
|
|
20
18
|
const metroPromise = runMetro();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
console.log('simulator started');
|
|
25
|
-
const isInstalled = await measure(() => isAppInstalled(config.runner.deviceId, config.runner.bundleId), 'isAppInstalled');
|
|
26
|
-
console.log(isInstalled);
|
|
27
|
-
if (!isInstalled) {
|
|
28
|
-
await buildIOSApp(config.runner.deviceId);
|
|
19
|
+
if (simulatorStatus === 'stopped') {
|
|
20
|
+
await runSimulator(udid);
|
|
21
|
+
shouldStopSimulator = true;
|
|
29
22
|
}
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
const isInstalled = await isAppInstalled(udid, runner.bundleId);
|
|
24
|
+
if (!isInstalled) {
|
|
25
|
+
throw new AppNotInstalledError(runner.deviceId, runner.bundleId, 'ios');
|
|
32
26
|
}
|
|
33
|
-
const interactionEngine = await interactionEnginePromise;
|
|
34
27
|
const metro = await metroPromise;
|
|
28
|
+
await runApp(udid, runner.bundleId);
|
|
35
29
|
return {
|
|
36
30
|
restart: async () => {
|
|
37
|
-
await runApp(
|
|
31
|
+
await runApp(udid, runner.bundleId);
|
|
38
32
|
},
|
|
39
33
|
dispose: async () => {
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
await killApp(udid, runner.bundleId);
|
|
35
|
+
if (shouldStopSimulator) {
|
|
36
|
+
await stopSimulator(udid);
|
|
42
37
|
}
|
|
43
|
-
await interactionEngine.close();
|
|
44
38
|
await killWithAwait(metro);
|
|
45
|
-
await killApp(config.runner.deviceId, config.runner.bundleId);
|
|
46
39
|
},
|
|
47
|
-
interactionEngine,
|
|
48
40
|
};
|
|
49
41
|
},
|
|
50
42
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type IOSSimulatorStatus = 'stopped' | 'loading' | 'running';
|
|
2
|
-
export declare const getSimulatorDeviceId: (simulatorName: string) => Promise<string | null>;
|
|
2
|
+
export declare const getSimulatorDeviceId: (simulatorName: string, systemVersion: string) => Promise<string | null>;
|
|
3
3
|
export declare const getAvailableSimulators: () => Promise<Array<{
|
|
4
4
|
name: string;
|
|
5
5
|
udid: string;
|
|
6
6
|
runtime: string;
|
|
7
7
|
}>>;
|
|
8
|
-
export declare const getSimulatorStatus: (
|
|
9
|
-
export declare const runSimulator: (
|
|
10
|
-
export declare const stopSimulator: (
|
|
8
|
+
export declare const getSimulatorStatus: (udid: string) => Promise<IOSSimulatorStatus>;
|
|
9
|
+
export declare const runSimulator: (udid: string) => Promise<void>;
|
|
10
|
+
export declare const stopSimulator: (udid: string) => Promise<void>;
|
|
11
11
|
//# sourceMappingURL=simulator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/simulator.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnE,eAAO,MAAM,oBAAoB,GAC/B,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/simulator.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnE,eAAO,MAAM,oBAAoB,GAC/B,eAAe,MAAM,EACrB,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CA+BvB,CAAC;AAEF,eAAO,MAAM,sBAAsB,QAAa,OAAO,CACrD,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCvD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,MAAM,KACX,OAAO,CAAC,kBAAkB,CAiC5B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAkC7D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAE9D,CAAC"}
|
|
@@ -1,128 +1,108 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const getSimulatorDeviceId = (simulatorName) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
});
|
|
1
|
+
import { spawn, SubprocessError } from '@react-native-harness/tools';
|
|
2
|
+
export const getSimulatorDeviceId = async (simulatorName, systemVersion) => {
|
|
3
|
+
try {
|
|
4
|
+
const { stdout } = await spawn('xcrun', [
|
|
5
|
+
'simctl',
|
|
6
|
+
'list',
|
|
7
|
+
'devices',
|
|
8
|
+
'--json',
|
|
9
|
+
]);
|
|
10
|
+
const devices = JSON.parse(stdout);
|
|
11
|
+
const expectedRuntimeId = `com.apple.CoreSimulator.SimRuntime.iOS-${systemVersion.replace(/\./, '-')}`;
|
|
12
|
+
const runtime = devices.devices[expectedRuntimeId];
|
|
13
|
+
if (!runtime) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
const device = runtime.find((d) => d.name === simulatorName);
|
|
18
|
+
if (device) {
|
|
19
|
+
return device.udid;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
29
26
|
};
|
|
30
|
-
export const getAvailableSimulators = () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
27
|
+
export const getAvailableSimulators = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const { stdout } = await spawn('xcrun', [
|
|
30
|
+
'simctl',
|
|
31
|
+
'list',
|
|
32
|
+
'devices',
|
|
33
|
+
'--json',
|
|
34
|
+
]);
|
|
35
|
+
const devices = JSON.parse(stdout);
|
|
36
|
+
const simulators = [];
|
|
37
|
+
for (const runtime in devices.devices) {
|
|
38
|
+
if (runtime.includes('iOS')) {
|
|
39
|
+
const runtimeDevices = devices.devices[runtime];
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
runtimeDevices.forEach((device) => {
|
|
42
|
+
if (device.isAvailable) {
|
|
43
|
+
simulators.push({
|
|
44
|
+
name: device.name,
|
|
45
|
+
udid: device.udid,
|
|
46
|
+
runtime: runtime,
|
|
51
47
|
});
|
|
52
48
|
}
|
|
53
|
-
}
|
|
54
|
-
resolve(simulators);
|
|
49
|
+
});
|
|
55
50
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
}
|
|
52
|
+
return simulators;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
61
57
|
};
|
|
62
|
-
export const getSimulatorStatus = (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
resolve('stopped');
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
58
|
+
export const getSimulatorStatus = async (udid) => {
|
|
59
|
+
try {
|
|
60
|
+
const { stdout } = await spawn('xcrun', [
|
|
61
|
+
'simctl',
|
|
62
|
+
'list',
|
|
63
|
+
'devices',
|
|
64
|
+
'--json',
|
|
65
|
+
]);
|
|
66
|
+
const devices = JSON.parse(stdout);
|
|
67
|
+
for (const runtime in devices.devices) {
|
|
68
|
+
if (runtime.includes('iOS')) {
|
|
69
|
+
const runtimeDevices = devices.devices[runtime];
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
const device = runtimeDevices.find((d) => d.udid === udid);
|
|
72
|
+
if (device) {
|
|
73
|
+
switch (device.state) {
|
|
74
|
+
case 'Booted':
|
|
75
|
+
return 'running';
|
|
76
|
+
case 'Booting':
|
|
77
|
+
return 'loading';
|
|
78
|
+
default:
|
|
79
|
+
return 'stopped';
|
|
88
80
|
}
|
|
89
81
|
}
|
|
90
|
-
resolve('stopped');
|
|
91
82
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
}
|
|
84
|
+
return 'stopped';
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return 'stopped';
|
|
88
|
+
}
|
|
97
89
|
};
|
|
98
|
-
export const runSimulator = async (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
throw new Error('Simulator not found');
|
|
90
|
+
export const runSimulator = async (udid) => {
|
|
91
|
+
try {
|
|
92
|
+
await spawn('xcrun', ['simctl', 'boot', udid]);
|
|
102
93
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
await new Promise((resolve, reject) => {
|
|
114
|
-
exec('open -a Simulator', (error) => {
|
|
115
|
-
if (error) {
|
|
116
|
-
reject(error);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
resolve();
|
|
120
|
-
});
|
|
121
|
-
});
|
|
94
|
+
catch (bootError) {
|
|
95
|
+
// Ignore if simulator is already booted
|
|
96
|
+
if (bootError instanceof SubprocessError &&
|
|
97
|
+
!bootError.stderr?.includes('Unable to boot device in current state: Booted')) {
|
|
98
|
+
throw bootError;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
await spawn('open', ['-a', 'Simulator']);
|
|
122
102
|
let attempts = 0;
|
|
123
103
|
while (true) {
|
|
124
104
|
attempts++;
|
|
125
|
-
const status = await getSimulatorStatus(
|
|
105
|
+
const status = await getSimulatorStatus(udid);
|
|
126
106
|
if (status === 'running') {
|
|
127
107
|
break;
|
|
128
108
|
}
|
|
@@ -132,25 +112,18 @@ export const runSimulator = async (name) => {
|
|
|
132
112
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
133
113
|
}
|
|
134
114
|
};
|
|
135
|
-
export const stopSimulator = (
|
|
136
|
-
|
|
137
|
-
getSimulatorDeviceId(name).then((simulatorId) => {
|
|
138
|
-
if (!simulatorId) {
|
|
139
|
-
resolve(); // Already stopped
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
stopSimulatorById(simulatorId, resolve, reject);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
115
|
+
export const stopSimulator = async (udid) => {
|
|
116
|
+
await stopSimulatorById(udid);
|
|
145
117
|
};
|
|
146
|
-
const stopSimulatorById = (
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
118
|
+
const stopSimulatorById = async (udid) => {
|
|
119
|
+
try {
|
|
120
|
+
await spawn('xcrun', ['simctl', 'shutdown', udid]);
|
|
121
|
+
}
|
|
122
|
+
catch (shutdownError) {
|
|
123
|
+
// Ignore if simulator is already shut down
|
|
124
|
+
if (shutdownError instanceof SubprocessError &&
|
|
125
|
+
!shutdownError.stderr?.includes('Unable to shutdown device in current state: Shutdown')) {
|
|
126
|
+
throw shutdownError;
|
|
153
127
|
}
|
|
154
|
-
|
|
155
|
-
});
|
|
128
|
+
}
|
|
156
129
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { InteractionEngine } from '@react-native-harness/interaction-engine';
|
|
1
|
+
import { TestRunnerConfig } from '@react-native-harness/config';
|
|
3
2
|
export type Environment = {
|
|
4
3
|
restart: () => Promise<void>;
|
|
5
4
|
dispose: () => Promise<void>;
|
|
6
|
-
interactionEngine: InteractionEngine;
|
|
7
5
|
};
|
|
8
6
|
export type PlatformAdapter = {
|
|
9
7
|
name: string;
|
|
10
|
-
getEnvironment: (
|
|
8
|
+
getEnvironment: (runner: TestRunnerConfig) => Promise<Environment>;
|
|
11
9
|
};
|
|
12
10
|
//# sourceMappingURL=platform-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-adapter.d.ts","sourceRoot":"","sources":["../../src/platforms/platform-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"platform-adapter.d.ts","sourceRoot":"","sources":["../../src/platforms/platform-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACpE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-registry.d.ts","sourceRoot":"","sources":["../../src/platforms/platform-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"platform-registry.d.ts","sourceRoot":"","sources":["../../src/platforms/platform-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAaxD,eAAO,MAAM,kBAAkB,GAC7B,cAAc,MAAM,KACnB,OAAO,CAAC,eAAe,CAUzB,CAAC"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import androidPlatformAdapter from './android/index.js';
|
|
2
2
|
import iosPlatformAdapter from './ios/index.js';
|
|
3
|
+
import webPlatformAdapter from './web/index.js';
|
|
4
|
+
import vegaPlatformAdapter from './vega/index.js';
|
|
3
5
|
const platformAdapters = {
|
|
4
6
|
android: androidPlatformAdapter,
|
|
5
7
|
ios: iosPlatformAdapter,
|
|
8
|
+
web: webPlatformAdapter,
|
|
9
|
+
vega: vegaPlatformAdapter,
|
|
6
10
|
};
|
|
7
11
|
export const getPlatformAdapter = async (platformName) => {
|
|
8
12
|
if (!(platformName in platformAdapters)) {
|
|
@@ -11,7 +15,7 @@ export const getPlatformAdapter = async (platformName) => {
|
|
|
11
15
|
try {
|
|
12
16
|
return platformAdapters[platformName];
|
|
13
17
|
}
|
|
14
|
-
catch
|
|
18
|
+
catch {
|
|
15
19
|
throw new Error(`Platform adapter for ${platformName} not found`);
|
|
16
20
|
}
|
|
17
21
|
};
|