@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.
Files changed (41) hide show
  1. package/dist/__tests__/adb.test.js +77 -5
  2. package/dist/__tests__/environment.test.js +67 -1
  3. package/dist/__tests__/instance.test.js +1 -1
  4. package/dist/__tests__/targets.test.d.ts +2 -0
  5. package/dist/__tests__/targets.test.d.ts.map +1 -0
  6. package/dist/__tests__/targets.test.js +49 -0
  7. package/dist/adb.d.ts.map +1 -1
  8. package/dist/adb.js +47 -13
  9. package/dist/config.d.ts +16 -16
  10. package/dist/environment.d.ts +3 -0
  11. package/dist/environment.d.ts.map +1 -1
  12. package/dist/environment.js +33 -11
  13. package/dist/instance.d.ts.map +1 -1
  14. package/dist/instance.js +2 -4
  15. package/dist/runner.d.ts.map +1 -1
  16. package/dist/runner.js +2 -5
  17. package/dist/targets.d.ts.map +1 -1
  18. package/dist/targets.js +4 -2
  19. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  20. package/package.json +4 -4
  21. package/src/__tests__/adb.test.ts +133 -28
  22. package/src/__tests__/environment.test.ts +135 -10
  23. package/src/__tests__/instance.test.ts +49 -49
  24. package/src/__tests__/targets.test.ts +53 -0
  25. package/src/adb.ts +106 -48
  26. package/src/environment.ts +99 -55
  27. package/src/instance.ts +17 -17
  28. package/src/runner.ts +5 -10
  29. package/src/targets.ts +9 -2
  30. package/dist/assertions.d.ts +0 -5
  31. package/dist/assertions.d.ts.map +0 -1
  32. package/dist/assertions.js +0 -6
  33. package/dist/emulator.d.ts +0 -6
  34. package/dist/emulator.d.ts.map +0 -1
  35. package/dist/emulator.js +0 -27
  36. package/dist/reader.d.ts +0 -6
  37. package/dist/reader.d.ts.map +0 -1
  38. package/dist/reader.js +0 -57
  39. package/dist/types.d.ts +0 -381
  40. package/dist/types.d.ts.map +0 -1
  41. package/dist/types.js +0 -107
@@ -17,6 +17,7 @@ import {
17
17
  } from '../adb.js';
18
18
  import * as tools from '@react-native-harness/tools';
19
19
  import * as environment from '../environment.js';
20
+ import * as avdConfig from '../avd-config.js';
20
21
 
21
22
  const createAbortError = () =>
22
23
  new DOMException('The operation was aborted', 'AbortError');
@@ -48,7 +49,7 @@ describe('getStartAppArgs', () => {
48
49
  user_id: 42,
49
50
  mode: 'debug',
50
51
  },
51
- })
52
+ }),
52
53
  ).toEqual([
53
54
  'shell',
54
55
  'am',
@@ -77,7 +78,7 @@ describe('getStartAppArgs', () => {
77
78
  extras: {
78
79
  count: Number.MAX_SAFE_INTEGER + 1,
79
80
  },
80
- })
81
+ }),
81
82
  ).toThrow('must be a safe integer');
82
83
  });
83
84
 
@@ -88,7 +89,7 @@ describe('getStartAppArgs', () => {
88
89
  } as Awaited<ReturnType<typeof tools.spawn>>);
89
90
 
90
91
  await expect(getAppUid('emulator-5554', 'com.example.app')).resolves.toBe(
91
- 10234
92
+ 10234,
92
93
  );
93
94
 
