You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: website/src/docs/api/plugins.mdx
+23-6Lines changed: 23 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,10 +8,13 @@ A plugin can react to events such as:
8
8
9
9
- Harness startup and teardown
10
10
- run start and finish
11
+
- runtime ready and disconnect events
11
12
- Metro initialization and bundle events
12
13
- app lifecycle signals
13
14
- collection, suite, and test execution events
14
15
16
+
Each plugin receives a context with useful runtime information such as a logger, project root, current runner, current config, and hook-specific data like the run ID or test file path.
17
+
15
18
## Defining a Plugin
16
19
17
20
Use `definePlugin()` from `@react-native-harness/plugins` and register the plugin in your Harness config.
The public plugin shape is based on nested objects like `run.started`, `metro.bundleFinished`, or `harness.beforeDispose`.
91
+
The public plugin shape is based on nested objects like `run.started`, `runtime.ready`, `metro.bundleFinished`, `app.exited`, or `harness.beforeDispose`.
By default, Harness ensures test isolation by resetting the environment between test files.
68
78
69
79
-**`resetEnvironmentBetweenTestFiles`**: (Default: `true`) When enabled, the app is fully restarted between different test files. This prevents state leakage (like singleton native modules or global variables) from affecting subsequent tests.
70
80
71
81
### Native Module Mocking
82
+
72
83
Mocks created via `mock()` are tied to the module cache. Use `resetModules()` in an `afterEach` hook to ensure mocks don't leak between individual tests within the same file.
73
84
74
85
---
@@ -82,6 +93,23 @@ Harness includes a built-in **Native Crash Monitor**:
82
93
-**`detectNativeCrashes`**: (Default: `true`) When enabled, Harness actively monitors the native process during both startup and test execution. If the app crashes, Harness reports a `NativeCrashError` for the current test file, restarts the app, and continues with the remaining test files.
83
94
-**`crashDetectionInterval`**: (Default: `500ms`) How often the CLI polls the device to ensure the app is still alive.
84
95
96
+
## Startup Failures and Retries
97
+
98
+
Harness treats app startup as part of the test run.
99
+
100
+
- If the app crashes while launching, Harness reports the startup failure instead of waiting for a generic timeout.
101
+
- If the app becomes unresponsive during launch, Harness fails the startup attempt with a startup-stall error.
102
+
- Harness can retry startup automatically before giving up. Control this with `maxAppRestarts` in `rn-harness.config.mjs`.
103
+
104
+
```javascript title="rn-harness.config.mjs"
105
+
exportdefault {
106
+
// ...
107
+
maxAppRestarts:2,
108
+
};
109
+
```
110
+
111
+
This is most useful in CI, where cold boots and slower launch times can make the first startup attempt less reliable.
112
+
85
113
---
86
114
87
115
## Forwarding Client Logs
@@ -92,10 +120,11 @@ To aid in debugging, you can forward all `console` output from the device to you
92
120
exportdefault {
93
121
// ...
94
122
forwardClientLogs:true,
95
-
}
123
+
};
96
124
```
97
125
98
126
When enabled, logs from the device appear in your terminal with indicators:
Copy file name to clipboardExpand all lines: website/src/docs/getting-started/configuration.mdx
+54-4Lines changed: 54 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -91,12 +91,15 @@ For Expo projects, the `entryPoint` should be set to the path specified in the `
91
91
|`entryPoint`|**Required.** Path to your React Native app's entry point file. |
92
92
|`appRegistryComponentName`|**Required.** Name of the component registered with AppRegistry. |
93
93
|`runners`|**Required.** Array of test runners (at least one required). |
94
+
|`plugins`| Array of Harness plugins to run during the test lifecycle. |
94
95
|`defaultRunner`| Default runner to use when none specified. |
95
96
|`host`| Hostname or IP address to bind the Metro server to (default: Metro default). |
96
97
|`metroPort`| Preferred port used by Metro and Harness bridge traffic (default: `8081`). Harness falls back to the next available port when this one is already in use. |
98
+
|`webSocketPort`| Deprecated. Bridge traffic now uses `metroPort`; this option is ignored. |
97
99
|`platformReadyTimeout`| Platform-ready timeout in milliseconds (default: `300000`). |
98
100
|`bridgeTimeout`| Bridge timeout in milliseconds (default: `60000`). |
99
101
|`bundleStartTimeout`| Bundle start timeout in milliseconds (default: `60000`). |
102
+
|`maxAppRestarts`| Maximum number of automatic app relaunch attempts while Harness is waiting for startup (default: `2`). |
100
103
|`resetEnvironmentBetweenTestFiles`| Reset environment between test files (default: `true`). |
101
104
|`detectNativeCrashes`| Detect native app crashes during startup and test execution (default: `true`). |
102
105
|`crashDetectionInterval`| Interval in milliseconds to check for native crashes (default: `500`). |
@@ -112,6 +115,8 @@ For Expo projects, the `entryPoint` should be set to the path specified in the `
112
115
Harness treats `metroPort` as the preferred starting port. If that port is already in use, Harness tries the next available ports automatically and logs the port it selected for the run.
113
116
114
117
Physical iOS devices are the exception: they always use the default Metro port and do not support custom or fallback ports.
118
+
119
+
When multiple Harness runs target the same device, simulator, emulator, or browser configuration, Harness waits for the existing run to finish before starting the next one.
115
120
:::
116
121
117
122
A test runner defines how tests are executed on a specific platform. React Native Harness uses platform-specific packages to create runners with type-safe configurations.
@@ -216,6 +221,49 @@ The bundle start timeout controls how long React Native Harness waits for the la
216
221
**Default:** 60000 (60 seconds)
217
222
**Minimum:** 1000 (1 second)
218
223
224
+
## Startup Recovery
225
+
226
+
Harness can retry app startup automatically when the app fails to come up cleanly during launch.
227
+
228
+
```javascript
229
+
{
230
+
maxAppRestarts:2,
231
+
}
232
+
```
233
+
234
+
**Default:** 2
235
+
**Minimum:** 0
236
+
237
+
Increase this value if your app occasionally needs another launch attempt before it reaches a ready state, especially in slower CI environments.
238
+
239
+
Set it to `0` if you want startup failures to fail immediately without any automatic retry.
240
+
241
+
## Plugins
242
+
243
+
You can register Harness plugins with the `plugins` option.
Use plugins for project-specific logging, artifact collection, reporting, or workflow automation. See the [Plugins](/docs/api/plugins) guide for more.
266
+
219
267
## Environment-Specific Configurations
220
268
221
269
You can create different configurations for different environments:
@@ -263,7 +311,9 @@ The coverage root option specifies the root directory for coverage instrumentati
263
311
264
312
```javascript
265
313
{
266
-
coverageRoot:'../', // Use parent directory as coverage root
314
+
coverage: {
315
+
root:'../',
316
+
},
267
317
}
268
318
```
269
319
@@ -275,8 +325,8 @@ This option is passed to babel-plugin-istanbul's `cwd` option and ensures that c
275
325
- Libraries are structured with separate test and source directories
276
326
- Projects have nested directory structures that don't align with the current working directory
277
327
278
-
Without specifying `coverageRoot`, babel-plugin-istanbul may skip instrumenting files outside the current working directory, resulting in incomplete coverage reports.
328
+
Without specifying `coverage.root`, babel-plugin-istanbul may skip instrumenting files outside the current working directory, resulting in incomplete coverage reports.
279
329
280
-
:::tip When to use coverageRoot
281
-
Set `coverageRoot` when you notice 0% coverage in your reports or when source files are not being instrumented for coverage. This commonly occurs in create-react-native-library projects and other monorepo setups.
330
+
:::tip When to use coverage.root
331
+
Set `coverage.root` when you notice 0% coverage in your reports or when source files are not being instrumented for coverage. This commonly occurs in create-react-native-library projects and other monorepo setups.
-`cacheAvd` (optional, Android only): Whether to cache the Android Virtual Device snapshot. Defaults to `true`
45
+
-`cacheAvd` (optional, Android only): Whether to cache the Android Virtual Device snapshot. Defaults to `true`. This is most useful when your Android runner defines AVD details in `rn-harness.config.mjs`.
46
46
-`preRunHook` (optional): Inline shell script run in `bash` immediately before Harness starts
47
47
-`afterRunHook` (optional): Inline shell script run in `bash` immediately after Harness finishes and before artifacts are uploaded
48
48
@@ -233,12 +233,28 @@ The official action can run optional shell hooks around the Harness invocation:
233
233
234
234
On Android, both hooks execute inside the `android-emulator-runner` session, so they can safely use `adb` against the active emulator. On iOS, the hooks run after the simulator is booted and the app is installed. On web, the same inputs are available for consistency and run immediately before and after the Harness command.
235
235
236
+
## Android Emulator Caching
237
+
238
+
For Android emulator runners, the official action can cache the emulator snapshot between runs.
239
+
240
+
- Enable this with `cacheAvd: true`.
241
+
- For best results, define the emulator's AVD details in your Android runner config.
242
+
- Use this when you want faster CI runs and a more consistent emulator setup.
243
+
244
+
If your workflow does not define AVD details, the action can still run the tests, but emulator snapshot caching is less useful.
245
+
236
246
## Metro cache
237
247
238
248
React Native Harness can persist Metro's transformation cache under `.harness/metro-cache` in your project root. Enabling it in config (`unstable__enableMetroCache: true`) speeds up repeated Metro runs.
239
249
240
250
When you use the `callstackincubator/react-native-harness` GitHub Action, Metro cache restoration and saving is handled automatically for the resolved `projectRoot`. You do not need to add a separate `actions/cache` step for `.harness/metro-cache`.
241
251
252
+
## Web in CI
253
+
254
+
The official action supports web runners as well. At the moment, the action installs Playwright Chromium automatically before running Harness.
255
+
256
+
If your workflow depends on a different browser setup, make that expectation explicit in your CI configuration.
257
+
242
258
## Build Artifact Caching
243
259
244
260
The workflow includes build artifact caching to significantly reduce CI execution times. When native modules haven't changed, you can reuse the same debug builds instead of rebuilding from scratch.
Copy file name to clipboardExpand all lines: website/src/docs/platforms/android.mdx
+29-2Lines changed: 29 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,16 +43,39 @@ androidPlatform({
43
43
feature_enabled:true,
44
44
},
45
45
},
46
-
})
46
+
});
47
47
```
48
48
49
+
If you want Harness and the official GitHub Action to create and cache a matching emulator setup reliably in CI, you can also provide AVD details:
50
+
51
+
```javascript
52
+
androidPlatform({
53
+
name:'android',
54
+
device:androidEmulator('Pixel_8_API_35', {
55
+
apiLevel:35,
56
+
profile:'pixel_8',
57
+
diskSize:'6G',
58
+
heapSize:'1G',
59
+
snapshot: {
60
+
enabled:true,
61
+
},
62
+
}),
63
+
bundleId:'com.yourapp.debug',
64
+
});
65
+
```
66
+
67
+
Use the extra AVD configuration when you want more reproducible emulator setup in CI or when you plan to enable AVD snapshot caching in the official GitHub Action.
68
+
49
69
#### Finding Emulator Names
70
+
50
71
You can list all available AVDs on your system using the `emulator` command:
51
72
52
73
```bash
53
74
emulator -list-avds
54
75
```
76
+
55
77
Output example:
78
+
56
79
```
57
80
Pixel_6_API_33
58
81
Pixel_8_API_35
@@ -72,7 +95,7 @@ androidPlatform({
72
95
launch_mode:'test',
73
96
},
74
97
},
75
-
})
98
+
});
76
99
```
77
100
78
101
The first argument is the manufacturer, and the second is the model name. These are used for reporting and logging purposes. Harness will automatically detect the connected device via ADB.
@@ -82,6 +105,10 @@ The first argument is the manufacturer, and the second is the model name. These
82
105
-**ADB**: The Android Debug Bridge (`adb`) must be installed and in your system PATH.
83
106
-**Development Build**: You must have a debug build of your app installed on the device/emulator (`adb install ...`). Harness does not build your app; it injects the test bundle into the existing installed app.
84
107
108
+
## CI Notes
109
+
110
+
If you use the official GitHub Action with an Android emulator runner, `cacheAvd` works best when your runner includes the emulator's AVD configuration. This helps the action reuse the correct emulator snapshot between runs.
111
+
85
112
## App Launch Options
86
113
87
114
Android runners support `appLaunchOptions.extras`, which are passed as primitive extras to `adb shell am start`.
Copy file name to clipboardExpand all lines: website/src/docs/platforms/ios.mdx
+2-3Lines changed: 2 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -82,7 +82,6 @@ Physical iOS devices always connect to the default Metro port (`8081`). Custom `
82
82
83
83
-**Xcode**: Xcode must be installed on your system.
84
84
-**xcrun**: Harness uses `xcrun simctl` for simulators and `xcrun devicectl` for physical devices.
85
-
-**libimobiledevice**: `idevicesyslog`, `idevicecrashreport`, and `idevice_id` must be installed and available in `PATH` for physical-device crash diagnostics.
86
85
-**Development Build**: A debug build of your app must be installed on the simulator or device.
87
86
88
87
## App Launch Options
@@ -98,7 +97,7 @@ Harness maps them differently depending on the target:
98
97
99
98
Harness uses separate crash-monitoring implementations by target:
100
99
101
-
- iOS simulators use `simctl` for live log streaming and also scan local crash reports in `~/Library/Logs/DiagnosticReports`. When Harness finds a matching simulator `.ips` report, it attaches the parsed crash metadata and the crashing thread stack trace.
102
-
- iOS physical devices use `libimobiledevice` to stream logs and pull `.crash` reports from the device.
100
+
- iOS simulators can report startup and runtime crashes with matching crash details when those reports are available on your machine.
101
+
- iOS physical devices can report native crash details as part of the failure output when the connected device provides matching diagnostics.
103
102
104
103
Native crash details are attached to startup and execution failures when Harness can match the failing process from these sources. When the report contains it, Harness prints the extracted crashing-thread stack trace in the failure output.
0 commit comments