@react-native-harness/platform-android 1.4.0-rc.1 → 1.4.1

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 (78) hide show
  1. package/dist/adb.d.ts +3 -1
  2. package/dist/adb.d.ts.map +1 -1
  3. package/dist/adb.js +30 -21
  4. package/dist/app-session.d.ts +11 -2
  5. package/dist/app-session.d.ts.map +1 -1
  6. package/dist/app-session.js +17 -12
  7. package/dist/avd-config.d.ts +1 -0
  8. package/dist/avd-config.d.ts.map +1 -1
  9. package/dist/avd-config.js +11 -0
  10. package/dist/emulator-startup.d.ts +23 -0
  11. package/dist/emulator-startup.d.ts.map +1 -1
  12. package/dist/emulator-startup.js +58 -0
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -0
  16. package/dist/instance.d.ts.map +1 -1
  17. package/dist/instance.js +21 -15
  18. package/dist/runner.d.ts +2 -2
  19. package/dist/runner.d.ts.map +1 -1
  20. package/package.json +4 -4
  21. package/src/adb.ts +72 -65
  22. package/src/app-session.ts +28 -12
  23. package/src/avd-config.ts +17 -0
  24. package/src/emulator-startup.ts +74 -0
  25. package/src/index.ts +1 -0
  26. package/src/instance.ts +30 -16
  27. package/src/runner.ts +5 -9
  28. package/dist/__tests__/adb-id.test.d.ts +0 -2
  29. package/dist/__tests__/adb-id.test.d.ts.map +0 -1
  30. package/dist/__tests__/adb-id.test.js +0 -41
  31. package/dist/__tests__/adb.test.d.ts +0 -2
  32. package/dist/__tests__/adb.test.d.ts.map +0 -1
  33. package/dist/__tests__/adb.test.js +0 -552
  34. package/dist/__tests__/app-monitor.test.d.ts +0 -2
  35. package/dist/__tests__/app-monitor.test.d.ts.map +0 -1
  36. package/dist/__tests__/app-monitor.test.js +0 -257
  37. package/dist/__tests__/avd-config.test.d.ts +0 -2
  38. package/dist/__tests__/avd-config.test.d.ts.map +0 -1
  39. package/dist/__tests__/avd-config.test.js +0 -174
  40. package/dist/__tests__/ci-action.test.d.ts +0 -2
  41. package/dist/__tests__/ci-action.test.d.ts.map +0 -1
  42. package/dist/__tests__/ci-action.test.js +0 -46
  43. package/dist/__tests__/crash-diagnostics.test.d.ts +0 -2
  44. package/dist/__tests__/crash-diagnostics.test.d.ts.map +0 -1
  45. package/dist/__tests__/crash-diagnostics.test.js +0 -119
  46. package/dist/__tests__/crash-parser.test.d.ts +0 -2
  47. package/dist/__tests__/crash-parser.test.d.ts.map +0 -1
  48. package/dist/__tests__/crash-parser.test.js +0 -45
  49. package/dist/__tests__/crash-reporter.test.d.ts +0 -2
  50. package/dist/__tests__/crash-reporter.test.d.ts.map +0 -1
  51. package/dist/__tests__/crash-reporter.test.js +0 -150
  52. package/dist/__tests__/emulator-startup.test.d.ts +0 -2
  53. package/dist/__tests__/emulator-startup.test.d.ts.map +0 -1
  54. package/dist/__tests__/emulator-startup.test.js +0 -20
  55. package/dist/__tests__/environment.test.d.ts +0 -2
  56. package/dist/__tests__/environment.test.d.ts.map +0 -1
  57. package/dist/__tests__/environment.test.js +0 -117
  58. package/dist/__tests__/instance.test.d.ts +0 -2
  59. package/dist/__tests__/instance.test.d.ts.map +0 -1
  60. package/dist/__tests__/instance.test.js +0 -593
  61. package/dist/__tests__/shared-prefs.test.d.ts +0 -2
  62. package/dist/__tests__/shared-prefs.test.d.ts.map +0 -1
  63. package/dist/__tests__/shared-prefs.test.js +0 -87
  64. package/dist/__tests__/targets.test.d.ts +0 -2
  65. package/dist/__tests__/targets.test.d.ts.map +0 -1
  66. package/dist/__tests__/targets.test.js +0 -49
  67. package/dist/tsconfig.lib.tsbuildinfo +0 -1
  68. package/src/__tests__/adb-id.test.ts +0 -51
  69. package/src/__tests__/avd-config.test.ts +0 -206
  70. package/src/__tests__/ci-action.test.ts +0 -81
  71. package/src/__tests__/crash-diagnostics.test.ts +0 -144
  72. package/src/__tests__/crash-parser.test.ts +0 -52
  73. package/src/__tests__/crash-reporter.test.ts +0 -167
  74. package/src/__tests__/emulator-startup.test.ts +0 -35
  75. package/src/__tests__/instance.test.ts +0 -845
  76. package/src/__tests__/shared-prefs.test.ts +0 -144
  77. package/src/__tests__/targets.test.ts +0 -53
  78. package/tsconfig.tsbuildinfo +0 -1