94
95
  expect(spawnSpy).toHaveBeenCalledWith(expect.stringMatching(/adb$/), [
@@ -108,7 +109,7 @@ describe('getStartAppArgs', () => {
108
109
  } as Awaited<ReturnType<typeof tools.spawn>>);
109
110
 
110
111
  await expect(getLogcatTimestamp('emulator-5554')).resolves.toBe(
111
- '03-12 11:35:08.000'
112
+ '03-12 11:35:08.000',
112
113
  );
113
114
 
114
115
  expect(spawnSpy).toHaveBeenCalledWith(expect.stringMatching(/adb$/), [
@@ -146,14 +147,19 @@ describe('getStartAppArgs', () => {
146
147
  });
147
148
 
148
149
  it('creates an AVD and appends config overrides', async () => {
150
+ vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
149
151
  const spawnSpy = vi
150
152
  .spyOn(tools, 'spawn')
151
- .mockResolvedValue({} as Awaited<ReturnType<typeof tools.spawn>>);
153
+ .mockResolvedValue({} as Awaited<ReturnType<typeof tools.spawn>>)
154
+ .mockResolvedValueOnce({
155
+ stdout:
156
+ 'id: 0 or "pixel_8"\n Name: Pixel 8\nid: 1 or "pixel_6"\n Name: Pixel 6\n',
157
+ } as Awaited<ReturnType<typeof tools.spawn>>);
152
158
  const verifyAndroidEmulatorSdk = vi
153
159
  .spyOn(environment, 'ensureAndroidSdkPackages')
154
160
  .mockResolvedValue('/tmp/android-sdk');
155
161
  vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue(
156
- 'x86_64'
162
+ 'x86_64',
157
163
  );
158
164
 
159
165
  await createAvd({
@@ -170,29 +176,128 @@ describe('getStartAppArgs', () => {
170
176
  'platforms;android-35',
171
177
  'system-images;android-35;default;x86_64',
172
178
  ]);
173
- expect(spawnSpy).toHaveBeenNthCalledWith(1, 'bash', [
179
+ expect(spawnSpy).toHaveBeenNthCalledWith(
180
+ 1,
181
+ expect.stringMatching(/avdmanager$/),
182
+ ['list', 'device'],
183
+ );
184
+ expect(spawnSpy).toHaveBeenNthCalledWith(2, 'bash', [
174
185
  '-lc',
175
186
  expect.stringContaining(
176
- 'create avd --force --name "Pixel_8_API_35" --package "system-images;android-35;default;x86_64" --device "pixel_8"'
187
+ 'create avd --force --name "Pixel_8_API_35" --package "system-images;android-35;default;x86_64" --device "pixel_8" -p ',
177
188
  ),
178
189
  ]);
179
- expect(spawnSpy).toHaveBeenNthCalledWith(2, 'bash', [
190
+ expect(spawnSpy).toHaveBeenNthCalledWith(3, 'bash', [
191
+ '-lc',
192
+ expect.stringContaining(`'avd.ini.encoding=UTF-8' 'path=`),
193
+ ]);
194
+ expect(spawnSpy).toHaveBeenNthCalledWith(4, 'bash', [
180
195
  '-lc',
181
196
  expect.stringContaining(
182
- `'disk.dataPartition.size=1G' 'vm.heapSize=1G' >> `
197
+ `'disk.dataPartition.size=1G' 'vm.heapSize=1G' >> `,
183
198
  ),
184
199
  ]);
185
200
  });
186
201
 
187
- it('creates an AVD with arm64 system image packages on arm64 hosts', async () => {
188
- vi.spyOn(tools, 'spawn').mockResolvedValue(
189
- {} as Awaited<ReturnType<typeof tools.spawn>>
202
+ it('recreates the companion ini file when avdmanager leaves it missing', async () => {
203
+ vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
204
+ const spawnSpy = vi
205
+ .spyOn(tools, 'spawn')
206
+ .mockResolvedValue({} as Awaited<ReturnType<typeof tools.spawn>>)
207
+ .mockResolvedValueOnce({
208
+ stdout: 'id: 0 or "pixel_6"\n Name: Pixel 6\n',
209
+ } as Awaited<ReturnType<typeof tools.spawn>>);
210
+ vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue(
211
+ '/tmp/android-sdk',
212
+ );
213
+ vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue(
214
+ 'x86_64',
190
215
  );
216
+
217
+ await createAvd({
218
+ name: 'Pixel_6_API_35',
219
+ apiLevel: 35,
220
+ profile: 'pixel_6',
221
+ diskSize: '1G',
222
+ heapSize: '1G',
223
+ });
224
+
225
+ expect(spawnSpy).toHaveBeenNthCalledWith(3, 'bash', [
226
+ '-lc',
227
+ expect.stringContaining(`'avd.ini.encoding=UTF-8' 'path=`),
228
+ ]);
229
+ expect(spawnSpy).toHaveBeenNthCalledWith(4, 'bash', [
230
+ '-lc',
231
+ expect.stringContaining(
232
+ `'disk.dataPartition.size=1G' 'vm.heapSize=1G' >> `,
233
+ ),
234
+ ]);
235
+ });
236
+
237
+ it('throws an actionable error when the requested AVD profile is unavailable', async () => {
238
+ vi.spyOn(tools, 'spawn').mockResolvedValueOnce({
239
+ stdout:
240
+ 'id: 0 or "pixel_8"\n Name: Pixel 8\nid: 1 or "pixel_6"\n Name: Pixel 6\n',
241
+ } as Awaited<ReturnType<typeof tools.spawn>>);
242
+ vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue(
243
+ '/tmp/android-sdk',
244
+ );
245
+ vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue(
246
+ 'x86_64',
247
+ );
248
+
249
+ await expect(
250
+ createAvd({
251
+ name: 'Pixel_8_Pro_API_35',
252
+ apiLevel: 35,
253
+ profile: 'pixel_8_pro',
254
+ diskSize: '1G',
255
+ heapSize: '1G',
256
+ }),
257
+ ).rejects.toThrow(
258
+ 'Android AVD profile "pixel_8_pro" is not available on this machine. Available profiles: pixel_8, pixel_6',
259
+ );
260
+ });
261
+
262
+ it('throws a clear error when avdmanager does not create config.ini', async () => {
263
+ vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue(null);
264
+ vi.spyOn(tools, 'spawn')
265
+ .mockResolvedValue({} as Awaited<ReturnType<typeof tools.spawn>>)
266
+ .mockResolvedValueOnce({
267
+ stdout: 'id: 0 or "pixel_6"\n Name: Pixel 6\n',
268
+ } as Awaited<ReturnType<typeof tools.spawn>>);
269
+ vi.spyOn(environment, 'ensureAndroidSdkPackages').mockResolvedValue(
270
+ '/tmp/android-sdk',
271
+ );
272
+ vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue(
273
+ 'x86_64',
274
+ );
275
+
276
+ await expect(
277
+ createAvd({
278
+ name: 'Pixel_6_API_35',
279
+ apiLevel: 35,
280
+ profile: 'pixel_6',
281
+ diskSize: '1G',
282
+ heapSize: '1G',
283
+ }),
284
+ ).rejects.toThrow(
285
+ 'Android AVD "Pixel_6_API_35" was created, but config.ini was not found at ',
286
+ );
287
+ });
288
+
289
+ it('creates an AVD with arm64 system image packages on arm64 hosts', async () => {
290
+ vi.spyOn(avdConfig, 'readAvdConfig').mockResolvedValue({});
291
+ vi.spyOn(tools, 'spawn')
292
+ .mockResolvedValue({} as Awaited<ReturnType<typeof tools.spawn>>)
293
+ .mockResolvedValueOnce({
294
+ stdout: 'id: 0 or "pixel_8"\n Name: Pixel 8\n',
295
+ } as Awaited<ReturnType<typeof tools.spawn>>);
191
296
  const ensureAndroidSdkPackages = vi
192
297
  .spyOn(environment, 'ensureAndroidSdkPackages')
193
298
  .mockResolvedValue('/tmp/android-sdk');
194
299
  vi.spyOn(environment, 'getHostAndroidSystemImageArch').mockReturnValue(
195
- 'arm64-v8a'
300
+ 'arm64-v8a',
196
301
  );
197
302
 
198
303
  await createAvd({
@@ -241,7 +346,7 @@ describe('getStartAppArgs', () => {
241
346
  child.emit('close', 1, null);
242
347
 
243
348
  await expect(startPromise).rejects.toThrow(
244
- 'Unknown AVD name [Pixel_8_API_35]'
349
+ 'Unknown AVD name [Pixel_8_API_35]',
245
350
  );
246
351
  });
247
352
 
@@ -271,7 +376,7 @@ describe('getStartAppArgs', () => {
271
376
  child.emit('close', 1, null);
272
377
 
273
378
  await expect(startPromise).rejects.toThrow(
274
- 'emulator: panic: broken config'
379
+ 'emulator: panic: broken config',
275
380
  );
276
381
  });
277
382
 
@@ -291,7 +396,7 @@ describe('getStartAppArgs', () => {
291
396
  vi.spyOn(emulatorProcess, 'startDetachedProcess').mockReturnValue(
292
397
  child as unknown as ReturnType<
293
398
  typeof emulatorProcess.startDetachedProcess
294
- >
399
+ >,
295
400
  );
296
401
 
297
402
  const startPromise = startEmulator('Pixel_8_API_35');
@@ -317,7 +422,7 @@ describe('getStartAppArgs', () => {
317
422
  .mockReturnValue(
318
423
  child as unknown as ReturnType<
319
424
  typeof emulatorProcess.startDetachedProcess
320
- >
425
+ >,
321
426
  );
322
427
 
323
428
  const startPromise = startEmulator('Pixel_8_API_35');
@@ -326,7 +431,7 @@ describe('getStartAppArgs', () => {
326
431
 
327
432
  expect(startDetachedProcess).toHaveBeenCalledWith(
328
433
  expect.stringMatching(/emulator$/),
329
- expect.arrayContaining(['-no-snapshot-load', '-no-snapshot-save'])
434
+ expect.arrayContaining(['-no-snapshot-load', '-no-snapshot-save']),
330
435
  );
331
436
  });
332
437
 
@@ -345,22 +450,22 @@ describe('getStartAppArgs', () => {
345
450
  .mockReturnValue(
346
451
  child as unknown as ReturnType<
347
452
  typeof emulatorProcess.startDetachedProcess
348
- >
453
+ >,
349
454
  );
350
455
 
351
456
  const startPromise = startEmulator(
352
457
  'Pixel_8_API_35',
353
- 'clean-snapshot-generation'
458
+ 'clean-snapshot-generation',
354
459
  );
355
460
  await vi.runAllTimersAsync();
356
461
  await startPromise;
357
462
 
358
463
  expect(startDetachedProcess).toHaveBeenCalledWith(
359
464
  expect.stringMatching(/emulator$/),
360
- expect.arrayContaining(['-no-snapshot-load'])
465
+ expect.arrayContaining(['-no-snapshot-load']),
361
466
  );
362
467
  expect(startDetachedProcess.mock.calls[0]?.[1]).not.toContain(
363
- '-no-snapshot-save'
468
+ '-no-snapshot-save',
364
469
  );
365
470
  });
366
471
 
@@ -379,7 +484,7 @@ describe('getStartAppArgs', () => {
379
484
  .mockReturnValue(
380
485
  child as unknown as ReturnType<
381
486
  typeof emulatorProcess.startDetachedProcess
382
- >
487
+ >,
383
488
  );
384
489
 
385
490
  const startPromise = startEmulator('Pixel_8_API_35', 'snapshot-reuse');
@@ -388,10 +493,10 @@ describe('getStartAppArgs', () => {
388
493
 
389
494
  expect(startDetachedProcess).toHaveBeenCalledWith(
390
495
  expect.stringMatching(/emulator$/),
391
- expect.arrayContaining(['-no-snapshot-save'])
496
+ expect.arrayContaining(['-no-snapshot-save']),
392
497
  );
393
498
  expect(startDetachedProcess.mock.calls[0]?.[1]).not.toContain(
394
- '-no-snapshot-load'
499
+ '-no-snapshot-load',
395
500
  );
396
501
  });
397
502
 
@@ -459,7 +564,7 @@ describe('getStartAppArgs', () => {
459
564
 
460
565
  const waitPromise = waitForBoot(
461
566
  'Pixel_8_API_35',
462
- new AbortController().signal
567
+ new AbortController().signal,
463
568
  );
464
569
 
465
570
  await vi.advanceTimersByTimeAsync(1000);
@@ -482,7 +587,7 @@ describe('getStartAppArgs', () => {
482
587
 
483
588
  const waitPromise = waitForEmulatorDisconnect(
484
589
  'emulator-5554',
485
- new AbortController().signal
590
+ new AbortController().signal,
486
591
  );
487
592
 
488
593
  await vi.advanceTimersByTimeAsync(1000);
@@ -1,11 +1,17 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
2
5
  import {
6
+ ensureAndroidAdbAvailable,
7
+ ensureAndroidEmulatorAvailable,
3
8
  getAndroidSdkRoot,
4
9
  getAndroidSystemImagePackage,
5
10
  getDefaultUnixAndroidSdkRoot,
6
11
  getHostAndroidSystemImageArch,
7
12
  getRequiredAndroidSdkPackages,
8
13
  } from '../environment.js';
14
+ import * as tools from '@react-native-harness/tools';
9
15
 
10
16
  describe('Android environment', () => {
11
17
  beforeEach(() => {
@@ -13,12 +19,131 @@ describe('Android environment', () => {
13
19
  vi.unstubAllEnvs();
14
20
  });
15
21
 
22
+ it('skips bootstrapping command-line tools when adb is already installed', async () => {
23
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
24
+ const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
25
+
26
+ fs.mkdirSync(path.dirname(adbPath), { recursive: true });
27
+ fs.writeFileSync(adbPath, '');
28
+
29
+ const spawnSpy = vi.spyOn(tools, 'spawn');
30
+
31
+ await expect(
32
+ ensureAndroidAdbAvailable({
33
+ env: { ANDROID_HOME: sdkRoot },
34
+ }),
35
+ ).resolves.toBe(sdkRoot);
36
+
37
+ expect(spawnSpy).not.toHaveBeenCalled();
38
+
39
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
40
+ });
41
+
42
+ it('installs only platform-tools when adb is missing', async () => {
43
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
44
+ const sdkManagerDirectory = path.join(
45
+ sdkRoot,
46
+ 'cmdline-tools',
47
+ 'latest',
48
+ 'bin',
49
+ );
50
+
51
+ fs.mkdirSync(sdkManagerDirectory, { recursive: true });
52
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
53
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
54
+
55
+ const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (
56
+ command: string,
57
+ args?: readonly string[],
58
+ ) => {
59
+ if (command === 'bash' && typeof args?.[1] === 'string') {
60
+ const commandString = args[1];
61
+
62
+ if (commandString.includes('platform-tools')) {
63
+ const adbPath = path.join(sdkRoot, 'platform-tools', 'adb');
64
+ fs.mkdirSync(path.dirname(adbPath), { recursive: true });
65
+ fs.writeFileSync(adbPath, '');
66
+ }
67
+ }
68
+
69
+ return {} as Awaited<ReturnType<typeof tools.spawn>>;
70
+ }) as typeof tools.spawn);
71
+
72
+ await expect(
73
+ ensureAndroidAdbAvailable({
74
+ env: { ANDROID_HOME: sdkRoot },
75
+ }),
76
+ ).resolves.toBe(sdkRoot);
77
+
78
+ expect(spawnSpy).toHaveBeenCalledWith(
79
+ 'bash',
80
+ ['-lc', expect.stringContaining('platform-tools')],
81
+ expect.any(Object),
82
+ );
83
+ expect(
84
+ spawnSpy.mock.calls.some(
85
+ ([command, args]) =>
86
+ command === 'bash' &&
87
+ typeof args?.[1] === 'string' &&
88
+ args[1].includes('platform-tools') &&
89
+ args[1].includes('emulator'),
90
+ ),
91
+ ).toBe(false);
92
+
93
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
94
+ });
95
+
96
+ it('installs emulator only when emulator is missing', async () => {
97
+ const sdkRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'android-sdk-'));
98
+ const sdkManagerDirectory = path.join(
99
+ sdkRoot,
100
+ 'cmdline-tools',
101
+ 'latest',
102
+ 'bin',
103
+ );
104
+
105
+ fs.mkdirSync(sdkManagerDirectory, { recursive: true });
106
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'sdkmanager'), '');
107
+ fs.writeFileSync(path.join(sdkManagerDirectory, 'avdmanager'), '');
108
+
109
+ const spawnSpy = vi.spyOn(tools, 'spawn').mockImplementation((async (
110
+ command: string,
111
+ args?: readonly string[],
112
+ ) => {
113
+ if (command === 'bash' && typeof args?.[1] === 'string') {
114
+ const commandString = args[1];
115
+
116
+ if (commandString.includes('emulator')) {
117
+ const emulatorPath = path.join(sdkRoot, 'emulator', 'emulator');
118
+ fs.mkdirSync(path.dirname(emulatorPath), { recursive: true });
119
+ fs.writeFileSync(emulatorPath, '');
120
+ }
121
+ }
122
+
123
+ return {} as Awaited<ReturnType<typeof tools.spawn>>;
124
+ }) as typeof tools.spawn);
125
+
126
+ await expect(
127
+ ensureAndroidEmulatorAvailable({
128
+ env: { ANDROID_HOME: sdkRoot },
129
+ }),
130
+ ).resolves.toBe(sdkRoot);
131
+
132
+ expect(spawnSpy).toHaveBeenCalledWith(
133
+ 'bash',
134
+ ['-lc', expect.stringContaining('emulator')],
135
+ expect.any(Object),
136
+ );
137
+
138
+ fs.rmSync(sdkRoot, { force: true, recursive: true });
139
+ });
140
+
16
141
  it('uses the default Unix SDK root when env vars are missing', () => {
17
142
  expect(
18
143
  getDefaultUnixAndroidSdkRoot({
19
144
  platform: 'darwin',
20
145
  homeDirectory: '/Users/tester',
21
- })
146
+ }),
22
147
  ).toBe('/Users/tester/Library/Android/sdk');
23
148
 
24
149
  expect(
@@ -27,8 +152,8 @@ describe('Android environment', () => {
27
152
  {
28
153
  platform: 'linux',
29
154
  homeDirectory: '/home/tester',
30
- }
31
- )
155
+ },
156
+ ),
32
157
  ).toBe('/home/tester/Android/Sdk');
33
158
  });
34
159
 
@@ -42,8 +167,8 @@ describe('Android environment', () => {
42
167
  {
43
168
  platform: 'darwin',
44
169
  homeDirectory: '/Users/tester',
45
- }
46
- )
170
+ },
171
+ ),
47
172
  ).toBe('/env/android-home');
48
173
 
49
174
  expect(
@@ -54,8 +179,8 @@ describe('Android environment', () => {
54
179
  {
55
180
  platform: 'linux',
56
181
  homeDirectory: '/home/tester',
57
- }
58
- )
182
+ },
183
+ ),
59
184
  ).toBe('/env/android-sdk-root');
60
185
  });
61
186
 
@@ -63,10 +188,10 @@ describe('Android environment', () => {
63
188
  expect(getHostAndroidSystemImageArch('x64')).toBe('x86_64');
64
189
  expect(getHostAndroidSystemImageArch('arm64')).toBe('arm64-v8a');
65
190
  expect(getAndroidSystemImagePackage(35, 'x86_64')).toBe(
66
- 'system-images;android-35;default;x86_64'
191
+ 'system-images;android-35;default;x86_64',
67
192
  );
68
193
  expect(getAndroidSystemImagePackage(35, 'arm64-v8a')).toBe(
69
- 'system-images;android-35;default;arm64-v8a'
194
+ 'system-images;android-35;default;arm64-v8a',
70
195
  );
71
196
  });
72
197
 
@@ -76,7 +201,7 @@ describe('Android environment', () => {
76
201
  apiLevel: 34,
77
202
  includeEmulator: true,
78
203
  architecture: 'x86_64',
79
- })
204
+ }),
80
205
  ).toEqual([
81
206
  'platform-tools',
82
207
  'emulator',