@react-native-harness/platform-android 1.1.0-rc.3 → 1.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/dist/__tests__/adb.test.js +77 -5
- package/dist/__tests__/environment.test.js +67 -1
- package/dist/__tests__/instance.test.js +1 -1
- package/dist/__tests__/targets.test.d.ts +2 -0
- package/dist/__tests__/targets.test.d.ts.map +1 -0
- package/dist/__tests__/targets.test.js +49 -0
- package/dist/adb.d.ts.map +1 -1
- package/dist/adb.js +47 -13
- package/dist/config.d.ts +16 -16
- package/dist/environment.d.ts +3 -0
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +33 -11
- package/dist/instance.d.ts.map +1 -1
- package/dist/instance.js +2 -4
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +2 -5
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +4 -2
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/__tests__/adb.test.ts +133 -28
- package/src/__tests__/environment.test.ts +135 -10
- package/src/__tests__/instance.test.ts +49 -49
- package/src/__tests__/targets.test.ts +53 -0
- package/src/adb.ts +106 -48
- package/src/environment.ts +99 -55
- package/src/instance.ts +17 -17
- package/src/runner.ts +5 -10
- package/src/targets.ts +9 -2
- package/dist/assertions.d.ts +0 -5
- package/dist/assertions.d.ts.map +0 -1
- package/dist/assertions.js +0 -6
- package/dist/emulator.d.ts +0 -6
- package/dist/emulator.d.ts.map +0 -1
- package/dist/emulator.js +0 -27
- package/dist/reader.d.ts +0 -6
- package/dist/reader.d.ts.map +0 -1
- package/dist/reader.js +0 -57
- package/dist/types.d.ts +0 -381
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -107
|
@@ -5,6 +5,7 @@ import { SubprocessError } from '@react-native-harness/tools';
|
|
|
5
5
|
import { createAvd, deleteAvd, emulatorProcess, getAppUid, getLogcatTimestamp, getStartAppArgs, hasAvd, installApp, startEmulator, waitForBoot, waitForEmulatorDisconnect, } from '../adb.js';
|
|
6
6
|
import * as tools from '@react-native-harness/tools';
|
|
7
7
|
import * as environment from '../environment.js';
|
|
8
|
+
import * as avdConfig from '../avd-config.js';
|
|
8
9
|
const createAbortError = () => new DOMException('The operation was aborted', 'AbortError');
|
|
9
10
|
const createMockChildProcess = () => {
|
|
10
11
|
const process = new EventEmitter();
|
|
@@ -101,9 +102,13 @@ describe('getStartAppArgs', () => {
|
|
|
101
102
|
]);
|
|
102
103
|
});
|
|
103
104
|
it('creates an AVD and appends config overrides', async () => {
|
|
105
|
+
vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
|
|
104
106
|
const spawnSpy = vi
|
|
105
107
|
.spyOn(tools, 'spawn')
|
|
106
|
-
.mockResolvedValue({})
|
|
108
|
+
.mockResolvedValue({})
|
|
109
|
+
.mockResolvedValueOnce({
|
|
110
|
+
stdout: 'id: 0 or "pixel_8"\n Name: Pixel 8\nid: 1 or "pixel_6"\n Name: Pixel 6\n',
|
|
111
|
+
});
|
|
107
112
|
const verifyAndroidEmulatorSdk = vi
|
|
108
113
|
.spyOn(environment, 'ensureAndroidSdkPackages')
|
|
109
114
|
.mockResolvedValue('/tmp/android-sdk');
|
|
@@ -121,17 +126,84 @@ describe('getStartAppArgs', () => {
|
|
|
121
126
|
'platforms;android-35',
|
|
122
127
|
'system-images;android-35;default;x86_64',
|
|
123
128
|
]);
|
|
124
|
-
expect(spawnSpy).toHaveBeenNthCalledWith(1, '
|
|
129
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(1, expect.stringMatching(/avdmanager$/), ['list', 'device']);
|
|
130
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(2, 'bash', [
|
|
125
131
|
'-lc',
|
|
126
|
-
expect.stringContaining('create avd --force --name "Pixel_8_API_35" --package "system-images;android-35;default;x86_64" --device "pixel_8"'),
|
|
132
|
+
expect.stringContaining('create avd --force --name "Pixel_8_API_35" --package "system-images;android-35;default;x86_64" --device "pixel_8" -p '),
|
|
127
133
|
]);
|
|
128
|
-
expect(spawnSpy).toHaveBeenNthCalledWith(
|
|
134
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(3, 'bash', [
|
|
135
|
+
'-lc',
|
|
136
|
+
expect.stringContaining(`'avd.ini.encoding=UTF-8' 'path=`),
|
|
137
|
+
]);
|
|
138
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(4, 'bash', [
|
|
139
|
+
'-lc',
|
|
140
|
+
expect.stringContaining(`'disk.dataPartition.size=1G' 'vm.heapSize=1G' >> `),
|
|
141
|
+
]);
|
|
142
|
+
});
|
|
143
|
+
it('recreates the companion ini file when avdmanager leaves it missing', async () => {
|
|
144
|
+
vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
|
|
145
|
+
const spawnSpy = vi
|
|
146
|
+
.spyOn(tools, 'spawn')
|
|
147
|
+
.mockResolvedValue({})
|
|
148
|
+
.mockResolvedValueOnce({
|
|
149
|
+
stdout: 'id: 0 or "pixel_6"\n Name: Pixel 6\n',
|
|
150
|
+
});
|
|
151
|
+
vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue('/tmp/android-sdk');
|
|
152
|
+
vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue('x86_64');
|
|
153
|
+
await createAvd({
|
|
154
|
+
name: 'Pixel_6_API_35',
|
|
155
|
+
apiLevel: 35,
|
|
156
|
+
profile: 'pixel_6',
|
|
157
|
+
diskSize: '1G',
|
|
158
|
+
heapSize: '1G',
|
|
159
|
+
});
|
|
160
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(3, 'bash', [
|
|
161
|
+
'-lc',
|
|
162
|
+
expect.stringContaining(`'avd.ini.encoding=UTF-8' 'path=`),
|
|
163
|
+
]);
|
|
164
|
+
expect(spawnSpy).toHaveBeenNthCalledWith(4, 'bash', [
|
|
129
165
|
'-lc',
|
|
130
166
|
expect.stringContaining(`'disk.dataPartition.size=1G' 'vm.heapSize=1G' >> `),
|
|
131
167
|
]);
|
|
132
168
|
});
|
|
169
|
+
it('throws an actionable error when the requested AVD profile is unavailable', async () => {
|
|
170
|
+
vi.spyOn(tools, 'spawn').mockResolvedValueOnce({
|
|
171
|
+
stdout: 'id: 0 or "pixel_8"\n Name: Pixel 8\nid: 1 or "pixel_6"\n Name: Pixel 6\n',
|
|
172
|
+
});
|
|
173
|
+
vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue('/tmp/android-sdk');
|
|
174
|
+
vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue('x86_64');
|
|
175
|
+
await expect(createAvd({
|
|
176
|
+
name: 'Pixel_8_Pro_API_35',
|
|
177
|
+
apiLevel: 35,
|
|
178
|
+
profile: 'pixel_8_pro',
|
|
179
|
+
diskSize: '1G',
|
|
180
|
+
heapSize: '1G',
|
|
181
|
+
})).rejects.toThrow('Android AVD profile "pixel_8_pro" is not available on this machine. Available profiles: pixel_8, pixel_6');
|
|
182
|
+
});
|
|
183
|
+
it('throws a clear error when avdmanager does not create config.ini', async () => {
|
|
184
|
+
vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue(null);
|
|
185
|
+
vi.spyOn(tools, 'spawn')
|
|
186
|
+
.mockResolvedValue({})
|
|
187
|
+
.mockResolvedValueOnce({
|
|
188
|
+
stdout: 'id: 0 or "pixel_6"\n Name: Pixel 6\n',
|
|
189
|
+
});
|
|
190
|
+
vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue('/tmp/android-sdk');
|
|
191
|
+
vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue('x86_64');
|
|
192
|
+
await expect(createAvd({
|
|
193
|
+
name: 'Pixel_6_API_35',
|
|
194
|
+
apiLevel: 35,
|
|
195
|
+
profile: 'pixel_6',
|
|
196
|
+
diskSize: '1G',
|
|
197
|
+
heapSize: '1G',
|
|
198
|
+
})).rejects.toThrow('Android AVD "Pixel_6_API_35" was created, but config.ini was not found at ');
|
|
199
|
+
});
|
|
133
200
|
it('creates an AVD with arm64 system image packages on arm64 hosts', async () => {
|
|
134
|
-
vi.spyOn(
|
|
201
|
+
vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
|
|
202
|
+
vi.spyOn(tools, 'spawn')
|
|
203
|
+
.mockResolvedValue({})
|
|
204
|
+
.mockResolvedValueOnce({
|
|
205
|
+
stdout: 'id: 0 or "pixel_8"\n Name: Pixel 8\n',
|
|
206
|
+
});
|
|
135
207
|
const ensureAndroidSdkPackages = vi
|
|
136
208
|
.spyOn(environment, 'ensureAndroidSdkPackages')
|
|
137
209
|
.mockResolvedValue('/tmp/android-sdk');
|
|
@@ -1,10 +1,76 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { ensureAndroidAdbAvailable, ensureAndroidEmulatorAvailable, getAndroidSdkRoot, getAndroidSystemImagePackage, getDefaultUnixAndroidSdkRoot, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from '../environment.js';
|
|
6
|
+
import * as tools from '@react-native-harness/tools';
|
|
3
7
|
describe('Android environment', () => {
|
|
4
8
|
beforeEach(() => {
|
|
5
9
|
vi.restoreAllMocks();
|
|
6
10
|
vi.unstubAllEnvs();
|
|
7
11
|
});
|
|
12
|
+
it('skips bootstrapping command-line tools when adb is already installed', async () => {
|
|
13
|
+
const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
|
|
14
|
+
const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
|
|
15
|
+
fs.mkdirSync(path.dirname(adbPath), { recursive: true });
|
|
16
|
+
fs.writeFileSync(adbPath, '');
|
|
17
|
+
const spawnSpy = vi.spyOn(tools, 'spawn');
|
|
18
|
+
await expect(ensureAndroidAdbAvailable({
|
|
19
|
+
env: { ANDROID_HOME: sdkRoot },
|
|
20
|
+
})).resolves.toBe(sdkRoot);
|
|
21
|
+
expect(spawnSpy).not.toHaveBeenCalled();
|
|
22
|
+
fs.rmSync(sdkRoot, { force: true, recursive: true });
|
|
23
|
+
});
|
|
24
|
+
it('installs only platform-tools when adb is missing', async () => {
|
|
25
|
+
const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
|
|
26
|
+
const sdkManagerDirectory = path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin');
|
|
27
|
+
fs.mkdirSync(sdkManagerDirectory, { recursive: true });
|
|
28
|
+
fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
|
|
29
|
+
fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
|
|
30
|
+
const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (command, args) => {
|
|
31
|
+
if (command === 'bash' && typeof args?.[1] === 'string') {
|
|
32
|
+
const commandString = args[1];
|
|
33
|
+
if (commandString.includes('platform-tools')) {
|
|
34
|
+
const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
|
|
35
|
+
fs.mkdirSync(path.dirname(adbPath), { recursive: true });
|
|
36
|
+
fs.writeFileSync(adbPath, '');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {};
|
|
40
|
+
}));
|
|
41
|
+
await expect(ensureAndroidAdbAvailable({
|
|
42
|
+
env: { ANDROID_HOME: sdkRoot },
|
|
43
|
+
})).resolves.toBe(sdkRoot);
|
|
44
|
+
expect(spawnSpy).toHaveBeenCalledWith('bash', ['-lc', expect.stringContaining('platform-tools')], expect.any(Object));
|
|
45
|
+
expect(spawnSpy.mock.calls.some(([command, args]) => command === 'bash' &&
|
|
46
|
+
typeof args?.[1] === 'string' &&
|
|
47
|
+
args[1].includes('platform-tools') &&
|
|
48
|
+
args[1].includes('emulator'))).toBe(false);
|
|
49
|
+
fs.rmSync(sdkRoot, { force: true, recursive: true });
|
|
50
|
+
});
|
|
51
|
+
it('installs emulator only when emulator is missing', async () => {
|
|
52
|
+
const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
|
|
53
|
+
const sdkManagerDirectory = path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin');
|
|
54
|
+
fs.mkdirSync(sdkManagerDirectory, { recursive: true });
|
|
55
|
+
fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
|
|
56
|
+
fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
|
|
57
|
+
const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (command, args) => {
|
|
58
|
+
if (command === 'bash' && typeof args?.[1] === 'string') {
|
|
59
|
+
const commandString = args[1];
|
|
60
|
+
if (commandString.includes('emulator')) {
|
|
61
|
+
const emulatorPath = path.join(sdkRoot, 'emulator', 'emulator');
|
|
62
|
+
fs.mkdirSync(path.dirname(emulatorPath), { recursive: true });
|
|
63
|
+
fs.writeFileSync(emulatorPath, '');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {};
|
|
67
|
+
}));
|
|
68
|
+
await expect(ensureAndroidEmulatorAvailable({
|
|
69
|
+
env: { ANDROID_HOME: sdkRoot },
|
|
70
|
+
})).resolves.toBe(sdkRoot);
|
|
71
|
+
expect(spawnSpy).toHaveBeenCalledWith('bash', ['-lc', expect.stringContaining('emulator')], expect.any(Object));
|
|
72
|
+
fs.rmSync(sdkRoot, { force: true, recursive: true });
|
|
73
|
+
});
|
|
8
74
|
it('uses the default Unix SDK root when env vars are missing', () => {
|
|
9
75
|
expect(getDefaultUnixAndroidSdkRoot({
|
|
10
76
|
platform: 'darwin',
|
|
@@ -54,7 +54,7 @@ describe('Android platform instance', () => {
|
|
|
54
54
|
activityName: '.MainActivity',
|
|
55
55
|
}, harnessConfig, init);
|
|
56
56
|
await instance.dispose();
|
|
57
|
-
expect(ensureAndroidEmulatorEnvironment).
|
|
57
|
+
expect(ensureAndroidEmulatorEnvironment).not.toHaveBeenCalled();
|
|
58
58
|
expect(stopEmulator).not.toHaveBeenCalled();
|
|
59
59
|
});
|
|
60
60
|
it('creates and boots an emulator when missing and shuts it down on dispose', async () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/targets.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { getRunTargets } from '../targets.js';
|
|
3
|
+
import * as adb from '../adb.js';
|
|
4
|
+
import * as environment from '../environment.js';
|
|
5
|
+
describe('Android target discovery', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
vi.restoreAllMocks();
|
|
8
|
+
vi.unstubAllEnvs();
|
|
9
|
+
});
|
|
10
|
+
it('installs adb and emulator only for discovery', async () => {
|
|
11
|
+
const ensureAndroidAdbAvailable = vi
|
|
12
|
+
.spyOn(environment, 'ensureAndroidAdbAvailable')
|
|
13
|
+
.mockResolvedValue('/tmp/android-sdk');
|
|
14
|
+
const ensureAndroidEmulatorAvailable = vi
|
|
15
|
+
.spyOn(environment, 'ensureAndroidEmulatorAvailable')
|
|
16
|
+
.mockResolvedValue('/tmp/android-sdk');
|
|
17
|
+
vi.spyOn(adb, 'getAvds').mockResolvedValue(['Pixel_8_API_35']);
|
|
18
|
+
vi.spyOn(adb, 'getConnectedDevices').mockResolvedValue([
|
|
19
|
+
{
|
|
20
|
+
id: 'device-1',
|
|
21
|
+
manufacturer: 'Google',
|
|
22
|
+
model: 'Pixel 8',
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
await expect(getRunTargets()).resolves.toEqual([
|
|
26
|
+
{
|
|
27
|
+
type: 'emulator',
|
|
28
|
+
name: 'Pixel_8_API_35',
|
|
29
|
+
platform: 'android',
|
|
30
|
+
description: 'Android emulator',
|
|
31
|
+
device: {
|
|
32
|
+
name: 'Pixel_8_API_35',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'physical',
|
|
37
|
+
name: 'Google Pixel 8',
|
|
38
|
+
platform: 'android',
|
|
39
|
+
description: 'Physical device (device-1)',
|
|
40
|
+
device: {
|
|
41
|
+
manufacturer: 'Google',
|
|
42
|
+
model: 'Pixel 8',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
expect(ensureAndroidAdbAvailable).toHaveBeenCalledTimes(1);
|
|
47
|
+
expect(ensureAndroidEmulatorAvailable).toHaveBeenCalledTimes(1);
|
|
48
|
+
});
|
|
49
|
+
});
|
package/dist/adb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAG/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"adb.d.ts","sourceRoot":"","sources":["../src/adb.ts"],"names":[],"mappings":"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"}
|
package/dist/adb.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { spawn, SubprocessError } from '@react-native-harness/tools';
|
|
2
2
|
import { spawn as nodeSpawn } from 'node:child_process';
|
|
3
3
|
import { access, rm } from 'node:fs/promises';
|
|
4
|
-
import {
|
|
4
|
+
import { getAvdConfigPath, getAvdDirectory, readAvdConfig, } from './avd-config.js';
|
|
5
|
+
import { ensureAndroidEmulatorAvailable, ensureAndroidSdkPackages, getAdbBinaryPath, getAndroidSystemImagePackage, getAvdManagerBinaryPath, getEmulatorBinaryPath, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from './environment.js';
|
|
5
6
|
import { getEmulatorStartupArgs, } from './emulator-startup.js';
|
|
6
7
|
const wait = async (ms) => {
|
|
7
8
|
await new Promise((resolve) => {
|
|
@@ -24,7 +25,6 @@ const waitWithSignal = async (ms, signal) => {
|
|
|
24
25
|
}
|
|
25
26
|
await Promise.race([wait(ms), waitForAbort(signal)]);
|
|
26
27
|
};
|
|
27
|
-
const getAvdConfigPath = (name) => `${process.env.ANDROID_AVD_HOME ?? `${process.env.HOME}/.android/avd`}/${name}.avd/config.ini`;
|
|
28
28
|
const EMULATOR_STARTUP_OBSERVATION_TIMEOUT_MS = 5000;
|
|
29
29
|
const EMULATOR_OUTPUT_BUFFER_LIMIT = 16 * 1024;
|
|
30
30
|
export const emulatorProcess = {
|
|
@@ -64,16 +64,10 @@ const formatEmulatorStartupError = ({ name, stdout, stderr, exitCode, signal, er
|
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
66
|
const ensureEmulatorInstalled = async () => {
|
|
67
|
+
await ensureAndroidEmulatorAvailable();
|
|
67
68
|
const emulatorBinaryPath = getEmulatorBinaryPath();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return emulatorBinaryPath;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
await spawn(getSdkManagerBinaryPath(), ['emulator']);
|
|
74
|
-
await access(emulatorBinaryPath);
|
|
75
|
-
return emulatorBinaryPath;
|
|
76
|
-
}
|
|
69
|
+
await access(emulatorBinaryPath);
|
|
70
|
+
return emulatorBinaryPath;
|
|
77
71
|
};
|
|
78
72
|
export const getRequiredEmulatorPackages = (apiLevel) => {
|
|
79
73
|
return getRequiredAndroidSdkPackages({
|
|
@@ -85,6 +79,43 @@ export const getRequiredEmulatorPackages = (apiLevel) => {
|
|
|
85
79
|
export const verifyAndroidEmulatorSdk = async (apiLevel) => {
|
|
86
80
|
await ensureAndroidSdkPackages(getRequiredEmulatorPackages(apiLevel));
|
|
87
81
|
};
|
|
82
|
+
const listAvdProfiles = async () => {
|
|
83
|
+
const { stdout } = await spawn(getAvdManagerBinaryPath(), ['list', 'device']);
|
|
84
|
+
return stdout
|
|
85
|
+
.split('\n')
|
|
86
|
+
.map((line) => line.match(/^id:\s+\d+\s+or\s+"([^"]+)"/i)?.[1]?.trim())
|
|
87
|
+
.filter((profile) => profile != null && profile !== '');
|
|
88
|
+
};
|
|
89
|
+
const ensureAvdProfileAvailable = async (profile) => {
|
|
90
|
+
const availableProfiles = await listAvdProfiles();
|
|
91
|
+
if (availableProfiles.includes(profile)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const availableProfilesList = availableProfiles.length > 0
|
|
95
|
+
? availableProfiles.join(', ')
|
|
96
|
+
: 'None reported by avdmanager.';
|
|
97
|
+
throw new Error(`Android AVD profile "${profile}" is not available on this machine. Available profiles: ${availableProfilesList}`);
|
|
98
|
+
};
|
|
99
|
+
const ensureAvdConfigExists = async (name) => {
|
|
100
|
+
const configPath = getAvdConfigPath(name);
|
|
101
|
+
if ((await readAvdConfig(name)) == null) {
|
|
102
|
+
throw new Error(`Android AVD "${name}" was created, but config.ini was not found at ${configPath}.`);
|
|
103
|
+
}
|
|
104
|
+
return configPath;
|
|
105
|
+
};
|
|
106
|
+
const getAvdIniPath = (name) => {
|
|
107
|
+
const avdHome = process.env.ANDROID_AVD_HOME ?? `${process.env.HOME}/.android/avd`;
|
|
108
|
+
return `${avdHome}/${name}.ini`;
|
|
109
|
+
};
|
|
110
|
+
const ensureAvdIniExists = async ({ name, apiLevel, }) => {
|
|
111
|
+
const iniPath = getAvdIniPath(name);
|
|
112
|
+
const avdDirectory = getAvdDirectory(name);
|
|
113
|
+
await spawn('bash', [
|
|
114
|
+
'-lc',
|
|
115
|
+
`printf '%s\n%s\n%s\n%s\n' 'avd.ini.encoding=UTF-8' 'path=${avdDirectory}' 'path.rel=avd/${name}.avd' 'target=android-${apiLevel}' > "${iniPath}"`,
|
|
116
|
+
]);
|
|
117
|
+
return iniPath;
|
|
118
|
+
};
|
|
88
119
|
export const getStartAppArgs = (bundleId, activityName, options) => {
|
|
89
120
|
const args = [
|
|
90
121
|
'shell',
|
|
@@ -213,13 +244,16 @@ export const hasAvd = async (name) => {
|
|
|
213
244
|
export const createAvd = async ({ name, apiLevel, profile, diskSize, heapSize, }) => {
|
|
214
245
|
const systemImagePackage = getAndroidSystemImagePackage(apiLevel, getHostAndroidSystemImageArch());
|
|
215
246
|
await verifyAndroidEmulatorSdk(apiLevel);
|
|
247
|
+
await ensureAvdProfileAvailable(profile);
|
|
216
248
|
await spawn('bash', [
|
|
217
249
|
'-lc',
|
|
218
|
-
`printf 'no\n' | "${getAvdManagerBinaryPath()}" create avd --force --name "${name}" --package "${systemImagePackage}" --device "${profile}"`,
|
|
250
|
+
`printf 'no\n' | "${getAvdManagerBinaryPath()}" create avd --force --name "${name}" --package "${systemImagePackage}" --device "${profile}" -p "${getAvdDirectory(name)}"`,
|
|
219
251
|
]);
|
|
252
|
+
await ensureAvdIniExists({ name, apiLevel });
|
|
253
|
+
const configPath = await ensureAvdConfigExists(name);
|
|
220
254
|
await spawn('bash', [
|
|
221
255
|
'-lc',
|
|
222
|
-
`printf '%s\n%s\n' 'disk.dataPartition.size=${diskSize}' 'vm.heapSize=${heapSize}' >> "${
|
|
256
|
+
`printf '%s\n%s\n' 'disk.dataPartition.size=${diskSize}' 'vm.heapSize=${heapSize}' >> "${configPath}"`,
|
|
223
257
|
]);
|
|
224
258
|
};
|
|
225
259
|
export const deleteAvd = async (name) => {
|
package/dist/config.d.ts
CHANGED
|
@@ -68,8 +68,8 @@ export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
|
68
68
|
} | undefined;
|
|
69
69
|
}>>;
|
|
70
70
|
}, "strip", z.ZodTypeAny, {
|
|
71
|
-
name: string;
|
|
72
71
|
type: "emulator";
|
|
72
|
+
name: string;
|
|
73
73
|
avd?: {
|
|
74
74
|
apiLevel: number;
|
|
75
75
|
profile: string;
|
|
@@ -80,8 +80,8 @@ export declare const AndroidEmulatorSchema: z.ZodObject<{
|
|
|
80
80
|
} | undefined;
|
|
81
81
|
} | undefined;
|
|
82
82
|
}, {
|
|
83
|
-
name: string;
|
|
84
83
|
type: "emulator";
|
|
84
|
+
name: string;
|
|
85
85
|
avd?: {
|
|
86
86
|
apiLevel: number;
|
|
87
87
|
profile: string;
|
|
@@ -97,13 +97,13 @@ export declare const PhysicalAndroidDeviceSchema: z.ZodObject<{
|
|
|
97
97
|
manufacturer: z.ZodString;
|
|
98
98
|
model: z.ZodString;
|
|
99
99
|
}, "strip", z.ZodTypeAny, {
|
|
100
|
+
type: "physical";
|
|
100
101
|
manufacturer: string;
|
|
101
102
|
model: string;
|
|
102
|
-
type: "physical";
|
|
103
103
|
}, {
|
|
104
|
+
type: "physical";
|
|
104
105
|
manufacturer: string;
|
|
105
106
|
model: string;
|
|
106
|
-
type: "physical";
|
|
107
107
|
}>;
|
|
108
108
|
export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
109
109
|
type: z.ZodLiteral<"emulator">;
|
|
@@ -138,8 +138,8 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
138
138
|
} | undefined;
|
|
139
139
|
}>>;
|
|
140
140
|
}, "strip", z.ZodTypeAny, {
|
|
141
|
-
name: string;
|
|
142
141
|
type: "emulator";
|
|
142
|
+
name: string;
|
|
143
143
|
avd?: {
|
|
144
144
|
apiLevel: number;
|
|
145
145
|
profile: string;
|
|
@@ -150,8 +150,8 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
150
150
|
} | undefined;
|
|
151
151
|
} | undefined;
|
|
152
152
|
}, {
|
|
153
|
-
name: string;
|
|
154
153
|
type: "emulator";
|
|
154
|
+
name: string;
|
|
155
155
|
avd?: {
|
|
156
156
|
apiLevel: number;
|
|
157
157
|
profile: string;
|
|
@@ -166,13 +166,13 @@ export declare const AndroidDeviceSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
|
|
|
166
166
|
manufacturer: z.ZodString;
|
|
167
167
|
model: z.ZodString;
|
|
168
168
|
}, "strip", z.ZodTypeAny, {
|
|
169
|
+
type: "physical";
|
|
169
170
|
manufacturer: string;
|
|
170
171
|
model: string;
|
|
171
|
-
type: "physical";
|
|
172
172
|
}, {
|
|
173
|
+
type: "physical";
|
|
173
174
|
manufacturer: string;
|
|
174
175
|
model: string;
|
|
175
|
-
type: "physical";
|
|
176
176
|
}>]>;
|
|
177
177
|
export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
178
178
|
name: z.ZodString;
|
|
@@ -209,8 +209,8 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
209
209
|
} | undefined;
|
|
210
210
|
}>>;
|
|
211
211
|
}, "strip", z.ZodTypeAny, {
|
|
212
|
-
name: string;
|
|
213
212
|
type: "emulator";
|
|
213
|
+
name: string;
|
|
214
214
|
avd?: {
|
|
215
215
|
apiLevel: number;
|
|
216
216
|
profile: string;
|
|
@@ -221,8 +221,8 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
221
221
|
} | undefined;
|
|
222
222
|
} | undefined;
|
|
223
223
|
}, {
|
|
224
|
-
name: string;
|
|
225
224
|
type: "emulator";
|
|
225
|
+
name: string;
|
|
226
226
|
avd?: {
|
|
227
227
|
apiLevel: number;
|
|
228
228
|
profile: string;
|
|
@@ -237,13 +237,13 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
237
237
|
manufacturer: z.ZodString;
|
|
238
238
|
model: z.ZodString;
|
|
239
239
|
}, "strip", z.ZodTypeAny, {
|
|
240
|
+
type: "physical";
|
|
240
241
|
manufacturer: string;
|
|
241
242
|
model: string;
|
|
242
|
-
type: "physical";
|
|
243
243
|
}, {
|
|
244
|
+
type: "physical";
|
|
244
245
|
manufacturer: string;
|
|
245
246
|
model: string;
|
|
246
|
-
type: "physical";
|
|
247
247
|
}>]>;
|
|
248
248
|
bundleId: z.ZodString;
|
|
249
249
|
activityName: z.ZodDefault<z.ZodString>;
|
|
@@ -257,8 +257,8 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
257
257
|
}, "strip", z.ZodTypeAny, {
|
|
258
258
|
name: string;
|
|
259
259
|
device: {
|
|
260
|
-
name: string;
|
|
261
260
|
type: "emulator";
|
|
261
|
+
name: string;
|
|
262
262
|
avd?: {
|
|
263
263
|
apiLevel: number;
|
|
264
264
|
profile: string;
|
|
@@ -269,9 +269,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
269
269
|
} | undefined;
|
|
270
270
|
} | undefined;
|
|
271
271
|
} | {
|
|
272
|
+
type: "physical";
|
|
272
273
|
manufacturer: string;
|
|
273
274
|
model: string;
|
|
274
|
-
type: "physical";
|
|
275
275
|
};
|
|
276
276
|
bundleId: string;
|
|
277
277
|
activityName: string;
|
|
@@ -281,8 +281,8 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
281
281
|
}, {
|
|
282
282
|
name: string;
|
|
283
283
|
device: {
|
|
284
|
-
name: string;
|
|
285
284
|
type: "emulator";
|
|
285
|
+
name: string;
|
|
286
286
|
avd?: {
|
|
287
287
|
apiLevel: number;
|
|
288
288
|
profile: string;
|
|
@@ -293,9 +293,9 @@ export declare const AndroidPlatformConfigSchema: z.ZodObject<{
|
|
|
293
293
|
} | undefined;
|
|
294
294
|
} | undefined;
|
|
295
295
|
} | {
|
|
296
|
+
type: "physical";
|
|
296
297
|
manufacturer: string;
|
|
297
298
|
model: string;
|
|
298
|
-
type: "physical";
|
|
299
299
|
};
|
|
300
300
|
bundleId: string;
|
|
301
301
|
activityName?: string | undefined;
|
package/dist/environment.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export declare const getRequiredAndroidSdkPackages: ({ apiLevel, includeEmulator
|
|
|
15
15
|
architecture?: AndroidSystemImageArch;
|
|
16
16
|
}) => string[];
|
|
17
17
|
export declare const ensureAndroidSdkPackages: (packages: readonly string[], { env, platform, homeDirectory, }?: AndroidSdkRootOptions) => Promise<string>;
|
|
18
|
+
export declare const ensureAndroidAdbAvailable: (options?: AndroidSdkRootOptions) => Promise<string>;
|
|
19
|
+
export declare const ensureAndroidEmulatorAvailable: (options?: AndroidSdkRootOptions) => Promise<string>;
|
|
20
|
+
export declare const ensureAndroidAvdProvisioningAvailable: (apiLevel: number, architecture?: AndroidSystemImageArch, options?: AndroidSdkRootOptions) => Promise<string>;
|
|
18
21
|
export declare const ensureAndroidDiscoveryEnvironment: () => Promise<string>;
|
|
19
22
|
export declare const ensureAndroidPhysicalDeviceEnvironment: () => Promise<string>;
|
|
20
23
|
export declare const ensureAndroidEmulatorEnvironment: (apiLevel: number) => Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;AAE5E,KAAK,qBAAqB,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAQF,eAAO,MAAM,4BAA4B,GAAI,+BAG1C,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAAG,MAAM,GAAG,IAUrD,CAAC;AAwRF,eAAO,MAAM,iBAAiB,GAC5B,MAAK,MAAM,CAAC,UAAwB,EACpC,UAAS,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAC/C,MAAM,GAAG,IAIX,CAAC;AAiBF,eAAO,MAAM,6BAA6B,GACxC,eAAc,MAAqB,KAClC,sBAUF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,UAAU,MAAM,KAAG,MAE5D,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,UAAU,MAAM,EAChB,eAAc,sBAAwD,KACrE,MAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,+CAI3C;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,sBAAsB,CAAC;CAClC,KAAG,MAAM,EAed,CAAC;
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,CAAC;AAE5E,KAAK,qBAAqB,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAQF,eAAO,MAAM,4BAA4B,GAAI,+BAG1C,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAAG,MAAM,GAAG,IAUrD,CAAC;AAwRF,eAAO,MAAM,iBAAiB,GAC5B,MAAK,MAAM,CAAC,UAAwB,EACpC,UAAS,IAAI,CAAC,qBAAqB,EAAE,KAAK,CAAM,KAC/C,MAAM,GAAG,IAIX,CAAC;AAiBF,eAAO,MAAM,6BAA6B,GACxC,eAAc,MAAqB,KAClC,sBAUF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,UAAU,MAAM,KAAG,MAE5D,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,UAAU,MAAM,EAChB,eAAc,sBAAwD,KACrE,MAEF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GAAI,+CAI3C;IACD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,sBAAsB,CAAC;CAClC,KAAG,MAAM,EAed,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GACnC,UAAU,SAAS,MAAM,EAAE,EAC3B,oCAIG,qBAA0B,KAC5B,OAAO,CAAC,MAAM,CA8BhB,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAEhB,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAEhB,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,UAAU,MAAM,EAChB,eAAc,sBAAwD,EACtE,UAAS,qBAA0B,KAClC,OAAO,CAAC,MAAM,CAQhB,CAAC;AAEF,eAAO,MAAM,iCAAiC,QAAa,OAAO,CAAC,MAAM,CAIxE,CAAC;AAEF,eAAO,MAAM,sCAAsC,QACvC,OAAO,CAAC,MAAM,CAIvB,CAAC;AAEJ,eAAO,MAAM,gCAAgC,GAC3C,UAAU,MAAM,KACf,OAAO,CAAC,MAAM,CAOhB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,MAAK,MAAM,CAAC,UAAwB,KACnC,MAAM,CAAC,UA2BT,CAAC;AAEF,eAAO,MAAM,2BAA2B,QAAO,IAE9C,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAS,MAAoC,KAC5C,MAAqD,CAAC;AAEzD,eAAO,MAAM,qBAAqB,GAChC,UAAS,MAAoC,KAC5C,MAAoD,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC;AAE1E,eAAO,MAAM,uBAAuB,GAClC,UAAS,MAAoC,KAC5C,MACsE,CAAC"}
|
package/dist/environment.js
CHANGED
|
@@ -232,34 +232,56 @@ export const getRequiredAndroidSdkPackages = ({ apiLevel, includeEmulator = fals
|
|
|
232
232
|
}
|
|
233
233
|
return packages;
|
|
234
234
|
};
|
|
235
|
-
|
|
235
|
+
const getMissingAndroidSdkPackagesForEnvironment = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
|
|
236
236
|
const sdkRoot = getRequiredAndroidSdkRoot(env, { platform, homeDirectory });
|
|
237
237
|
await mkdir(sdkRoot, { recursive: true });
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
return {
|
|
239
|
+
sdkRoot,
|
|
240
|
+
missingPackages: await getMissingAndroidSdkPackages(sdkRoot, packages),
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
export const ensureAndroidSdkPackages = async (packages, { env = process.env, platform = process.platform, homeDirectory = os.homedir(), } = {}) => {
|
|
244
|
+
const { sdkRoot, missingPackages } = await getMissingAndroidSdkPackagesForEnvironment(packages, {
|
|
245
|
+
env,
|
|
246
|
+
platform,
|
|
247
|
+
homeDirectory,
|
|
248
|
+
});
|
|
249
|
+
if (missingPackages.length === 0) {
|
|
250
|
+
return sdkRoot;
|
|
242
251
|
}
|
|
252
|
+
await ensureAndroidCommandLineTools(sdkRoot, platform);
|
|
253
|
+
await installAndroidSdkPackages(sdkRoot, missingPackages);
|
|
243
254
|
const unresolvedPackages = await getMissingAndroidSdkPackages(sdkRoot, packages);
|
|
244
255
|
if (unresolvedPackages.length > 0) {
|
|
245
256
|
throw new Error(`Android SDK packages are still missing after installation: ${unresolvedPackages.join(', ')}`);
|
|
246
257
|
}
|
|
247
258
|
return sdkRoot;
|
|
248
259
|
};
|
|
260
|
+
export const ensureAndroidAdbAvailable = async (options = {}) => {
|
|
261
|
+
return ensureAndroidSdkPackages(['platform-tools'], options);
|
|
262
|
+
};
|
|
263
|
+
export const ensureAndroidEmulatorAvailable = async (options = {}) => {
|
|
264
|
+
return ensureAndroidSdkPackages(['emulator'], options);
|
|
265
|
+
};
|
|
266
|
+
export const ensureAndroidAvdProvisioningAvailable = async (apiLevel, architecture = getHostAndroidSystemImageArch(), options = {}) => {
|
|
267
|
+
return ensureAndroidSdkPackages([
|
|
268
|
+
getAndroidPlatformPackage(apiLevel),
|
|
269
|
+
getAndroidSystemImagePackage(apiLevel, architecture),
|
|
270
|
+
], options);
|
|
271
|
+
};
|
|
249
272
|
export const ensureAndroidDiscoveryEnvironment = async () => {
|
|
250
273
|
initializeAndroidProcessEnv();
|
|
251
|
-
return
|
|
274
|
+
return ensureAndroidAdbAvailable();
|
|
252
275
|
};
|
|
253
276
|
export const ensureAndroidPhysicalDeviceEnvironment = async () => {
|
|
254
277
|
initializeAndroidProcessEnv();
|
|
255
|
-
return
|
|
278
|
+
return ensureAndroidAdbAvailable();
|
|
256
279
|
};
|
|
257
280
|
export const ensureAndroidEmulatorEnvironment = async (apiLevel) => {
|
|
258
281
|
initializeAndroidProcessEnv();
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}));
|
|
282
|
+
await ensureAndroidAdbAvailable();
|
|
283
|
+
await ensureAndroidEmulatorAvailable();
|
|
284
|
+
return ensureAndroidAvdProvisioningAvailable(apiLevel);
|
|
263
285
|
};
|
|
264
286
|
export const getAndroidProcessEnv = (env = process.env) => {
|
|
265
287
|
const sdkRoot = getAndroidSdkRoot(env);
|
package/dist/instance.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,0BAA0B,EAC/B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EACL,qBAAqB,EAGtB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,0BAA0B,EAC/B,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE5E,OAAO,EACL,qBAAqB,EAGtB,MAAM,aAAa,CAAC;AAkKrB,eAAO,MAAM,kCAAkC,GAC7C,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAkI/B,CAAC;AAEF,eAAO,MAAM,wCAAwC,GACnD,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,KAC3B,OAAO,CAAC,qBAAqB,CAiE/B,CAAC"}
|
package/dist/instance.js
CHANGED
|
@@ -8,7 +8,7 @@ import { applyHarnessDebugHttpHost, clearHarnessDebugHttpHost, } from './shared-
|
|
|
8
8
|
import { getDeviceName } from './utils.js';
|
|
9
9
|
import { createAndroidAppMonitor } from './app-monitor.js';
|
|
10
10
|
import { HarnessAppPathError, HarnessEmulatorConfigError } from './errors.js';
|
|
11
|
-
import { ensureAndroidEmulatorEnvironment, getHostAndroidSystemImageArch, } from './environment.js';
|
|
11
|
+
import { ensureAndroidEmulatorAvailable, ensureAndroidEmulatorEnvironment, getHostAndroidSystemImageArch, } from './environment.js';
|
|
12
12
|
import { isInteractive } from '@react-native-harness/tools';
|
|
13
13
|
import fs from 'node:fs';
|
|
14
14
|
const androidInstanceLogger = logger.child('android-instance');
|
|
@@ -40,6 +40,7 @@ const configureAndroidRuntime = async (adbId, config, harnessConfig) => {
|
|
|
40
40
|
return adb.getAppUid(adbId, config.bundleId);
|
|
41
41
|
};
|
|
42
42
|
const startAndWaitForBoot = async ({ emulatorName, signal, mode, }) => {
|
|
43
|
+
await ensureAndroidEmulatorAvailable();
|
|
43
44
|
await adb.startEmulator(emulatorName, mode);
|
|
44
45
|
return adb.waitForBoot(emulatorName, signal);
|
|
45
46
|
};
|
|
@@ -135,9 +136,6 @@ export const getAndroidEmulatorPlatformInstance = async (config, harnessConfig,
|
|
|
135
136
|
startedByHarness = true;
|
|
136
137
|
androidInstanceLogger.debug('Android emulator %s connected as %s', emulatorConfig.name, adbId);
|
|
137
138
|
}
|
|
138
|
-
else if (emulatorConfig.avd) {
|
|
139
|
-
await ensureAndroidEmulatorEnvironment(emulatorConfig.avd.apiLevel);
|
|
140
|
-
}
|
|
141
139
|
if (!adbId) {
|
|
142
140
|
throw new DeviceNotFoundError(getDeviceName(emulatorConfig));
|
|
143
141
|
}
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,aAAa,CAAC;AAUrB,QAAA,MAAM,gBAAgB,GACpB,QAAQ,qBAAqB,EAC7B,eAAe,aAAa,EAC5B,MAAM,0BAA0B,KAC/B,OAAO,CAAC,qBAAqB,CAgB/B,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|