@@ -1,150 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { createAndroidCrashReporter } from '../crash-reporter.js';
3
- const javaCrashDropbox = `
4
- ========================================
5
- 2026-03-12 10:30:45.123 data_app_crash (text, 500 bytes)
6
- Process: com.harnessplayground
7
- PID: 7777
8
- Package: com.harnessplayground v1 (1.0)
9
- java.lang.RuntimeException: boom
10
- \tat com.harnessplayground.MainActivity.onCreate(MainActivity.kt:38)
11
- `;
12
- const nativeCrashDropbox = `
13
- ========================================
14
- 2026-03-12 10:31:10.456 data_app_native_crash (text, 800 bytes)
15
- Process: com.harnessplayground
16
- PID: 8888
17
- signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbeef
18
- Abort message: 'JNI DETECTED ERROR IN APPLICATION'
19
- backtrace:
20
- #00 pc 00001234 /data/app/lib/libapp.so
21
- `;
22
- describe('createAndroidCrashReporter', () => {
23
- afterEach(() => {
24
- vi.useRealTimers();
25
- });
26
- it('persists the current logcat crash block with the test file path', async () => {
27
- vi.useFakeTimers();
28
- const persistArtifact = vi.fn(() => '/tmp/.harness/crash-reports/logcat.txt');
29
- const reporter = createAndroidCrashReporter({
30
- bundleId: 'com.harnessplayground',
31
- crashArtifactWriter: {
32
- runTimestamp: '2026-03-12T11-35-08-000Z',
33
- persistArtifact,
34
- },
35
- getLogs: () => [
36
- { line: 'ordinary crash-buffer line', occurredAt: 1_000 },
37
- { line: '--------- beginning of crash', occurredAt: 1_100 },
38
- {
39
- line: 'Process: com.harnessplayground, PID: 7777',
40
- occurredAt: 1_100,
41
- },
42
- { line: 'FATAL EXCEPTION: main', occurredAt: 1_100 },
43
- ],
44
- });
45
- const detailsPromise = reporter.getCrashDetails({
46
- occurredAt: 1_100,
47
- pid: 7777,
48
- testFilePath: '/test/native-crash.test.ts',
49
- });
50
- await vi.advanceTimersByTimeAsync(100);
51
- const details = await detailsPromise;
52
- expect(details).toMatchObject({
53
- artifactType: 'logcat',
54
- artifactPath: '/tmp/.harness/crash-reports/logcat.txt',
55
- pid: 7777,
56
- processName: 'com.harnessplayground',
57
- });
58
- expect(persistArtifact).toHaveBeenCalledWith({
59
- artifactKind: 'logcat',
60
- testFilePath: '/test/native-crash.test.ts',
61
- source: {
62
- kind: 'text',
63
- fileName: 'logcat.txt',
64
- text: [
65
- '--------- beginning of crash',
66
- 'Process: com.harnessplayground, PID: 7777',
67
- 'FATAL EXCEPTION: main',
68
- '',
69
- ].join('\n'),
70
- },
71
- });
72
- });
73
- it('adds dropbox artifacts as enrichment when logcat evidence is available', async () => {
74
- vi.useFakeTimers();
75
- const persistArtifact = vi
76
- .fn()
77
- .mockImplementation(({ artifactKind }) => {
78
- return `/tmp/.harness/crash-reports/${artifactKind}.txt`;
79
- });
80
- const reporter = createAndroidCrashReporter({
81
- bundleId: 'com.harnessplayground',
82
- crashArtifactWriter: {
83
- runTimestamp: '2026-03-12T11-35-08-000Z',
84
- persistArtifact,
85
- },
86
- getLogs: () => [
87
- { line: '--------- beginning of crash', occurredAt: 1_100 },
88
- {
89
- line: 'Process: com.harnessplayground, PID: 7777',
90
- occurredAt: 1_100,
91
- },
92
- { line: 'FATAL EXCEPTION: main', occurredAt: 1_100 },
93
- ],
94
- getDropboxOutput: async () => javaCrashDropbox,
95
- getExitInfo: async () => 'ApplicationExitInfo #0:\n package=com.harnessplayground pid=7777 reason=4 (APP CRASH(NATIVE))',
96
- });
97
- const detailsPromise = reporter.getCrashDetails({
98
- occurredAt: 1_100,
99
- pid: 7777,
100
- testFilePath: '/test/native-crash.test.ts',
101
- });
102
- await vi.advanceTimersByTimeAsync(100);
103
- const details = await detailsPromise;
104
- expect(details).toMatchObject({
105
- artifactType: 'logcat',
106
- artifactPath: '/tmp/.harness/crash-reports/logcat.txt',
107
- });
108
- expect(details?.enrichmentArtifacts).toEqual(expect.arrayContaining([
109
- {
110
- artifactType: 'dropbox-crash',
111
- artifactPath: '/tmp/.harness/crash-reports/dropbox-crash.txt',
112
- },
113
- {
114
- artifactType: 'exit-info',
115
- artifactPath: '/tmp/.harness/crash-reports/exit-info.txt',
116
- },
117
- ]));
118
- });
119
- it('falls back to native dropbox evidence when logcat is empty', async () => {
120
- vi.useFakeTimers();
121
- const persistArtifact = vi
122
- .fn()
123
- .mockImplementation(({ artifactKind }) => {
124
- return `/tmp/.harness/crash-reports/${artifactKind}.txt`;
125
- });
126
- const reporter = createAndroidCrashReporter({
127
- bundleId: 'com.harnessplayground',
128
- crashArtifactWriter: {
129
- runTimestamp: '2026-03-12T11-35-08-000Z',
130
- persistArtifact,
131
- },
132
- getLogs: () => [],
133
- getDropboxOutput: async () => nativeCrashDropbox,
134
- });
135
- const detailsPromise = reporter.getCrashDetails({
136
- occurredAt: 1_100,
137
- pid: 8888,
138
- testFilePath: '/test/native-crash.test.ts',
139
- });
140
- await vi.advanceTimersByTimeAsync(100);
141
- const details = await detailsPromise;
142
- expect(details).toMatchObject({
143
- artifactType: 'dropbox-native-crash',
144
- artifactPath: '/tmp/.harness/crash-reports/dropbox-native-crash.txt',
145
- pid: 8888,
146
- signal: 'SIGSEGV',
147
- processName: 'com.harnessplayground',
148
- });
149
- });
150
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=emulator-startup.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"emulator-startup.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/emulator-startup.test.ts"],"names":[],"mappings":""}
@@ -1,20 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { getEmulatorStartupArgs } from '../emulator-startup.js';
3
- describe('emulator startup modes', () => {
4
- it('builds default boot args', () => {
5
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'default-boot')).toEqual(expect.arrayContaining([
6
- '@Pixel_8_API_35',
7
- '-no-snapshot-load',
8
- '-no-snapshot-save',
9
- ]));
10
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'default-boot')).not.toEqual(expect.arrayContaining(['-camera-back', 'none']));
11
- });
12
- it('builds clean snapshot generation args', () => {
13
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'clean-snapshot-generation')).toEqual(expect.arrayContaining(['@Pixel_8_API_35', '-no-snapshot-load']));
14
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'clean-snapshot-generation')).not.toContain('-no-snapshot-save');
15
- });
16
- it('builds snapshot reuse args', () => {
17
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'snapshot-reuse')).toEqual(expect.arrayContaining(['@Pixel_8_API_35', '-no-snapshot-save']));
18
- expect(getEmulatorStartupArgs('Pixel_8_API_35', 'snapshot-reuse')).not.toContain('-no-snapshot-load');
19
- });
20
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=environment.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"environment.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/environment.test.ts"],"names":[],"mappings":""}
@@ -1,117 +0,0 @@
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';
5
- import { ensureAndroidAdbAvailable, ensureAndroidEmulatorAvailable, getAndroidSdkRoot, getAndroidSystemImagePackage, getDefaultUnixAndroidSdkRoot, getHostAndroidSystemImageArch, getRequiredAndroidSdkPackages, } from '../environment.js';
6
- import * as tools from '@react-native-harness/tools';
7
- describe('Android environment', () => {
8
- beforeEach(() => {
9
- vi.restoreAllMocks();
10
- vi.unstubAllEnvs();
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
- });
74
- it('uses the default Unix SDK root when env vars are missing', () => {
75
- expect(getDefaultUnixAndroidSdkRoot({
76
- platform: 'darwin',
77
- homeDirectory: '/Users/tester',
78
- })).toBe('/Users/tester/Library/Android/sdk');
79
- expect(getAndroidSdkRoot({}, {
80
- platform: 'linux',
81
- homeDirectory: '/home/tester',
82
- })).toBe('/home/tester/Android/Sdk');
83
- });
84
- it('prefers ANDROID_HOME and ANDROID_SDK_ROOT over default paths', () => {
85
- expect(getAndroidSdkRoot({
86
- ANDROID_HOME: '/env/android-home',
87
- ANDROID_SDK_ROOT: '/env/android-sdk-root',
88
- }, {
89
- platform: 'darwin',
90
- homeDirectory: '/Users/tester',
91
- })).toBe('/env/android-home');
92
- expect(getAndroidSdkRoot({
93
- ANDROID_SDK_ROOT: '/env/android-sdk-root',
94
- }, {
95
- platform: 'linux',
96
- homeDirectory: '/home/tester',
97
- })).toBe('/env/android-sdk-root');
98
- });
99
- it('selects Android packages using the host architecture', () => {
100
- expect(getHostAndroidSystemImageArch('x64')).toBe('x86_64');
101
- expect(getHostAndroidSystemImageArch('arm64')).toBe('arm64-v8a');
102
- expect(getAndroidSystemImagePackage(35, 'x86_64')).toBe('system-images;android-35;default;x86_64');
103
- expect(getAndroidSystemImagePackage(35, 'arm64-v8a')).toBe('system-images;android-35;default;arm64-v8a');
104
- });
105
- it('derives emulator package requirements from runner config fields', () => {
106
- expect(getRequiredAndroidSdkPackages({
107
- apiLevel: 34,
108
- includeEmulator: true,
109
- architecture: 'x86_64',
110
- })).toEqual([
111
- 'platform-tools',
112
- 'emulator',
113
- 'platforms;android-34',
114
- 'system-images;android-34;default;x86_64',
115
- ]);
116
- });
117
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=instance.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/instance.test.ts"],"names":[],"mappings":""}