@react-native-harness/cli 1.0.0-canary.1764675030942 → 1.0.0-canary.1766225407244
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 +24 -47
- package/dist/platforms/android/build.d.ts +2 -3
- package/dist/platforms/android/build.d.ts.map +1 -1
- package/dist/platforms/android/build.js +49 -24
- package/dist/platforms/android/emulator.d.ts +1 -0
- package/dist/platforms/android/emulator.d.ts.map +1 -1
- package/dist/platforms/android/emulator.js +132 -101
- package/dist/platforms/android/index.d.ts.map +1 -1
- package/dist/platforms/android/index.js +19 -23
- package/dist/platforms/ios/build.d.ts +7 -5
- package/dist/platforms/ios/build.d.ts.map +1 -1
- package/dist/platforms/ios/build.js +116 -41
- package/dist/platforms/ios/index.d.ts.map +1 -1
- package/dist/platforms/ios/index.js +32 -24
- 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 +131 -104
- package/dist/platforms/platform-adapter.d.ts +4 -2
- 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 +1 -5
- package/dist/platforms/web/index.d.ts +1 -3
- package/dist/platforms/web/index.d.ts.map +1 -1
- package/dist/platforms/web/index.js +50 -9
- package/dist/process.js +1 -1
- package/dist/reporters/default-reporter.d.ts.map +1 -1
- package/dist/reporters/default-reporter.js +17 -22
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/commands/test.d.ts +0 -3
- package/dist/commands/test.d.ts.map +0 -1
- package/dist/commands/test.js +0 -140
- package/dist/discovery/index.d.ts +0 -3
- package/dist/discovery/index.d.ts.map +0 -1
- package/dist/discovery/index.js +0 -1
- package/dist/discovery/testDiscovery.d.ts +0 -11
- package/dist/discovery/testDiscovery.d.ts.map +0 -1
- package/dist/discovery/testDiscovery.js +0 -29
- package/dist/errors/appNotInstalledError.d.ts +0 -7
- package/dist/errors/appNotInstalledError.d.ts.map +0 -1
- package/dist/errors/appNotInstalledError.js +0 -12
- package/dist/errors/bridgeTimeoutError.d.ts +0 -7
- package/dist/errors/bridgeTimeoutError.d.ts.map +0 -1
- package/dist/errors/bridgeTimeoutError.js +0 -12
- package/dist/errors/errorHandler.d.ts +0 -2
- package/dist/errors/errorHandler.d.ts.map +0 -1
- package/dist/errors/errorHandler.js +0 -152
- package/dist/errors/errors.d.ts +0 -45
- package/dist/errors/errors.d.ts.map +0 -1
- package/dist/errors/errors.js +0 -89
- package/dist/jest.d.ts +0 -2
- package/dist/jest.d.ts.map +0 -1
- package/dist/jest.js +0 -7
- package/dist/platforms/android/device.d.ts +0 -5
- package/dist/platforms/android/device.d.ts.map +0 -1
- package/dist/platforms/android/device.js +0 -36
- package/dist/platforms/ios/device.d.ts +0 -11
- package/dist/platforms/ios/device.d.ts.map +0 -1
- package/dist/platforms/ios/device.js +0 -51
- package/dist/platforms/vega/build.d.ts +0 -23
- package/dist/platforms/vega/build.d.ts.map +0 -1
- package/dist/platforms/vega/build.js +0 -55
- package/dist/platforms/vega/device.d.ts +0 -57
- package/dist/platforms/vega/device.d.ts.map +0 -1
- package/dist/platforms/vega/device.js +0 -206
- package/dist/platforms/vega/index.d.ts +0 -4
- package/dist/platforms/vega/index.d.ts.map +0 -1
- package/dist/platforms/vega/index.js +0 -75
- package/dist/reporters/junit-reporter.d.ts +0 -3
- package/dist/reporters/junit-reporter.d.ts.map +0 -1
- package/dist/reporters/junit-reporter.js +0 -119
- package/dist/reporters/live-reporter.d.ts +0 -20
- package/dist/reporters/live-reporter.d.ts.map +0 -1
- package/dist/reporters/live-reporter.js +0 -176
- package/dist/src/reporters/default-reporter.js +0 -135
- package/dist/test-reporter-demo.js +0 -95
- package/dist/utils/status-formatter.d.ts +0 -27
- package/dist/utils/status-formatter.d.ts.map +0 -1
- package/dist/utils/status-formatter.js +0 -54
- package/dist/utils.d.ts +0 -6
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -26
package/dist/bundlers/metro.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ChildProcess } from 'node:child_process';
|
|
2
|
-
export declare const runMetro: (
|
|
2
|
+
export declare const runMetro: () => Promise<ChildProcess>;
|
|
3
3
|
export declare const waitForMetro: (port?: number, maxRetries?: number, retryDelay?: number) => Promise<void>;
|
|
4
|
-
export declare const reloadApp: () => Promise<void>;
|
|
4
|
+
export declare const reloadApp: (port?: number) => Promise<void>;
|
|
5
5
|
//# sourceMappingURL=metro.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metro.d.ts","sourceRoot":"","sources":["../../src/bundlers/metro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"metro.d.ts","sourceRoot":"","sources":["../../src/bundlers/metro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAQ9D,eAAO,MAAM,QAAQ,QAAa,OAAO,CAAC,YAAY,CAmBrD,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAM,MAAa,EACnB,aAAY,MAAW,EACvB,aAAY,MAAa,KACxB,OAAO,CAAC,IAAI,CA0Bd,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,aAAW,KAAG,OAAO,CAAC,IAAI,CAEzD,CAAC"}
|
package/dist/bundlers/metro.js
CHANGED
|
@@ -1,48 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (childProcess.stdout) {
|
|
21
|
-
childProcess.stdout.on('data', (data) => {
|
|
22
|
-
logger.debug(data.toString().trim());
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
if (childProcess.stderr) {
|
|
26
|
-
childProcess.stderr.on('data', (data) => {
|
|
27
|
-
logger.debug(data.toString().trim());
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
metro.catch((error) => {
|
|
32
|
-
// This process is going to be killed by us, so we don't need to throw an error
|
|
33
|
-
if (error instanceof SubprocessError && error.signalName === 'SIGTERM') {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
logger.error('Metro crashed unexpectedly', error);
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
const getTimeoutSignal = (timeout) => {
|
|
3
|
+
const controller = new AbortController();
|
|
4
|
+
setTimeout(() => controller.abort(), timeout);
|
|
5
|
+
return controller.signal;
|
|
6
|
+
};
|
|
7
|
+
export const runMetro = async () => {
|
|
8
|
+
const metro = await new Promise((resolve, reject) => {
|
|
9
|
+
const metroProcess = spawn('npx', ['react-native', 'start'], {
|
|
10
|
+
stdio: 'ignore',
|
|
11
|
+
env: {
|
|
12
|
+
...process.env,
|
|
13
|
+
RN_HARNESS: 'true',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
metroProcess.on('error', (error) => {
|
|
17
|
+
reject(new Error(`Failed to start Metro: ${error.message}`));
|
|
18
|
+
});
|
|
19
|
+
resolve(metroProcess);
|
|
37
20
|
});
|
|
38
|
-
const isDefaultPortAvailable = await isPortAvailable(METRO_PORT);
|
|
39
|
-
if (!isDefaultPortAvailable) {
|
|
40
|
-
throw new MetroPortUnavailableError(METRO_PORT);
|
|
41
|
-
}
|
|
42
21
|
await waitForMetro();
|
|
43
|
-
return metro
|
|
22
|
+
return metro;
|
|
44
23
|
};
|
|
45
|
-
export const waitForMetro = async (port = 8081, maxRetries =
|
|
24
|
+
export const waitForMetro = async (port = 8081, maxRetries = 10, retryDelay = 1000) => {
|
|
46
25
|
let attempts = 0;
|
|
47
26
|
while (attempts < maxRetries) {
|
|
48
27
|
attempts++;
|
|
@@ -57,15 +36,13 @@ export const waitForMetro = async (port = 8081, maxRetries = 20, retryDelay = 10
|
|
|
57
36
|
}
|
|
58
37
|
}
|
|
59
38
|
}
|
|
60
|
-
catch {
|
|
61
|
-
// Errors are expected here, we're just waiting for the process to be ready
|
|
62
|
-
}
|
|
39
|
+
catch { }
|
|
63
40
|
if (attempts < maxRetries) {
|
|
64
41
|
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
65
42
|
}
|
|
66
43
|
}
|
|
67
44
|
throw new Error(`Metro bundler is not ready after ${maxRetries} attempts`);
|
|
68
45
|
};
|
|
69
|
-
export const reloadApp = async () => {
|
|
70
|
-
await fetch(`http://localhost:${
|
|
46
|
+
export const reloadApp = async (port = 8081) => {
|
|
47
|
+
await fetch(`http://localhost:${port}/reload`);
|
|
71
48
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export declare const buildAndroidApp: () => Promise<void>;
|
|
2
|
-
export declare const installApp: (deviceId: string) => Promise<void>;
|
|
1
|
+
export declare const buildAndroidApp: (deviceId: string, maxRetries?: number) => Promise<void>;
|
|
3
2
|
export declare const killApp: (deviceId: string, bundleId: string) => Promise<void>;
|
|
4
|
-
export declare const runApp: (deviceId: string, bundleId: string
|
|
3
|
+
export declare const runApp: (deviceId: string, bundleId: string) => Promise<void>;
|
|
5
4
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/build.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/build.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,mBAAc,KACb,OAAO,CAAC,IAAI,CAiCd,CAAC;AAEF,eAAO,MAAM,OAAO,GAClB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAWd,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAgBd,CAAC"}
|
|
@@ -1,29 +1,54 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
export const buildAndroidApp = async () => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import { reloadApp } from '../../bundlers/metro.js';
|
|
3
|
+
export const buildAndroidApp = async (deviceId, maxRetries = 2) => {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
let attempts = 0;
|
|
6
|
+
const attemptBuild = () => {
|
|
7
|
+
attempts++;
|
|
8
|
+
exec(`react-native run-android --deviceId=${deviceId} --no-packager`, async (error) => {
|
|
9
|
+
if (error) {
|
|
10
|
+
if (attempts <= maxRetries) {
|
|
11
|
+
try {
|
|
12
|
+
await reloadApp(8081);
|
|
13
|
+
// Wait a bit before retrying
|
|
14
|
+
setTimeout(attemptBuild, 3000);
|
|
15
|
+
}
|
|
16
|
+
catch (reloadError) {
|
|
17
|
+
console.warn('Reload failed, retrying build anyway...');
|
|
18
|
+
setTimeout(attemptBuild, 3000);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
reject(error);
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
resolve();
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
attemptBuild();
|
|
30
|
+
});
|
|
14
31
|
};
|
|
15
32
|
export const killApp = async (deviceId, bundleId) => {
|
|
16
|
-
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
exec(`adb -s ${deviceId} shell am force-stop ${bundleId}`, (error) => {
|
|
35
|
+
if (error) {
|
|
36
|
+
reject(error);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
resolve();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
17
42
|
};
|
|
18
|
-
export const runApp = async (deviceId, bundleId
|
|
43
|
+
export const runApp = async (deviceId, bundleId) => {
|
|
19
44
|
await killApp(deviceId, bundleId);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
exec(`adb -s ${deviceId} shell am start -n ${bundleId}/.MainActivity`, (error) => {
|
|
47
|
+
if (error) {
|
|
48
|
+
reject(error);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
29
54
|
};
|
|
@@ -7,4 +7,5 @@ export declare const runEmulator: (name: string) => Promise<ChildProcess>;
|
|
|
7
7
|
export declare const stopEmulator: (avdName: string) => Promise<void>;
|
|
8
8
|
export declare const isAppInstalled: (emulatorId: string, bundleId: string) => Promise<boolean>;
|
|
9
9
|
export declare const reversePort: (port: number) => Promise<void>;
|
|
10
|
+
export declare const getEmulatorScreenshot: (emulatorId: string, name?: string) => Promise<string>;
|
|
10
11
|
//# sourceMappingURL=emulator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/emulator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/emulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAQ,MAAM,oBAAoB,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtE,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,KACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAYvB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,KACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAwBvB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,KACd,OAAO,CAAC,qBAAqB,CAuB/B,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,OAAO,CAAC,YAAY,CAgC9D,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAY1D,CAAC;AAiBF,eAAO,MAAM,cAAc,GACzB,YAAY,MAAM,EAClB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAejB,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAW5D,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,EAClB,OAAM,MAGsB,KAC3B,OAAO,CAAC,MAAM,CAchB,CAAC"}
|
|
@@ -1,116 +1,147 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
2
|
export const getEmulatorNameFromId = async (emulatorId) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
3
|
+
return new Promise((resolve) => {
|
|
4
|
+
exec(`adb -s ${emulatorId} emu avd name`, (error, stdout) => {
|
|
5
|
+
if (error) {
|
|
6
|
+
resolve(null);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const avdName = stdout.split('\n')[0].trim();
|
|
10
|
+
resolve(avdName || null);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
17
13
|
};
|
|
18
14
|
export const getEmulatorDeviceId = async (avdName) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
exec('adb devices', async (error, stdout) => {
|
|
17
|
+
if (error) {
|
|
18
|
+
resolve(null);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const lines = stdout.split('\n');
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
const parts = line.trim().split('\t');
|
|
24
|
+
if (parts.length === 2 && parts[0].startsWith('emulator-')) {
|
|
25
|
+
const emulatorId = parts[0].trim();
|
|
26
|
+
const name = await getEmulatorNameFromId(emulatorId);
|
|
27
|
+
if (name === avdName) {
|
|
28
|
+
resolve(emulatorId);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
33
|
+
resolve(null);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
37
36
|
};
|
|
38
|
-
export const getEmulatorStatus =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return 'loading';
|
|
57
|
-
}
|
|
37
|
+
export const getEmulatorStatus = (avdName) => {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
getEmulatorDeviceId(avdName).then((emulatorId) => {
|
|
40
|
+
if (!emulatorId) {
|
|
41
|
+
resolve('stopped');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Check if device is fully booted by checking boot completion
|
|
45
|
+
exec(`adb -s ${emulatorId} shell getprop sys.boot_completed`, (bootError, bootStdout) => {
|
|
46
|
+
if (bootError) {
|
|
47
|
+
resolve('loading');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const bootCompleted = bootStdout.trim() === '1';
|
|
51
|
+
resolve(bootCompleted ? 'running' : 'loading');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
58
55
|
};
|
|
59
|
-
export const runEmulator =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
56
|
+
export const runEmulator = (name) => {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
// Start the emulator
|
|
59
|
+
const process = exec(`emulator -avd ${name}`, (error) => {
|
|
60
|
+
if (error) {
|
|
61
|
+
reject(error);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
// Poll for emulator status until it's fully running
|
|
66
|
+
const checkStatus = async () => {
|
|
67
|
+
try {
|
|
68
|
+
const status = await getEmulatorStatus(name);
|
|
69
|
+
if (status === 'running') {
|
|
70
|
+
resolve(process);
|
|
71
|
+
}
|
|
72
|
+
else if (status === 'loading') {
|
|
73
|
+
// Check again in 2 seconds
|
|
74
|
+
setTimeout(checkStatus, 2000);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Still stopped, check again in 1 second
|
|
78
|
+
setTimeout(checkStatus, 1000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
reject(error);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
// Start checking status after a brief delay to allow emulator to start
|
|
86
|
+
setTimeout(checkStatus, 3000);
|
|
87
|
+
});
|
|
84
88
|
};
|
|
85
|
-
export const stopEmulator =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
export const stopEmulator = (avdName) => {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
// First, get the emulator device ID
|
|
92
|
+
getEmulatorDeviceId(avdName).then((emulatorId) => {
|
|
93
|
+
if (!emulatorId) {
|
|
94
|
+
resolve(); // No emulator running, nothing to stop
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
stopEmulatorById(emulatorId, resolve, reject);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
92
100
|
};
|
|
93
|
-
const stopEmulatorById =
|
|
101
|
+
const stopEmulatorById = (emulatorId, resolve, reject) => {
|
|
94
102
|
// Stop the emulator using the found ID
|
|
95
|
-
|
|
103
|
+
exec(`adb -s ${emulatorId} emu kill`, (killError) => {
|
|
104
|
+
if (killError) {
|
|
105
|
+
reject(killError);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
resolve();
|
|
109
|
+
});
|
|
96
110
|
};
|
|
97
111
|
export const isAppInstalled = async (emulatorId, bundleId) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return stdout.trim() !== '';
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
exec(`adb -s ${emulatorId} shell pm list packages ${bundleId}`, (error, stdout) => {
|
|
114
|
+
if (error) {
|
|
115
|
+
resolve(false);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const installed = stdout.trim() !== '';
|
|
119
|
+
resolve(installed);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
113
122
|
};
|
|
114
123
|
export const reversePort = async (port) => {
|
|
115
|
-
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
exec(`adb reverse tcp:${port} tcp:${port}`, (error) => {
|
|
126
|
+
if (error) {
|
|
127
|
+
reject(error);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
resolve();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
export const getEmulatorScreenshot = async (emulatorId, name = `${emulatorId}-${new Date()
|
|
135
|
+
.toISOString()
|
|
136
|
+
.replace(/:/g, '-')
|
|
137
|
+
.replace(/\//g, '-')}.png`) => {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
exec(`adb -s ${emulatorId} exec-out screencap -p > ${name}`, (error) => {
|
|
140
|
+
if (error) {
|
|
141
|
+
reject(error);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
resolve(name);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
116
147
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/platforms/android/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAY9D,QAAA,MAAM,sBAAsB,EAAE,eAuD7B,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getAppiumInteractionEngine } from '@react-native-harness/interaction-engine';
|
|
2
|
+
import { assertNativeRunner } from '@react-native-harness/config';
|
|
3
3
|
import { runEmulator, getEmulatorDeviceId, reversePort, isAppInstalled, getEmulatorStatus, } from './emulator.js';
|
|
4
|
-
import { runApp, killApp } from './build.js';
|
|
4
|
+
import { buildAndroidApp, runApp, killApp } from './build.js';
|
|
5
5
|
import { killWithAwait } from '../../process.js';
|
|
6
6
|
import { runMetro } from '../../bundlers/metro.js';
|
|
7
|
-
import { AppNotInstalledError } from '../../errors/errors.js';
|
|
8
7
|
const androidPlatformAdapter = {
|
|
9
8
|
name: 'android',
|
|
10
|
-
getEnvironment: async (
|
|
11
|
-
|
|
9
|
+
getEnvironment: async (config) => {
|
|
10
|
+
assertNativeRunner(config);
|
|
12
11
|
let emulator = null;
|
|
13
|
-
const emulatorStatus = await getEmulatorStatus(runner.deviceId);
|
|
14
|
-
logger.debug(`Emulator status: ${emulatorStatus}`);
|
|
12
|
+
const emulatorStatus = await getEmulatorStatus(config.runner.deviceId);
|
|
15
13
|
const metroPromise = runMetro();
|
|
16
14
|
if (emulatorStatus === 'stopped') {
|
|
17
|
-
|
|
18
|
-
emulator = await runEmulator(runner.deviceId);
|
|
15
|
+
emulator = await runEmulator(config.runner.deviceId);
|
|
19
16
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
17
|
+
const interactionEnginePromise = getAppiumInteractionEngine(config);
|
|
18
|
+
const deviceId = await getEmulatorDeviceId(config.runner.deviceId);
|
|
22
19
|
if (!deviceId) {
|
|
23
20
|
throw new Error('Emulator not found');
|
|
24
21
|
}
|
|
@@ -27,29 +24,28 @@ const androidPlatformAdapter = {
|
|
|
27
24
|
reversePort(8080),
|
|
28
25
|
reversePort(3001),
|
|
29
26
|
]);
|
|
30
|
-
|
|
31
|
-
const isInstalled = await isAppInstalled(deviceId, runner.bundleId);
|
|
32
|
-
logger.debug(`App is installed: ${isInstalled}`);
|
|
27
|
+
const isInstalled = await isAppInstalled(deviceId, config.runner.bundleId);
|
|
33
28
|
if (!isInstalled) {
|
|
34
|
-
|
|
29
|
+
await buildAndroidApp(deviceId);
|
|
35
30
|
}
|
|
36
|
-
|
|
31
|
+
else {
|
|
32
|
+
await runApp(deviceId, config.runner.bundleId);
|
|
33
|
+
}
|
|
34
|
+
const interactionEngine = await interactionEnginePromise;
|
|
37
35
|
const metro = await metroPromise;
|
|
38
|
-
logger.debug('Metro started');
|
|
39
|
-
logger.debug('Running app');
|
|
40
|
-
await runApp(deviceId, runner.bundleId, runner.activityName);
|
|
41
|
-
logger.debug('App running');
|
|
42
36
|
return {
|
|
43
37
|
restart: async () => {
|
|
44
|
-
await runApp(deviceId, runner.bundleId
|
|
38
|
+
await runApp(config.runner.deviceId, config.runner.bundleId);
|
|
45
39
|
},
|
|
46
40
|
dispose: async () => {
|
|
47
|
-
await killApp(deviceId, runner.bundleId);
|
|
48
41
|
if (emulator) {
|
|
49
42
|
await killWithAwait(emulator);
|
|
50
43
|
}
|
|
44
|
+
await interactionEngine.close();
|
|
51
45
|
await killWithAwait(metro);
|
|
46
|
+
await killApp(deviceId, config.runner.bundleId);
|
|
52
47
|
},
|
|
48
|
+
interactionEngine,
|
|
53
49
|
};
|
|
54
50
|
},
|
|
55
51
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export declare const listDevices: () => Promise<any>;
|
|
2
|
-
export declare const getDeviceByName: (simulatorName: string
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
2
|
+
export declare const getDeviceByName: (simulatorName: string) => Promise<any | null>;
|
|
3
|
+
export declare const installPods: () => Promise<void>;
|
|
4
|
+
export declare const listApps: (udid: string) => Promise<string>;
|
|
5
|
+
export declare const isAppInstalled: (simulatorName: string, bundleId: string) => Promise<boolean>;
|
|
6
|
+
export declare const buildIOSApp: (simulatorName: string, maxRetries?: number) => Promise<void>;
|
|
7
|
+
export declare const runApp: (simulatorName: string, appName: string) => Promise<void>;
|
|
8
|
+
export declare const killApp: (simulatorName: string, appName: string) => Promise<void>;
|
|
7
9
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/build.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/platforms/ios/build.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,GAAG,CAgB/C,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,KACpB,OAAO,CAAC,GAAG,GAAG,IAAI,CAiBpB,CAAC;AAEF,eAAO,MAAM,WAAW,QAAa,OAAO,CAAC,IAAI,CAYhD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,CAW3D,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,eAAe,MAAM,EACrB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CAajB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,eAAe,MAAM,EACrB,aAAY,MAAU,KACrB,OAAO,CAAC,IAAI,CAoCd,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,OAAO,CAAC,IAAI,CAgBd,CAAC;AAEF,eAAO,MAAM,OAAO,GAClB,eAAe,MAAM,EACrB,SAAS,MAAM,KACd,OAAO,CAAC,IAAI,CAMd,CAAC"}
|