@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
|
@@ -36,7 +36,7 @@ describe('Android platform instance', () => {
|
|
|
36
36
|
const ensureAndroidEmulatorEnvironment = vi
|
|
37
37
|
.spyOn(
|
|
38
38
|
await import('../environment.js'),
|
|
39
|
-
'ensureAndroidEmulatorEnvironment'
|
|
39
|
+
'ensureAndroidEmulatorEnvironment',
|
|
40
40
|
)
|
|
41
41
|
.mockResolvedValue('/tmp/android-sdk');
|
|
42
42
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue(['emulator-5554']);
|
|
@@ -47,10 +47,10 @@ describe('Android platform instance', () => {
|
|
|
47
47
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
48
48
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
49
49
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
50
|
-
undefined
|
|
50
|
+
undefined,
|
|
51
51
|
);
|
|
52
52
|
vi.spyOn(sharedPrefs, 'clearHarnessDebugHttpHost').mockResolvedValue(
|
|
53
|
-
undefined
|
|
53
|
+
undefined,
|
|
54
54
|
);
|
|
55
55
|
vi.spyOn(adb, 'stopApp').mockResolvedValue(undefined);
|
|
56
56
|
const stopEmulator = vi.spyOn(adb, 'stopEmulator').mockResolvedValue();
|
|
@@ -72,19 +72,19 @@ describe('Android platform instance', () => {
|
|
|
72
72
|
activityName: '.MainActivity',
|
|
73
73
|
},
|
|
74
74
|
harnessConfig,
|
|
75
|
-
init
|
|
75
|
+
init,
|
|
76
76
|
);
|
|
77
77
|
|
|
78
78
|
await instance.dispose();
|
|
79
79
|
|
|
80
|
-
expect(ensureAndroidEmulatorEnvironment).
|
|
80
|
+
expect(ensureAndroidEmulatorEnvironment).not.toHaveBeenCalled();
|
|
81
81
|
expect(stopEmulator).not.toHaveBeenCalled();
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
it('creates and boots an emulator when missing and shuts it down on dispose', async () => {
|
|
85
85
|
vi.spyOn(
|
|
86
86
|
await import('../environment.js'),
|
|
87
|
-
'ensureAndroidEmulatorEnvironment'
|
|
87
|
+
'ensureAndroidEmulatorEnvironment',
|
|
88
88
|
).mockResolvedValue('/tmp/android-sdk');
|
|
89
89
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue([]);
|
|
90
90
|
vi.spyOn(adb, 'hasAvd').mockResolvedValue(false);
|
|
@@ -98,10 +98,10 @@ describe('Android platform instance', () => {
|
|
|
98
98
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
99
99
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
100
100
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
101
|
-
undefined
|
|
101
|
+
undefined,
|
|
102
102
|
);
|
|
103
103
|
vi.spyOn(sharedPrefs, 'clearHarnessDebugHttpHost').mockResolvedValue(
|
|
104
|
-
undefined
|
|
104
|
+
undefined,
|
|
105
105
|
);
|
|
106
106
|
vi.spyOn(adb, 'stopApp').mockResolvedValue(undefined);
|
|
107
107
|
const stopEmulator = vi.spyOn(adb, 'stopEmulator').mockResolvedValue();
|
|
@@ -123,7 +123,7 @@ describe('Android platform instance', () => {
|
|
|
123
123
|
activityName: '.MainActivity',
|
|
124
124
|
},
|
|
125
125
|
harnessConfig,
|
|
126
|
-
init
|
|
126
|
+
init,
|
|
127
127
|
);
|
|
128
128
|
|
|
129
129
|
expect(createAvd).toHaveBeenCalledWith({
|
|
@@ -144,7 +144,7 @@ describe('Android platform instance', () => {
|
|
|
144
144
|
const ensureAndroidEmulatorEnvironment = vi
|
|
145
145
|
.spyOn(
|
|
146
146
|
await import('../environment.js'),
|
|
147
|
-
'ensureAndroidEmulatorEnvironment'
|
|
147
|
+
'ensureAndroidEmulatorEnvironment',
|
|
148
148
|
)
|
|
149
149
|
.mockResolvedValue('/tmp/android-sdk');
|
|
150
150
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue([]);
|
|
@@ -159,7 +159,7 @@ describe('Android platform instance', () => {
|
|
|
159
159
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
160
160
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
161
161
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
162
|
-
undefined
|
|
162
|
+
undefined,
|
|
163
163
|
);
|
|
164
164
|
|
|
165
165
|
await expect(
|
|
@@ -180,8 +180,8 @@ describe('Android platform instance', () => {
|
|
|
180
180
|
activityName: '.MainActivity',
|
|
181
181
|
},
|
|
182
182
|
harnessConfig,
|
|
183
|
-
init
|
|
184
|
-
)
|
|
183
|
+
init,
|
|
184
|
+
),
|
|
185
185
|
).resolves.toBeDefined();
|
|
186
186
|
|
|
187
187
|
expect(ensureAndroidEmulatorEnvironment).toHaveBeenCalledWith(35);
|
|
@@ -193,7 +193,7 @@ describe('Android platform instance', () => {
|
|
|
193
193
|
vi.stubEnv('HARNESS_AVD_CACHING', 'true');
|
|
194
194
|
vi.spyOn(
|
|
195
195
|
await import('../environment.js'),
|
|
196
|
-
'ensureAndroidEmulatorEnvironment'
|
|
196
|
+
'ensureAndroidEmulatorEnvironment',
|
|
197
197
|
).mockResolvedValue('/tmp/android-sdk');
|
|
198
198
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue([]);
|
|
199
199
|
vi.spyOn(adb, 'hasAvd').mockResolvedValue(true);
|
|
@@ -211,7 +211,7 @@ describe('Android platform instance', () => {
|
|
|
211
211
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
212
212
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
213
213
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
214
|
-
undefined
|
|
214
|
+
undefined,
|
|
215
215
|
);
|
|
216
216
|
|
|
217
217
|
await expect(
|
|
@@ -233,14 +233,14 @@ describe('Android platform instance', () => {
|
|
|
233
233
|
activityName: '.MainActivity',
|
|
234
234
|
},
|
|
235
235
|
harnessConfig,
|
|
236
|
-
init
|
|
237
|
-
)
|
|
236
|
+
init,
|
|
237
|
+
),
|
|
238
238
|
).resolves.toBeDefined();
|
|
239
239
|
|
|
240
240
|
expect(adb.startEmulator).toHaveBeenCalledTimes(1);
|
|
241
241
|
expect(adb.startEmulator).toHaveBeenCalledWith(
|
|
242
242
|
'Pixel_8_API_35',
|
|
243
|
-
'snapshot-reuse'
|
|
243
|
+
'snapshot-reuse',
|
|
244
244
|
);
|
|
245
245
|
});
|
|
246
246
|
|
|
@@ -248,7 +248,7 @@ describe('Android platform instance', () => {
|
|
|
248
248
|
vi.stubEnv('HARNESS_AVD_CACHING', 'true');
|
|
249
249
|
vi.spyOn(
|
|
250
250
|
await import('../environment.js'),
|
|
251
|
-
'ensureAndroidEmulatorEnvironment'
|
|
251
|
+
'ensureAndroidEmulatorEnvironment',
|
|
252
252
|
).mockResolvedValue('/tmp/android-sdk');
|
|
253
253
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue([]);
|
|
254
254
|
vi.spyOn(adb, 'hasAvd').mockResolvedValue(true);
|
|
@@ -272,7 +272,7 @@ describe('Android platform instance', () => {
|
|
|
272
272
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
273
273
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
274
274
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
275
|
-
undefined
|
|
275
|
+
undefined,
|
|
276
276
|
);
|
|
277
277
|
|
|
278
278
|
await expect(
|
|
@@ -294,8 +294,8 @@ describe('Android platform instance', () => {
|
|
|
294
294
|
activityName: '.MainActivity',
|
|
295
295
|
},
|
|
296
296
|
harnessConfig,
|
|
297
|
-
init
|
|
298
|
-
)
|
|
297
|
+
init,
|
|
298
|
+
),
|
|
299
299
|
).resolves.toBeDefined();
|
|
300
300
|
|
|
301
301
|
expect(deleteAvd).toHaveBeenCalledWith('Pixel_8_API_35');
|
|
@@ -303,17 +303,17 @@ describe('Android platform instance', () => {
|
|
|
303
303
|
expect(stopEmulator).toHaveBeenCalledWith('emulator-5554');
|
|
304
304
|
expect(waitForEmulatorDisconnect).toHaveBeenCalledWith(
|
|
305
305
|
'emulator-5554',
|
|
306
|
-
init.signal
|
|
306
|
+
init.signal,
|
|
307
307
|
);
|
|
308
308
|
expect(adb.startEmulator).toHaveBeenNthCalledWith(
|
|
309
309
|
1,
|
|
310
310
|
'Pixel_8_API_35',
|
|
311
|
-
'clean-snapshot-generation'
|
|
311
|
+
'clean-snapshot-generation',
|
|
312
312
|
);
|
|
313
313
|
expect(adb.startEmulator).toHaveBeenNthCalledWith(
|
|
314
314
|
2,
|
|
315
315
|
'Pixel_8_API_35',
|
|
316
|
-
'snapshot-reuse'
|
|
316
|
+
'snapshot-reuse',
|
|
317
317
|
);
|
|
318
318
|
});
|
|
319
319
|
|
|
@@ -321,7 +321,7 @@ describe('Android platform instance', () => {
|
|
|
321
321
|
vi.stubEnv('HARNESS_AVD_CACHING', 'true');
|
|
322
322
|
vi.spyOn(
|
|
323
323
|
await import('../environment.js'),
|
|
324
|
-
'ensureAndroidEmulatorEnvironment'
|
|
324
|
+
'ensureAndroidEmulatorEnvironment',
|
|
325
325
|
).mockResolvedValue('/tmp/android-sdk');
|
|
326
326
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue([]);
|
|
327
327
|
vi.spyOn(adb, 'hasAvd').mockResolvedValue(false);
|
|
@@ -339,7 +339,7 @@ describe('Android platform instance', () => {
|
|
|
339
339
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
340
340
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
341
341
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
342
|
-
undefined
|
|
342
|
+
undefined,
|
|
343
343
|
);
|
|
344
344
|
|
|
345
345
|
await expect(
|
|
@@ -361,24 +361,24 @@ describe('Android platform instance', () => {
|
|
|
361
361
|
activityName: '.MainActivity',
|
|
362
362
|
},
|
|
363
363
|
harnessConfig,
|
|
364
|
-
init
|
|
365
|
-
)
|
|
364
|
+
init,
|
|
365
|
+
),
|
|
366
366
|
).resolves.toBeDefined();
|
|
367
367
|
|
|
368
368
|
expect(startEmulator).toHaveBeenNthCalledWith(
|
|
369
369
|
1,
|
|
370
370
|
'Pixel_8_API_35',
|
|
371
|
-
'clean-snapshot-generation'
|
|
371
|
+
'clean-snapshot-generation',
|
|
372
372
|
);
|
|
373
373
|
expect(stopEmulator).toHaveBeenCalledWith('emulator-5554');
|
|
374
374
|
expect(waitForEmulatorDisconnect).toHaveBeenCalledWith(
|
|
375
375
|
'emulator-5554',
|
|
376
|
-
init.signal
|
|
376
|
+
init.signal,
|
|
377
377
|
);
|
|
378
378
|
expect(startEmulator).toHaveBeenNthCalledWith(
|
|
379
379
|
2,
|
|
380
380
|
'Pixel_8_API_35',
|
|
381
|
-
'snapshot-reuse'
|
|
381
|
+
'snapshot-reuse',
|
|
382
382
|
);
|
|
383
383
|
});
|
|
384
384
|
|
|
@@ -388,7 +388,7 @@ describe('Android platform instance', () => {
|
|
|
388
388
|
vi.stubEnv('HARNESS_APP_PATH', appPath);
|
|
389
389
|
vi.spyOn(
|
|
390
390
|
await import('../environment.js'),
|
|
391
|
-
'ensureAndroidEmulatorEnvironment'
|
|
391
|
+
'ensureAndroidEmulatorEnvironment',
|
|
392
392
|
).mockResolvedValue('/tmp/android-sdk');
|
|
393
393
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue(['emulator-5554']);
|
|
394
394
|
vi.spyOn(adb, 'getEmulatorName').mockResolvedValue('Pixel_8_API_35');
|
|
@@ -399,7 +399,7 @@ describe('Android platform instance', () => {
|
|
|
399
399
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
400
400
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
401
401
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
402
|
-
undefined
|
|
402
|
+
undefined,
|
|
403
403
|
);
|
|
404
404
|
|
|
405
405
|
await expect(
|
|
@@ -420,8 +420,8 @@ describe('Android platform instance', () => {
|
|
|
420
420
|
activityName: '.MainActivity',
|
|
421
421
|
},
|
|
422
422
|
harnessConfig,
|
|
423
|
-
init
|
|
424
|
-
)
|
|
423
|
+
init,
|
|
424
|
+
),
|
|
425
425
|
).resolves.toBeDefined();
|
|
426
426
|
|
|
427
427
|
expect(installApp).toHaveBeenCalledWith('emulator-5554', appPath);
|
|
@@ -453,8 +453,8 @@ describe('Android platform instance', () => {
|
|
|
453
453
|
activityName: '.MainActivity',
|
|
454
454
|
},
|
|
455
455
|
harnessConfig,
|
|
456
|
-
init
|
|
457
|
-
)
|
|
456
|
+
init,
|
|
457
|
+
),
|
|
458
458
|
).rejects.toBeInstanceOf(HarnessAppPathError);
|
|
459
459
|
});
|
|
460
460
|
|
|
@@ -483,8 +483,8 @@ describe('Android platform instance', () => {
|
|
|
483
483
|
activityName: '.MainActivity',
|
|
484
484
|
},
|
|
485
485
|
harnessConfig,
|
|
486
|
-
init
|
|
487
|
-
)
|
|
486
|
+
init,
|
|
487
|
+
),
|
|
488
488
|
).rejects.toBeInstanceOf(HarnessAppPathError);
|
|
489
489
|
});
|
|
490
490
|
|
|
@@ -503,15 +503,15 @@ describe('Android platform instance', () => {
|
|
|
503
503
|
activityName: '.MainActivity',
|
|
504
504
|
},
|
|
505
505
|
harnessConfig,
|
|
506
|
-
init
|
|
507
|
-
)
|
|
506
|
+
init,
|
|
507
|
+
),
|
|
508
508
|
).rejects.toBeInstanceOf(HarnessEmulatorConfigError);
|
|
509
509
|
});
|
|
510
510
|
|
|
511
511
|
it('returns a noop emulator app monitor when native crash detection is disabled', async () => {
|
|
512
512
|
vi.spyOn(
|
|
513
513
|
await import('../environment.js'),
|
|
514
|
-
'ensureAndroidEmulatorEnvironment'
|
|
514
|
+
'ensureAndroidEmulatorEnvironment',
|
|
515
515
|
).mockResolvedValue('/tmp/android-sdk');
|
|
516
516
|
vi.spyOn(adb, 'getDeviceIds').mockResolvedValue(['emulator-5554']);
|
|
517
517
|
vi.spyOn(adb, 'getEmulatorName').mockResolvedValue('Pixel_8_API_35');
|
|
@@ -521,7 +521,7 @@ describe('Android platform instance', () => {
|
|
|
521
521
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
522
522
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
523
523
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
524
|
-
undefined
|
|
524
|
+
undefined,
|
|
525
525
|
);
|
|
526
526
|
|
|
527
527
|
const instance = await getAndroidEmulatorPlatformInstance(
|
|
@@ -541,7 +541,7 @@ describe('Android platform instance', () => {
|
|
|
541
541
|
activityName: '.MainActivity',
|
|
542
542
|
},
|
|
543
543
|
harnessConfigWithoutNativeCrashDetection,
|
|
544
|
-
init
|
|
544
|
+
init,
|
|
545
545
|
);
|
|
546
546
|
|
|
547
547
|
const listener = vi.fn();
|
|
@@ -565,7 +565,7 @@ describe('Android platform instance', () => {
|
|
|
565
565
|
vi.spyOn(adb, 'setHideErrorDialogs').mockResolvedValue(undefined);
|
|
566
566
|
vi.spyOn(adb, 'getAppUid').mockResolvedValue(10234);
|
|
567
567
|
vi.spyOn(sharedPrefs, 'applyHarnessDebugHttpHost').mockResolvedValue(
|
|
568
|
-
undefined
|
|
568
|
+
undefined,
|
|
569
569
|
);
|
|
570
570
|
|
|
571
571
|
await expect(
|
|
@@ -580,8 +580,8 @@ describe('Android platform instance', () => {
|
|
|
580
580
|
bundleId: 'com.harnessplayground',
|
|
581
581
|
activityName: '.MainActivity',
|
|
582
582
|
},
|
|
583
|
-
harnessConfigWithoutNativeCrashDetection
|
|
584
|
-
)
|
|
583
|
+
harnessConfigWithoutNativeCrashDetection,
|
|
584
|
+
),
|
|
585
585
|
).resolves.toBeDefined();
|
|
586
586
|
|
|
587
587
|
const instance = await getAndroidPhysicalDevicePlatformInstance(
|
|
@@ -595,7 +595,7 @@ describe('Android platform instance', () => {
|
|
|
595
595
|
bundleId: 'com.harnessplayground',
|
|
596
596
|
activityName: '.MainActivity',
|
|
597
597
|
},
|
|
598
|
-
harnessConfigWithoutNativeCrashDetection
|
|
598
|
+
harnessConfigWithoutNativeCrashDetection,
|
|
599
599
|
);
|
|
600
600
|
|
|
601
601
|
const listener = vi.fn();
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
|
|
6
|
+
describe('Android target discovery', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
vi.restoreAllMocks();
|
|
9
|
+
vi.unstubAllEnvs();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('installs adb and emulator only for discovery', async () => {
|
|
13
|
+
const ensureAndroidAdbAvailable = vi
|
|
14
|
+
.spyOn(environment, 'ensureAndroidAdbAvailable')
|
|
15
|
+
.mockResolvedValue('/tmp/android-sdk');
|
|
16
|
+
const ensureAndroidEmulatorAvailable = vi
|
|
17
|
+
.spyOn(environment, 'ensureAndroidEmulatorAvailable')
|
|
18
|
+
.mockResolvedValue('/tmp/android-sdk');
|
|
19
|
+
vi.spyOn(adb, 'getAvds').mockResolvedValue(['Pixel_8_API_35']);
|
|
20
|
+
vi.spyOn(adb, 'getConnectedDevices').mockResolvedValue([
|
|
21
|
+
{
|
|
22
|
+
id: 'device-1',
|
|
23
|
+
manufacturer: 'Google',
|
|
24
|
+
model: 'Pixel 8',
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
await expect(getRunTargets()).resolves.toEqual([
|
|
29
|
+
{
|
|
30
|
+
type: 'emulator',
|
|
31
|
+
name: 'Pixel_8_API_35',
|
|
32
|
+
platform: 'android',
|
|
33
|
+
description: 'Android emulator',
|
|
34
|
+
device: {
|
|
35
|
+
name: 'Pixel_8_API_35',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: 'physical',
|
|
40
|
+
name: 'Google Pixel 8',
|
|
41
|
+
platform: 'android',
|
|
42
|
+
description: 'Physical device (device-1)',
|
|
43
|
+
device: {
|
|
44
|
+
manufacturer: 'Google',
|
|
45
|
+
model: 'Pixel 8',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
expect(ensureAndroidAdbAvailable).toHaveBeenCalledTimes(1);
|
|
51
|
+
expect(ensureAndroidEmulatorAvailable).toHaveBeenCalledTimes(1);
|
|
52
|
+
});
|
|
53
|
+
});
|
package/src/adb.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { ChildProcessByStdio } from 'node:child_process';
|
|
|
5
5
|
import { access, rm } from 'node:fs/promises';
|
|
6
6
|
import type { Readable } from 'node:stream';
|
|
7
7
|
import {
|
|
8
|
+
ensureAndroidEmulatorAvailable,
|
|
8
9
|
ensureAndroidSdkPackages,
|
|
9
10
|
getAdbBinaryPath,
|
|
10
11
|
getAndroidSystemImagePackage,
|
|
@@ -12,7 +13,6 @@ import {
|
|
|
12
13
|
getEmulatorBinaryPath,
|
|
13
14
|
getHostAndroidSystemImageArch,
|
|
14
15
|
getRequiredAndroidSdkPackages,
|
|
15
|
-
getSdkManagerBinaryPath,
|
|
16
16
|
} from './environment.js';
|
|
17
17
|
import {
|
|
18
18
|
getEmulatorStartupArgs,
|
|
@@ -36,14 +36,14 @@ const waitForAbort = (signal: AbortSignal): Promise<never> => {
|
|
|
36
36
|
() => {
|
|
37
37
|
reject(signal.reason);
|
|
38
38
|
},
|
|
39
|
-
{ once: true }
|
|
39
|
+
{ once: true },
|
|
40
40
|
);
|
|
41
41
|
});
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const waitWithSignal = async (
|
|
45
45
|
ms: number,
|
|
46
|
-
signal: AbortSignal
|
|
46
|
+
signal: AbortSignal,
|
|
47
47
|
): Promise<void> => {
|
|
48
48
|
if (signal.aborted) {
|
|
49
49
|
throw signal.reason;
|
|
@@ -63,7 +63,7 @@ const EMULATOR_OUTPUT_BUFFER_LIMIT = 16 * 1024;
|
|
|
63
63
|
export const emulatorProcess = {
|
|
64
64
|
startDetachedProcess: (
|
|
65
65
|
file: string,
|
|
66
|
-
args: readonly string[]
|
|
66
|
+
args: readonly string[],
|
|
67
67
|
): ChildProcessByStdio<null, Readable, Readable> =>
|
|
68
68
|
nodeSpawn(file, args, {
|
|
69
69
|
detached: true,
|
|
@@ -74,7 +74,7 @@ export const emulatorProcess = {
|
|
|
74
74
|
const appendBoundedOutput = (
|
|
75
75
|
output: string,
|
|
76
76
|
chunk: string,
|
|
77
|
-
limit: number = EMULATOR_OUTPUT_BUFFER_LIMIT
|
|
77
|
+
limit: number = EMULATOR_OUTPUT_BUFFER_LIMIT,
|
|
78
78
|
): string => {
|
|
79
79
|
const nextOutput = output + chunk;
|
|
80
80
|
|
|
@@ -131,16 +131,11 @@ const formatEmulatorStartupError = ({
|
|
|
131
131
|
};
|
|
132
132
|
|
|
133
133
|
const ensureEmulatorInstalled = async (): Promise<string> => {
|
|
134
|
-
|
|
134
|
+
await ensureAndroidEmulatorAvailable();
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
} catch {
|
|
140
|
-
await spawn(getSdkManagerBinaryPath(), ['emulator']);
|
|
141
|
-
await access(emulatorBinaryPath);
|
|
142
|
-
return emulatorBinaryPath;
|
|
143
|
-
}
|
|
136
|
+
const emulatorBinaryPath = getEmulatorBinaryPath();
|
|
137
|
+
await access(emulatorBinaryPath);
|
|
138
|
+
return emulatorBinaryPath;
|
|
144
139
|
};
|
|
145
140
|
|
|
146
141
|
export type CreateAvdOptions = {
|
|
@@ -160,7 +155,7 @@ export const getRequiredEmulatorPackages = (apiLevel: number): string[] => {
|
|
|
160
155
|
};
|
|
161
156
|
|
|
162
157
|
export const verifyAndroidEmulatorSdk = async (
|
|
163
|
-
apiLevel: number
|
|
158
|
+
apiLevel: number,
|
|
164
159
|
): Promise<void> => {
|
|
165
160
|
await ensureAndroidSdkPackages(getRequiredEmulatorPackages(apiLevel));
|
|
166
161
|
};
|
|
@@ -168,7 +163,7 @@ export const verifyAndroidEmulatorSdk = async (
|
|
|
168
163
|
export const getStartAppArgs = (
|
|
169
164
|
bundleId: string,
|
|
170
165
|
activityName: string,
|
|
171
|
-
options?: AndroidAppLaunchOptions
|
|
166
|
+
options?: AndroidAppLaunchOptions,
|
|
172
167
|
): string[] => {
|
|
173
168
|
const args = [
|
|
174
169
|
'shell',
|
|
@@ -197,7 +192,7 @@ export const getStartAppArgs = (
|
|
|
197
192
|
|
|
198
193
|
if (!Number.isSafeInteger(value)) {
|
|
199
194
|
throw new Error(
|
|
200
|
-
`Android app launch option "${key}" must be a safe integer
|
|
195
|
+
`Android app launch option "${key}" must be a safe integer.`,
|
|
201
196
|
);
|
|
202
197
|
}
|
|
203
198
|
|
|
@@ -209,7 +204,7 @@ export const getStartAppArgs = (
|
|
|
209
204
|
|
|
210
205
|
export const isAppInstalled = async (
|
|
211
206
|
adbId: string,
|
|
212
|
-
bundleId: string
|
|
207
|
+
bundleId: string,
|
|
213
208
|
): Promise<boolean> => {
|
|
214
209
|
const { stdout } = await spawn(getAdbBinaryPath(), [
|
|
215
210
|
'-s',
|
|
@@ -226,7 +221,7 @@ export const isAppInstalled = async (
|
|
|
226
221
|
export const reversePort = async (
|
|
227
222
|
adbId: string,
|
|
228
223
|
port: number,
|
|
229
|
-
hostPort: number = port
|
|
224
|
+
hostPort: number = port,
|
|
230
225
|
): Promise<void> => {
|
|
231
226
|
await spawn(getAdbBinaryPath(), [
|
|
232
227
|
'-s',
|
|
@@ -239,7 +234,7 @@ export const reversePort = async (
|
|
|
239
234
|
|
|
240
235
|
export const stopApp = async (
|
|
241
236
|
adbId: string,
|
|
242
|
-
bundleId: string
|
|
237
|
+
bundleId: string,
|
|
243
238
|
): Promise<void> => {
|
|
244
239
|
await spawn(getAdbBinaryPath(), [
|
|
245
240
|
'-s',
|
|
@@ -255,7 +250,7 @@ export const startApp = async (
|
|
|
255
250
|
adbId: string,
|
|
256
251
|
bundleId: string,
|
|
257
252
|
activityName: string,
|
|
258
|
-
options?: AndroidAppLaunchOptions
|
|
253
|
+
options?: AndroidAppLaunchOptions,
|
|
259
254
|
): Promise<void> => {
|
|
260
255
|
await spawn(getAdbBinaryPath(), [
|
|
261
256
|
'-s',
|
|
@@ -274,7 +269,7 @@ export const getDeviceIds = async (): Promise<string[]> => {
|
|
|
274
269
|
};
|
|
275
270
|
|
|
276
271
|
export const getEmulatorName = async (
|
|
277
|
-
adbId: string
|
|
272
|
+
adbId: string,
|
|
278
273
|
): Promise<string | null> => {
|
|
279
274
|
const { stdout } = await spawn(getAdbBinaryPath(), [
|
|
280
275
|
'-s',
|
|
@@ -288,7 +283,7 @@ export const getEmulatorName = async (
|
|
|
288
283
|
|
|
289
284
|
export const getShellProperty = async (
|
|
290
285
|
adbId: string,
|
|
291
|
-
property: string
|
|
286
|
+
property: string,
|
|
292
287
|
): Promise<string | null> => {
|
|
293
288
|
const { stdout } = await spawn(getAdbBinaryPath(), [
|
|
294
289
|
'-s',
|
|
@@ -310,7 +305,7 @@ export type DeviceInfo = {
|
|
|
310
305
|
};
|
|
311
306
|
|
|
312
307
|
export const getDeviceInfo = async (
|
|
313
|
-
adbId: string
|
|
308
|
+
adbId: string,
|
|
314
309
|
): Promise<DeviceInfo | null> => {
|
|
315
310
|
const manufacturer = await getShellProperty(adbId, 'ro.product.manufacturer');
|
|
316
311
|
const model = await getShellProperty(adbId, 'ro.product.model');
|
|
@@ -336,7 +331,7 @@ export const stopEmulator = async (adbId: string): Promise<void> => {
|
|
|
336
331
|
|
|
337
332
|
export const installApp = async (
|
|
338
333
|
adbId: string,
|
|
339
|
-
appPath: string
|
|
334
|
+
appPath: string,
|
|
340
335
|
): Promise<void> => {
|
|
341
336
|
await spawn(getAdbBinaryPath(), ['-s', adbId, 'install', '-r', appPath]);
|
|
342
337
|
};
|
|
@@ -355,7 +350,7 @@ export const createAvd = async ({
|
|
|
355
350
|
}: CreateAvdOptions): Promise<void> => {
|
|
356
351
|
const systemImagePackage = getAndroidSystemImagePackage(
|
|
357
352
|
apiLevel,
|
|
358
|
-
getHostAndroidSystemImageArch()
|
|
353
|
+
getHostAndroidSystemImageArch(),
|
|
359
354
|
);
|
|
360
355
|
|
|
361
356
|
await verifyAndroidEmulatorSdk(apiLevel);
|
|
@@ -366,7 +361,7 @@ export const createAvd = async ({
|
|
|
366
361
|
await spawn('bash', [
|
|
367
362
|
'-lc',
|
|
368
363
|
`printf '%s\n%s\n' 'disk.dataPartition.size=${diskSize}' 'vm.heapSize=${heapSize}' >> "${getAvdConfigPath(
|
|
369
|
-
name
|
|
364
|
+
name,
|
|
370
365
|
)}"`,
|
|
371
366
|
]);
|
|
372
367
|
};
|
|
@@ -379,7 +374,7 @@ export const deleteAvd = async (name: string): Promise<void> => {
|
|
|
379
374
|
{
|
|
380
375
|
force: true,
|
|
381
376
|
recursive: true,
|
|
382
|
-
}
|
|
377
|
+
},
|
|
383
378
|
);
|
|
384
379
|
await rm(
|
|
385
380
|
`${
|
|
@@ -387,18 +382,18 @@ export const deleteAvd = async (name: string): Promise<void> => {
|
|
|
387
382
|
}/${name}.ini`,
|
|
388
383
|
{
|
|
389
384
|
force: true,
|
|
390
|
-
}
|
|
385
|
+
},
|
|
391
386
|
);
|
|
392
387
|
};
|
|
393
388
|
|
|
394
389
|
export const startEmulator = async (
|
|
395
390
|
name: string,
|
|
396
|
-
mode: EmulatorBootMode = 'default-boot'
|
|
391
|
+
mode: EmulatorBootMode = 'default-boot',
|
|
397
392
|
): Promise<void> => {
|
|
398
393
|
const emulatorBinaryPath = await ensureEmulatorInstalled();
|
|
399
394
|
const childProcess = emulatorProcess.startDetachedProcess(
|
|
400
395
|
emulatorBinaryPath,
|
|
401
|
-
getEmulatorStartupArgs(name, mode)
|
|
396
|
+
getEmulatorStartupArgs(name, mode),
|
|
402
397
|
);
|
|
403
398
|
|
|
404
399
|
let stdout = '';
|
|
@@ -434,7 +429,7 @@ export const startEmulator = async (
|
|
|
434
429
|
stdout,
|
|
435
430
|
stderr,
|
|
436
431
|
error,
|
|
437
|
-
})
|
|
432
|
+
}),
|
|
438
433
|
);
|
|
439
434
|
});
|
|
440
435
|
|
|
@@ -446,7 +441,7 @@ export const startEmulator = async (
|
|
|
446
441
|
stderr,
|
|
447
442
|
exitCode,
|
|
448
443
|
signal,
|
|
449
|
-
})
|
|
444
|
+
}),
|
|
450
445
|
);
|
|
451
446
|
});
|
|
452
447
|
});
|
|
@@ -462,7 +457,7 @@ export const startEmulator = async (
|
|
|
462
457
|
});
|
|
463
458
|
|
|
464
459
|
const observationTimeout = wait(EMULATOR_STARTUP_OBSERVATION_TIMEOUT_MS).then(
|
|
465
|
-
() => 'timeout' as const
|
|
460
|
+
() => 'timeout' as const,
|
|
466
461
|
);
|
|
467
462
|
|
|
468
463
|
try {
|
|
@@ -478,7 +473,7 @@ export const startEmulator = async (
|
|
|
478
473
|
|
|
479
474
|
export const waitForEmulator = async (
|
|
480
475
|
name: string,
|
|
481
|
-
signal: AbortSignal
|
|
476
|
+
signal: AbortSignal,
|
|
482
477
|
): Promise<string> => {
|
|
483
478
|
while (!signal.aborted) {
|
|
484
479
|
const adbIds = await getDeviceIds();
|
|
@@ -503,7 +498,7 @@ export const waitForEmulator = async (
|
|
|
503
498
|
|
|
504
499
|
export const waitForEmulatorDisconnect = async (
|
|
505
500
|
adbId: string,
|
|
506
|
-
signal: AbortSignal
|
|
501
|
+
signal: AbortSignal,
|
|
507
502
|
): Promise<void> => {
|
|
508
503
|
while (!signal.aborted) {
|
|
509
504
|
const adbIds = await getDeviceIds();
|
|
@@ -520,7 +515,7 @@ export const waitForEmulatorDisconnect = async (
|
|
|
520
515
|
|
|
521
516
|
export const waitForBoot = async (
|
|
522
517
|
name: string,
|
|
523
|
-
signal: AbortSignal
|
|
518
|
+
signal: AbortSignal,
|
|
524
519
|
): Promise<string> => {
|
|
525
520
|
while (!signal.aborted) {
|
|
526
521
|
const adbIds = await getDeviceIds();
|
|
@@ -549,7 +544,7 @@ export const waitForBoot = async (
|
|
|
549
544
|
|
|
550
545
|
export const isAppRunning = async (
|
|
551
546
|
adbId: string,
|
|
552
|
-
bundleId: string
|
|
547
|
+
bundleId: string,
|
|
553
548
|
): Promise<boolean> => {
|
|
554
549
|
try {
|
|
555
550
|
const { stdout } = await spawn(getAdbBinaryPath(), [
|
|
@@ -571,7 +566,7 @@ export const isAppRunning = async (
|
|
|
571
566
|
|
|
572
567
|
export const getAppUid = async (
|
|
573
568
|
adbId: string,
|
|
574
|
-
bundleId: string
|
|
569
|
+
bundleId: string,
|
|
575
570
|
): Promise<number> => {
|
|
576
571
|
const { stdout } = await spawn(getAdbBinaryPath(), [
|
|
577
572
|
'-s',
|
|
@@ -596,7 +591,7 @@ export const getAppUid = async (
|
|
|
596
591
|
|
|
597
592
|
export const setHideErrorDialogs = async (
|
|
598
593
|
adbId: string,
|
|
599
|
-
hide: boolean
|
|
594
|
+
hide: boolean,
|
|
600
595
|
): Promise<void> => {
|
|
601
596
|
await spawn(getAdbBinaryPath(), [
|
|
602
597
|
'-s',
|