@react-native-harness/platform-android 1.1.0-rc.3 → 1.1.0-rc.4
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__/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 +4 -10
- 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__/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 +35 -40
- 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/src/environment.ts
CHANGED
|
@@ -21,7 +21,7 @@ type AndroidSdkRootOptions = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const getConfiguredAndroidSdkRoot = (
|
|
24
|
-
env: NodeJS.ProcessEnv = process.env
|
|
24
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
25
25
|
): string | null => {
|
|
26
26
|
return env.ANDROID_HOME ?? env.ANDROID_SDK_ROOT ?? null;
|
|
27
27
|
};
|
|
@@ -42,7 +42,7 @@ export const getDefaultUnixAndroidSdkRoot = ({
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const canBootstrapAndroidSdk = (
|
|
45
|
-
platform: NodeJS.Platform = process.platform
|
|
45
|
+
platform: NodeJS.Platform = process.platform,
|
|
46
46
|
) => {
|
|
47
47
|
return platform === 'darwin' || platform === 'linux';
|
|
48
48
|
};
|
|
@@ -79,8 +79,8 @@ const downloadText = async (url: string): Promise<string> => {
|
|
|
79
79
|
response.resume();
|
|
80
80
|
reject(
|
|
81
81
|
new Error(
|
|
82
|
-
`Failed to download Android repository index from ${url} (status ${statusCode})
|
|
83
|
-
)
|
|
82
|
+
`Failed to download Android repository index from ${url} (status ${statusCode}).`,
|
|
83
|
+
),
|
|
84
84
|
);
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
@@ -102,7 +102,7 @@ const downloadText = async (url: string): Promise<string> => {
|
|
|
102
102
|
|
|
103
103
|
const downloadFile = async (
|
|
104
104
|
url: string,
|
|
105
|
-
destinationPath: string
|
|
105
|
+
destinationPath: string,
|
|
106
106
|
): Promise<void> => {
|
|
107
107
|
await new Promise<void>((resolve, reject) => {
|
|
108
108
|
const request = https.get(url, (response) => {
|
|
@@ -122,8 +122,8 @@ const downloadFile = async (
|
|
|
122
122
|
response.resume();
|
|
123
123
|
reject(
|
|
124
124
|
new Error(
|
|
125
|
-
`Failed to download Android command-line tools from ${url} (status ${statusCode})
|
|
126
|
-
)
|
|
125
|
+
`Failed to download Android command-line tools from ${url} (status ${statusCode}).`,
|
|
126
|
+
),
|
|
127
127
|
);
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
@@ -137,27 +137,27 @@ const downloadFile = async (
|
|
|
137
137
|
};
|
|
138
138
|
|
|
139
139
|
const getCommandLineToolsArchiveUrl = async (
|
|
140
|
-
platform: NodeJS.Platform = process.platform
|
|
140
|
+
platform: NodeJS.Platform = process.platform,
|
|
141
141
|
): Promise<string> => {
|
|
142
142
|
const archivePlatform =
|
|
143
143
|
platform === 'darwin' ? 'mac' : platform === 'linux' ? 'linux' : null;
|
|
144
144
|
|
|
145
145
|
if (!archivePlatform) {
|
|
146
146
|
throw new Error(
|
|
147
|
-
'Automatic Android SDK bootstrap is only supported on macOS and Linux.'
|
|
147
|
+
'Automatic Android SDK bootstrap is only supported on macOS and Linux.',
|
|
148
148
|
);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
const repositoryIndex = await downloadText(ANDROID_REPOSITORY_INDEX_URL);
|
|
152
152
|
const archivePattern = new RegExp(
|
|
153
153
|
`commandlinetools-${archivePlatform}-(\\d+)_latest\\.zip`,
|
|
154
|
-
'g'
|
|
154
|
+
'g',
|
|
155
155
|
);
|
|
156
156
|
const matches = [...repositoryIndex.matchAll(archivePattern)];
|
|
157
157
|
|
|
158
158
|
if (matches.length === 0) {
|
|
159
159
|
throw new Error(
|
|
160
|
-
`Failed to resolve Android command-line tools archive for ${archivePlatform}
|
|
160
|
+
`Failed to resolve Android command-line tools archive for ${archivePlatform}.`,
|
|
161
161
|
);
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -173,7 +173,7 @@ const getCommandLineToolsArchiveUrl = async (
|
|
|
173
173
|
|
|
174
174
|
const ensureAndroidCommandLineTools = async (
|
|
175
175
|
sdkRoot: string,
|
|
176
|
-
platform: NodeJS.Platform = process.platform
|
|
176
|
+
platform: NodeJS.Platform = process.platform,
|
|
177
177
|
): Promise<void> => {
|
|
178
178
|
if (
|
|
179
179
|
(await pathExists(getSdkManagerBinaryPath(sdkRoot))) &&
|
|
@@ -184,19 +184,19 @@ const ensureAndroidCommandLineTools = async (
|
|
|
184
184
|
|
|
185
185
|
if (!canBootstrapAndroidSdk(platform)) {
|
|
186
186
|
throw new Error(
|
|
187
|
-
'Android command-line tools are missing. Set ANDROID_HOME or ANDROID_SDK_ROOT to an initialized SDK.'
|
|
187
|
+
'Android command-line tools are missing. Set ANDROID_HOME or ANDROID_SDK_ROOT to an initialized SDK.',
|
|
188
188
|
);
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
androidEnvironmentLogger.info(
|
|
192
192
|
'Bootstrapping Android command-line tools in %s',
|
|
193
|
-
sdkRoot
|
|
193
|
+
sdkRoot,
|
|
194
194
|
);
|
|
195
195
|
|
|
196
196
|
await mkdir(sdkRoot, { recursive: true });
|
|
197
197
|
|
|
198
198
|
const temporaryDirectory = await mkdtemp(
|
|
199
|
-
path.join(os.tmpdir(), 'android-cmdline-tools-')
|
|
199
|
+
path.join(os.tmpdir(), 'android-cmdline-tools-'),
|
|
200
200
|
);
|
|
201
201
|
const archivePath = path.join(temporaryDirectory, 'cmdline-tools.zip');
|
|
202
202
|
const extractedPath = path.join(temporaryDirectory, 'extracted');
|
|
@@ -206,7 +206,7 @@ const ensureAndroidCommandLineTools = async (
|
|
|
206
206
|
try {
|
|
207
207
|
await downloadFile(
|
|
208
208
|
await getCommandLineToolsArchiveUrl(platform),
|
|
209
|
-
archivePath
|
|
209
|
+
archivePath,
|
|
210
210
|
);
|
|
211
211
|
await spawn('unzip', ['-q', archivePath, '-d', extractedPath]);
|
|
212
212
|
await rm(targetDirectory, { force: true, recursive: true });
|
|
@@ -225,7 +225,7 @@ const acceptAndroidLicenses = async (sdkRoot: string): Promise<void> => {
|
|
|
225
225
|
[
|
|
226
226
|
'-lc',
|
|
227
227
|
`yes | ${quoteShell(sdkManagerBinaryPath)} --sdk_root=${quoteShell(
|
|
228
|
-
sdkRoot
|
|
228
|
+
sdkRoot,
|
|
229
229
|
)} --licenses >/dev/null`,
|
|
230
230
|
],
|
|
231
231
|
{
|
|
@@ -234,13 +234,13 @@ const acceptAndroidLicenses = async (sdkRoot: string): Promise<void> => {
|
|
|
234
234
|
ANDROID_HOME: sdkRoot,
|
|
235
235
|
ANDROID_SDK_ROOT: sdkRoot,
|
|
236
236
|
}),
|
|
237
|
-
}
|
|
237
|
+
},
|
|
238
238
|
);
|
|
239
239
|
};
|
|
240
240
|
|
|
241
241
|
const getPackageVerificationPath = (
|
|
242
242
|
sdkRoot: string,
|
|
243
|
-
packageName: string
|
|
243
|
+
packageName: string,
|
|
244
244
|
): string | null => {
|
|
245
245
|
if (packageName === 'platform-tools') {
|
|
246
246
|
return getAdbBinaryPath(sdkRoot);
|
|
@@ -263,7 +263,7 @@ const getPackageVerificationPath = (
|
|
|
263
263
|
|
|
264
264
|
const getMissingAndroidSdkPackages = async (
|
|
265
265
|
sdkRoot: string,
|
|
266
|
-
packages: readonly string[]
|
|
266
|
+
packages: readonly string[],
|
|
267
267
|
): Promise<string[]> => {
|
|
268
268
|
const missingPackages: string[] = [];
|
|
269
269
|
|
|
@@ -284,7 +284,7 @@ const getMissingAndroidSdkPackages = async (
|
|
|
284
284
|
|
|
285
285
|
const installAndroidSdkPackages = async (
|
|
286
286
|
sdkRoot: string,
|
|
287
|
-
packages: readonly string[]
|
|
287
|
+
packages: readonly string[],
|
|
288
288
|
): Promise<void> => {
|
|
289
289
|
if (packages.length === 0) {
|
|
290
290
|
return;
|
|
@@ -297,7 +297,7 @@ const installAndroidSdkPackages = async (
|
|
|
297
297
|
|
|
298
298
|
androidEnvironmentLogger.info(
|
|
299
299
|
'Installing missing Android SDK packages: %s',
|
|
300
|
-
packages.join(', ')
|
|
300
|
+
packages.join(', '),
|
|
301
301
|
);
|
|
302
302
|
|
|
303
303
|
await acceptAndroidLicenses(sdkRoot);
|
|
@@ -306,7 +306,7 @@ const installAndroidSdkPackages = async (
|
|
|
306
306
|
[
|
|
307
307
|
'-lc',
|
|
308
308
|
`yes | ${quoteShell(sdkManagerBinaryPath)} --sdk_root=${quoteShell(
|
|
309
|
-
sdkRoot
|
|
309
|
+
sdkRoot,
|
|
310
310
|
)} ${packageArgs}`,
|
|
311
311
|
],
|
|
312
312
|
{
|
|
@@ -315,13 +315,13 @@ const installAndroidSdkPackages = async (
|
|
|
315
315
|
ANDROID_HOME: sdkRoot,
|
|
316
316
|
ANDROID_SDK_ROOT: sdkRoot,
|
|
317
317
|
}),
|
|
318
|
-
}
|
|
318
|
+
},
|
|
319
319
|
);
|
|
320
320
|
};
|
|
321
321
|
|
|
322
322
|
export const getAndroidSdkRoot = (
|
|
323
323
|
env: NodeJS.ProcessEnv = process.env,
|
|
324
|
-
options: Omit<AndroidSdkRootOptions, 'env'> = {}
|
|
324
|
+
options: Omit<AndroidSdkRootOptions, 'env'> = {},
|
|
325
325
|
): string | null => {
|
|
326
326
|
return (
|
|
327
327
|
getConfiguredAndroidSdkRoot(env) ?? getDefaultUnixAndroidSdkRoot(options)
|
|
@@ -330,13 +330,13 @@ export const getAndroidSdkRoot = (
|
|
|
330
330
|
|
|
331
331
|
const getRequiredAndroidSdkRoot = (
|
|
332
332
|
env: NodeJS.ProcessEnv = process.env,
|
|
333
|
-
options: Omit<AndroidSdkRootOptions, 'env'> = {}
|
|
333
|
+
options: Omit<AndroidSdkRootOptions, 'env'> = {},
|
|
334
334
|
): string => {
|
|
335
335
|
const sdkRoot = getAndroidSdkRoot(env, options);
|
|
336
336
|
|
|
337
337
|
if (!sdkRoot) {
|
|
338
338
|
throw new Error(
|
|
339
|
-
'Android SDK root is not configured. Set ANDROID_HOME or ANDROID_SDK_ROOT.'
|
|
339
|
+
'Android SDK root is not configured. Set ANDROID_HOME or ANDROID_SDK_ROOT.',
|
|
340
340
|
);
|
|
341
341
|
}
|
|
342
342
|
|
|
@@ -344,7 +344,7 @@ const getRequiredAndroidSdkRoot = (
|
|
|
344
344
|
};
|
|
345
345
|
|
|
346
346
|
export const getHostAndroidSystemImageArch = (
|
|
347
|
-
architecture: string = process.arch
|
|
347
|
+
architecture: string = process.arch,
|
|
348
348
|
): AndroidSystemImageArch => {
|
|
349
349
|
switch (architecture) {
|
|
350
350
|
case 'arm64':
|
|
@@ -363,7 +363,7 @@ export const getAndroidPlatformPackage = (apiLevel: number): string => {
|
|
|
363
363
|
|
|
364
364
|
export const getAndroidSystemImagePackage = (
|
|
365
365
|
apiLevel: number,
|
|
366
|
-
architecture: AndroidSystemImageArch = getHostAndroidSystemImageArch()
|
|
366
|
+
architecture: AndroidSystemImageArch = getHostAndroidSystemImageArch(),
|
|
367
367
|
): string => {
|
|
368
368
|
return `system-images;android-${apiLevel};default;${architecture}`;
|
|
369
369
|
};
|
|
@@ -393,71 +393,115 @@ export const getRequiredAndroidSdkPackages = ({
|
|
|
393
393
|
return packages;
|
|
394
394
|
};
|
|
395
395
|
|
|
396
|
-
|
|
396
|
+
const getMissingAndroidSdkPackagesForEnvironment = async (
|
|
397
397
|
packages: readonly string[],
|
|
398
398
|
{
|
|
399
399
|
env = process.env,
|
|
400
400
|
platform = process.platform,
|
|
401
401
|
homeDirectory = os.homedir(),
|
|
402
|
-
}: AndroidSdkRootOptions = {}
|
|
403
|
-
): Promise<string> => {
|
|
402
|
+
}: AndroidSdkRootOptions = {},
|
|
403
|
+
): Promise<{ sdkRoot: string; missingPackages: string[] }> => {
|
|
404
404
|
const sdkRoot = getRequiredAndroidSdkRoot(env, { platform, homeDirectory });
|
|
405
405
|
|
|
406
406
|
await mkdir(sdkRoot, { recursive: true });
|
|
407
|
-
await ensureAndroidCommandLineTools(sdkRoot, platform);
|
|
408
407
|
|
|
409
|
-
|
|
408
|
+
return {
|
|
409
|
+
sdkRoot,
|
|
410
|
+
missingPackages: await getMissingAndroidSdkPackages(sdkRoot, packages),
|
|
411
|
+
};
|
|
412
|
+
};
|
|
410
413
|
|
|
411
|
-
|
|
412
|
-
|
|
414
|
+
export const ensureAndroidSdkPackages = async (
|
|
415
|
+
packages: readonly string[],
|
|
416
|
+
{
|
|
417
|
+
env = process.env,
|
|
418
|
+
platform = process.platform,
|
|
419
|
+
homeDirectory = os.homedir(),
|
|
420
|
+
}: AndroidSdkRootOptions = {},
|
|
421
|
+
): Promise<string> => {
|
|
422
|
+
const { sdkRoot, missingPackages } =
|
|
423
|
+
await getMissingAndroidSdkPackagesForEnvironment(packages, {
|
|
424
|
+
env,
|
|
425
|
+
platform,
|
|
426
|
+
homeDirectory,
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
if (missingPackages.length === 0) {
|
|
430
|
+
return sdkRoot;
|
|
413
431
|
}
|
|
414
432
|
|
|
433
|
+
await ensureAndroidCommandLineTools(sdkRoot, platform);
|
|
434
|
+
|
|
435
|
+
await installAndroidSdkPackages(sdkRoot, missingPackages);
|
|
436
|
+
|
|
415
437
|
const unresolvedPackages = await getMissingAndroidSdkPackages(
|
|
416
438
|
sdkRoot,
|
|
417
|
-
packages
|
|
439
|
+
packages,
|
|
418
440
|
);
|
|
419
441
|
|
|
420
442
|
if (unresolvedPackages.length > 0) {
|
|
421
443
|
throw new Error(
|
|
422
444
|
`Android SDK packages are still missing after installation: ${unresolvedPackages.join(
|
|
423
|
-
', '
|
|
424
|
-
)}
|
|
445
|
+
', ',
|
|
446
|
+
)}`,
|
|
425
447
|
);
|
|
426
448
|
}
|
|
427
449
|
|
|
428
450
|
return sdkRoot;
|
|
429
451
|
};
|
|
430
452
|
|
|
431
|
-
export const
|
|
432
|
-
|
|
453
|
+
export const ensureAndroidAdbAvailable = async (
|
|
454
|
+
options: AndroidSdkRootOptions = {},
|
|
455
|
+
): Promise<string> => {
|
|
456
|
+
return ensureAndroidSdkPackages(['platform-tools'], options);
|
|
457
|
+
};
|
|
433
458
|
|
|
459
|
+
export const ensureAndroidEmulatorAvailable = async (
|
|
460
|
+
options: AndroidSdkRootOptions = {},
|
|
461
|
+
): Promise<string> => {
|
|
462
|
+
return ensureAndroidSdkPackages(['emulator'], options);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
export const ensureAndroidAvdProvisioningAvailable = async (
|
|
466
|
+
apiLevel: number,
|
|
467
|
+
architecture: AndroidSystemImageArch = getHostAndroidSystemImageArch(),
|
|
468
|
+
options: AndroidSdkRootOptions = {},
|
|
469
|
+
): Promise<string> => {
|
|
434
470
|
return ensureAndroidSdkPackages(
|
|
435
|
-
|
|
471
|
+
[
|
|
472
|
+
getAndroidPlatformPackage(apiLevel),
|
|
473
|
+
getAndroidSystemImagePackage(apiLevel, architecture),
|
|
474
|
+
],
|
|
475
|
+
options,
|
|
436
476
|
);
|
|
437
477
|
};
|
|
438
478
|
|
|
479
|
+
export const ensureAndroidDiscoveryEnvironment = async (): Promise<string> => {
|
|
480
|
+
initializeAndroidProcessEnv();
|
|
481
|
+
|
|
482
|
+
return ensureAndroidAdbAvailable();
|
|
483
|
+
};
|
|
484
|
+
|
|
439
485
|
export const ensureAndroidPhysicalDeviceEnvironment =
|
|
440
486
|
async (): Promise<string> => {
|
|
441
487
|
initializeAndroidProcessEnv();
|
|
442
488
|
|
|
443
|
-
return
|
|
489
|
+
return ensureAndroidAdbAvailable();
|
|
444
490
|
};
|
|
445
491
|
|
|
446
492
|
export const ensureAndroidEmulatorEnvironment = async (
|
|
447
|
-
apiLevel: number
|
|
493
|
+
apiLevel: number,
|
|
448
494
|
): Promise<string> => {
|
|
449
495
|
initializeAndroidProcessEnv();
|
|
450
496
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
})
|
|
456
|
-
);
|
|
497
|
+
await ensureAndroidAdbAvailable();
|
|
498
|
+
await ensureAndroidEmulatorAvailable();
|
|
499
|
+
|
|
500
|
+
return ensureAndroidAvdProvisioningAvailable(apiLevel);
|
|
457
501
|
};
|
|
458
502
|
|
|
459
503
|
export const getAndroidProcessEnv = (
|
|
460
|
-
env: NodeJS.ProcessEnv = process.env
|
|
504
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
461
505
|
): NodeJS.ProcessEnv => {
|
|
462
506
|
const sdkRoot = getAndroidSdkRoot(env);
|
|
463
507
|
|
|
@@ -492,19 +536,19 @@ export const initializeAndroidProcessEnv = (): void => {
|
|
|
492
536
|
};
|
|
493
537
|
|
|
494
538
|
export const getAdbBinaryPath = (
|
|
495
|
-
sdkRoot: string = getRequiredAndroidSdkRoot()
|
|
539
|
+
sdkRoot: string = getRequiredAndroidSdkRoot(),
|
|
496
540
|
): string => path.join(sdkRoot, 'platform-tools', 'adb');
|
|
497
541
|
|
|
498
542
|
export const getEmulatorBinaryPath = (
|
|
499
|
-
sdkRoot: string = getRequiredAndroidSdkRoot()
|
|
543
|
+
sdkRoot: string = getRequiredAndroidSdkRoot(),
|
|
500
544
|
): string => path.join(sdkRoot, 'emulator', 'emulator');
|
|
501
545
|
|
|
502
546
|
export const getSdkManagerBinaryPath = (
|
|
503
|
-
sdkRoot: string = getRequiredAndroidSdkRoot()
|
|
547
|
+
sdkRoot: string = getRequiredAndroidSdkRoot(),
|
|
504
548
|
): string =>
|
|
505
549
|
path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS, 'bin', 'sdkmanager');
|
|
506
550
|
|
|
507
551
|
export const getAvdManagerBinaryPath = (
|
|
508
|
-
sdkRoot: string = getRequiredAndroidSdkRoot()
|
|
552
|
+
sdkRoot: string = getRequiredAndroidSdkRoot(),
|
|
509
553
|
): string =>
|
|
510
554
|
path.join(sdkRoot, ...CMDLINE_TOOLS_PATH_SEGMENTS, 'bin', 'avdmanager');
|
package/src/instance.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { getDeviceName } from './utils.js';
|
|
|
27
27
|
import { createAndroidAppMonitor } from './app-monitor.js';
|
|
28
28
|
import { HarnessAppPathError, HarnessEmulatorConfigError } from './errors.js';
|
|
29
29
|
import {
|
|
30
|
+
ensureAndroidEmulatorAvailable,
|
|
30
31
|
ensureAndroidEmulatorEnvironment,
|
|
31
32
|
getHostAndroidSystemImageArch,
|
|
32
33
|
} from './environment.js';
|
|
@@ -61,7 +62,7 @@ const getHarnessAppPath = (): string => {
|
|
|
61
62
|
const configureAndroidRuntime = async (
|
|
62
63
|
adbId: string,
|
|
63
64
|
config: AndroidPlatformConfig,
|
|
64
|
-
harnessConfig: HarnessConfig
|
|
65
|
+
harnessConfig: HarnessConfig,
|
|
65
66
|
): Promise<number> => {
|
|
66
67
|
const metroPort = harnessConfig.metroPort;
|
|
67
68
|
|
|
@@ -84,6 +85,7 @@ const startAndWaitForBoot = async ({
|
|
|
84
85
|
signal: AbortSignal;
|
|
85
86
|
mode?: Parameters<typeof adb.startEmulator>[1];
|
|
86
87
|
}): Promise<string> => {
|
|
88
|
+
await ensureAndroidEmulatorAvailable();
|
|
87
89
|
await adb.startEmulator(emulatorName, mode);
|
|
88
90
|
return adb.waitForBoot(emulatorName, signal);
|
|
89
91
|
};
|
|
@@ -137,14 +139,14 @@ const prepareCachedAvd = async ({
|
|
|
137
139
|
hasExistingAvd
|
|
138
140
|
? 'Recreating incompatible Android emulator %s...'
|
|
139
141
|
: 'Creating Android emulator %s...',
|
|
140
|
-
emulatorName
|
|
142
|
+
emulatorName,
|
|
141
143
|
);
|
|
142
144
|
|
|
143
145
|
if (hasExistingAvd && !compatibility.compatible) {
|
|
144
146
|
androidInstanceLogger.debug(
|
|
145
147
|
'Android AVD %s is not reusable: %s',
|
|
146
148
|
emulatorName,
|
|
147
|
-
compatibility.reason
|
|
149
|
+
compatibility.reason,
|
|
148
150
|
);
|
|
149
151
|
await adb.deleteAvd(emulatorName);
|
|
150
152
|
}
|
|
@@ -174,7 +176,7 @@ const prepareCachedAvd = async ({
|
|
|
174
176
|
export const getAndroidEmulatorPlatformInstance = async (
|
|
175
177
|
config: AndroidPlatformConfig,
|
|
176
178
|
harnessConfig: HarnessConfig,
|
|
177
|
-
init: HarnessPlatformInitOptions
|
|
179
|
+
init: HarnessPlatformInitOptions,
|
|
178
180
|
): Promise<HarnessPlatformRunner> => {
|
|
179
181
|
assertAndroidDeviceEmulator(config.device);
|
|
180
182
|
const detectNativeCrashes = harnessConfig.detectNativeCrashes ?? true;
|
|
@@ -192,7 +194,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
192
194
|
androidInstanceLogger.debug(
|
|
193
195
|
'resolved Android emulator %s with adb id %s',
|
|
194
196
|
emulatorConfig.name,
|
|
195
|
-
adbId ?? 'not-found'
|
|
197
|
+
adbId ?? 'not-found',
|
|
196
198
|
);
|
|
197
199
|
|
|
198
200
|
if (!adbId) {
|
|
@@ -212,7 +214,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
212
214
|
logger.info('Creating Android emulator %s...', emulatorName);
|
|
213
215
|
androidInstanceLogger.debug(
|
|
214
216
|
'creating Android AVD %s before startup',
|
|
215
|
-
emulatorConfig.name
|
|
217
|
+
emulatorConfig.name,
|
|
216
218
|
);
|
|
217
219
|
await recreateAvd({ emulatorConfig });
|
|
218
220
|
} else {
|
|
@@ -221,7 +223,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
221
223
|
|
|
222
224
|
androidInstanceLogger.debug(
|
|
223
225
|
'starting Android emulator %s',
|
|
224
|
-
emulatorConfig.name
|
|
226
|
+
emulatorConfig.name,
|
|
225
227
|
);
|
|
226
228
|
return startAndWaitForBoot({
|
|
227
229
|
emulatorName: emulatorConfig.name,
|
|
@@ -234,10 +236,8 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
234
236
|
androidInstanceLogger.debug(
|
|
235
237
|
'Android emulator %s connected as %s',
|
|
236
238
|
emulatorConfig.name,
|
|
237
|
-
adbId
|
|
239
|
+
adbId,
|
|
238
240
|
);
|
|
239
|
-
} else if (emulatorConfig.avd) {
|
|
240
|
-
await ensureAndroidEmulatorEnvironment(emulatorConfig.avd.apiLevel);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
if (!adbId) {
|
|
@@ -246,7 +246,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
246
246
|
|
|
247
247
|
androidInstanceLogger.debug(
|
|
248
248
|
'waiting for Android emulator %s to finish booting',
|
|
249
|
-
adbId
|
|
249
|
+
adbId,
|
|
250
250
|
);
|
|
251
251
|
|
|
252
252
|
const isInstalled = await adb.isAppInstalled(adbId, config.bundleId);
|
|
@@ -265,7 +265,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
265
265
|
config.bundleId,
|
|
266
266
|
config.activityName,
|
|
267
267
|
(options as typeof config.appLaunchOptions | undefined) ??
|
|
268
|
-
config.appLaunchOptions
|
|
268
|
+
config.appLaunchOptions,
|
|
269
269
|
);
|
|
270
270
|
},
|
|
271
271
|
restartApp: async (options) => {
|
|
@@ -275,7 +275,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
275
275
|
config.bundleId,
|
|
276
276
|
config.activityName,
|
|
277
277
|
(options as typeof config.appLaunchOptions | undefined) ??
|
|
278
|
-
config.appLaunchOptions
|
|
278
|
+
config.appLaunchOptions,
|
|
279
279
|
);
|
|
280
280
|
},
|
|
281
281
|
stopApp: async () => {
|
|
@@ -311,7 +311,7 @@ export const getAndroidEmulatorPlatformInstance = async (
|
|
|
311
311
|
|
|
312
312
|
export const getAndroidPhysicalDevicePlatformInstance = async (
|
|
313
313
|
config: AndroidPlatformConfig,
|
|
314
|
-
harnessConfig: HarnessConfig
|
|
314
|
+
harnessConfig: HarnessConfig,
|
|
315
315
|
): Promise<HarnessPlatformRunner> => {
|
|
316
316
|
assertAndroidDevicePhysical(config.device);
|
|
317
317
|
const detectNativeCrashes = harnessConfig.detectNativeCrashes ?? true;
|
|
@@ -327,7 +327,7 @@ export const getAndroidPhysicalDevicePlatformInstance = async (
|
|
|
327
327
|
if (!isInstalled) {
|
|
328
328
|
throw new AppNotInstalledError(
|
|
329
329
|
config.bundleId,
|
|
330
|
-
getDeviceName(config.device)
|
|
330
|
+
getDeviceName(config.device),
|
|
331
331
|
);
|
|
332
332
|
}
|
|
333
333
|
|
|
@@ -340,7 +340,7 @@ export const getAndroidPhysicalDevicePlatformInstance = async (
|
|
|
340
340
|
config.bundleId,
|
|
341
341
|
config.activityName,
|
|
342
342
|
(options as typeof config.appLaunchOptions | undefined) ??
|
|
343
|
-
config.appLaunchOptions
|
|
343
|
+
config.appLaunchOptions,
|
|
344
344
|
);
|
|
345
345
|
},
|
|
346
346
|
restartApp: async (options) => {
|
|
@@ -350,7 +350,7 @@ export const getAndroidPhysicalDevicePlatformInstance = async (
|
|
|
350
350
|
config.bundleId,
|
|
351
351
|
config.activityName,
|
|
352
352
|
(options as typeof config.appLaunchOptions | undefined) ??
|
|
353
|
-
config.appLaunchOptions
|
|
353
|
+
config.appLaunchOptions,
|
|
354
354
|
);
|
|
355
355
|
},
|
|
356
356
|
stopApp: async () => {
|
package/src/runner.ts
CHANGED
|
@@ -13,34 +13,29 @@ import {
|
|
|
13
13
|
getAndroidPhysicalDevicePlatformInstance,
|
|
14
14
|
} from './instance.js';
|
|
15
15
|
import {
|
|
16
|
-
|
|
17
|
-
ensureAndroidPhysicalDeviceEnvironment,
|
|
16
|
+
ensureAndroidAdbAvailable,
|
|
18
17
|
initializeAndroidProcessEnv,
|
|
19
18
|
} from './environment.js';
|
|
20
19
|
|
|
21
20
|
const getAndroidRunner = async (
|
|
22
21
|
config: AndroidPlatformConfig,
|
|
23
22
|
harnessConfig: HarnessConfig,
|
|
24
|
-
init: HarnessPlatformInitOptions
|
|
23
|
+
init: HarnessPlatformInitOptions,
|
|
25
24
|
): Promise<HarnessPlatformRunner> => {
|
|
26
25
|
const parsedConfig = AndroidPlatformConfigSchema.parse(config);
|
|
27
26
|
|
|
28
27
|
initializeAndroidProcessEnv();
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
if (parsedConfig.device.avd) {
|
|
32
|
-
await ensureAndroidEmulatorEnvironment(parsedConfig.device.avd.apiLevel);
|
|
33
|
-
}
|
|
29
|
+
await ensureAndroidAdbAvailable();
|
|
34
30
|
|
|
31
|
+
if (isAndroidDeviceEmulator(parsedConfig.device)) {
|
|
35
32
|
return getAndroidEmulatorPlatformInstance(
|
|
36
33
|
parsedConfig,
|
|
37
34
|
harnessConfig,
|
|
38
|
-
init
|
|
35
|
+
init,
|
|
39
36
|
);
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
await ensureAndroidPhysicalDeviceEnvironment();
|
|
43
|
-
|
|
44
39
|
return getAndroidPhysicalDevicePlatformInstance(parsedConfig, harnessConfig);
|
|
45
40
|
};
|
|
46
41
|
|
package/src/targets.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { RunTarget } from '@react-native-harness/platforms';
|
|
2
2
|
import * as adb from './adb.js';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ensureAndroidAdbAvailable,
|
|
5
|
+
ensureAndroidEmulatorAvailable,
|
|
6
|
+
initializeAndroidProcessEnv,
|
|
7
|
+
} from './environment.js';
|
|
4
8
|
|
|
5
9
|
export const getRunTargets = async (): Promise<RunTarget[]> => {
|
|
6
|
-
|
|
10
|
+
initializeAndroidProcessEnv();
|
|
11
|
+
|
|
12
|
+
await ensureAndroidAdbAvailable();
|
|
13
|
+
await ensureAndroidEmulatorAvailable();
|
|
7
14
|
|
|
8
15
|
const [avds, connectedDevices] = await Promise.all([
|
|
9
16
|
adb.getAvds(),
|