Skip to content

Commit 1bf1a16

Browse files
committed
docs: update to match latest development
1 parent 2be7cea commit 1bf1a16

File tree

8 files changed

+173
-28
lines changed

8 files changed

+173
-28
lines changed

website/src/docs/api/plugins.mdx

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ A plugin can react to events such as:
88

99
- Harness startup and teardown
1010
- run start and finish
11+
- runtime ready and disconnect events
1112
- Metro initialization and bundle events
1213
- app lifecycle signals
1314
- collection, suite, and test execution events
1415

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+
1518
## Defining a Plugin
1619

1720
Use `definePlugin()` from `@react-native-harness/plugins` and register the plugin in your Harness config.
@@ -48,27 +51,41 @@ export const loggingPlugin = () =>
4851
Then register it in `rn-harness.config.mjs`:
4952

5053
```ts
54+
import {
55+
applePlatform,
56+
appleSimulator,
57+
} from '@react-native-harness/platform-apple';
5158
import { loggingPlugin } from './logging-plugin';
5259

5360
export default {
5461
entryPoint: './src/test.ts',
5562
appRegistryComponentName: 'App',
5663
runners: [
57-
{
64+
applePlatform({
5865
name: 'ios',
59-
runner: '@react-native-harness/platform-ios',
60-
platformId: 'ios',
61-
config: {},
62-
},
66+
device: appleSimulator('iPhone 16 Pro', '18.0'),
67+
bundleId: 'com.example.app',
68+
}),
6369
],
6470
plugins: [loggingPlugin()],
6571
};
6672
```
6773

74+
## Typical Uses
75+
76+
Plugins are a good fit when you want to:
77+
78+
- write custom logs for run start, finish, or failures
79+
- collect screenshots, crash artifacts, or extra diagnostics
80+
- send results to external reporting systems
81+
- trigger project-specific automation around test runs
82+
83+
Keep plugins focused on workflow needs that are specific to your app or team.
84+
6885
## Available Events
6986

7087
The full list of plugin events is defined in the source here:
7188

7289
- [packages/plugins/src/types.ts](https://github.com/callstackincubator/react-native-harness/blob/main/packages/plugins/src/types.ts)
7390

74-
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`.

website/src/docs/api/test-environment.mdx

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ When you run `react-native-harness`, the following process occurs for each test
1111
3. **Harness Initialization**: The native bridge is established.
1212
4. **`setupFiles`**: Global setup files are evaluated in the app environment.
1313
5. **Test Collection**: The test file is evaluated to build a structure of `describe` and `it` blocks.
14-
- **`setupFilesAfterEnv`**: These files are evaluated *during* this phase.
14+
- **`setupFilesAfterEnv`**: These files are evaluated _during_ this phase.
1515
6. **Execution**: Tests are run serially on the device.
1616
7. **Teardown**: Results are sent back to the CLI, and the environment is cleaned up.
1717

@@ -22,8 +22,10 @@ When you run `react-native-harness`, the following process occurs for each test
2222
Harness supports two types of setup files, configured in your `jest.harness.config.mjs`.
2323

2424
### `setupFiles`
25+
2526
Executed **before** the testing environment is initialized.
26-
- **Context**: Runs in the app's JavaScript environment, but *before* the Test Runner has initialized the test framework (Jest).
27+
28+
- **Context**: Runs in the app's JavaScript environment, but _before_ the Test Runner has initialized the test framework (Jest).
2729
- **Limitations**: `describe`, `it`, `expect`, and `beforeEach` are **not available**.
2830
- **Use Case**: Polyfilling global APIs that the environment or third-party libraries expect to exist immediately upon import.
2931

@@ -39,14 +41,21 @@ global.TextDecoder = TextDecoder;
3941
```
4042

4143
### `setupFilesAfterEnv`
44+
4245
Executed **after** the testing environment is initialized, but before the test file itself.
46+
4347
- **Context**: Runs immediately before the test file is executed. The test framework is fully loaded.
4448
- **Capabilities**: Full access to `describe`, `it`, `expect`, `beforeEach`, and Harness APIs like `mock`, `spyOn`, `clearAllMocks`, etc.
4549
- **Use Case**: Configuring global mocks, custom matchers, or global setup/teardown hooks.
4650

4751
```javascript
4852
// jest.setupAfterEnv.js
49-
import { beforeEach, afterEach, clearAllMocks, mock } from 'react-native-harness';
53+
import {
54+
beforeEach,
55+
afterEach,
56+
clearAllMocks,
57+
mock,
58+
} from 'react-native-harness';
5059

5160
// Global cleanup
5261
afterEach(() => {
@@ -64,11 +73,13 @@ mock('react-native-safe-area-context', () => ({
6473
## Isolation and Persistence
6574

6675
### Environment Reset
76+
6777
By default, Harness ensures test isolation by resetting the environment between test files.
6878

6979
- **`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.
7080

7181
### Native Module Mocking
82+
7283
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.
7384

7485
---
@@ -82,6 +93,23 @@ Harness includes a built-in **Native Crash Monitor**:
8293
- **`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.
8394
- **`crashDetectionInterval`**: (Default: `500ms`) How often the CLI polls the device to ensure the app is still alive.
8495

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+
export default {
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+
85113
---
86114

87115
## Forwarding Client Logs
@@ -92,10 +120,11 @@ To aid in debugging, you can forward all `console` output from the device to you
92120
export default {
93121
// ...
94122
forwardClientLogs: true,
95-
}
123+
};
96124
```
97125

98126
When enabled, logs from the device appear in your terminal with indicators:
99-
- ` LOG ` - `console.log`
100-
- ` WARN ` - `console.warn`
101-
- ` ERROR ` - `console.error`
127+
128+
- `LOG` - `console.log`
129+
- `WARN` - `console.warn`
130+
- `ERROR` - `console.error`

website/src/docs/getting-started/configuration.mdx

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,15 @@ For Expo projects, the `entryPoint` should be set to the path specified in the `
9191
| `entryPoint` | **Required.** Path to your React Native app's entry point file. |
9292
| `appRegistryComponentName` | **Required.** Name of the component registered with AppRegistry. |
9393
| `runners` | **Required.** Array of test runners (at least one required). |
94+
| `plugins` | Array of Harness plugins to run during the test lifecycle. |
9495
| `defaultRunner` | Default runner to use when none specified. |
9596
| `host` | Hostname or IP address to bind the Metro server to (default: Metro default). |
9697
| `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. |
9799
| `platformReadyTimeout` | Platform-ready timeout in milliseconds (default: `300000`). |
98100
| `bridgeTimeout` | Bridge timeout in milliseconds (default: `60000`). |
99101
| `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`). |
100103
| `resetEnvironmentBetweenTestFiles` | Reset environment between test files (default: `true`). |
101104
| `detectNativeCrashes` | Detect native app crashes during startup and test execution (default: `true`). |
102105
| `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 `
112115
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.
113116

114117
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.
115120
:::
116121

117122
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
216221
**Default:** 60000 (60 seconds)
217222
**Minimum:** 1000 (1 second)
218223

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.
244+
245+
```javascript
246+
import { definePlugin } from '@react-native-harness/plugins';
247+
248+
const loggingPlugin = definePlugin({
249+
name: 'logging-plugin',
250+
hooks: {
251+
run: {
252+
started: async (ctx) => {
253+
ctx.logger.info('Starting run', ctx.runId);
254+
},
255+
},
256+
},
257+
});
258+
259+
export default {
260+
// ...
261+
plugins: [loggingPlugin],
262+
};
263+
```
264+
265+
Use plugins for project-specific logging, artifact collection, reporting, or workflow automation. See the [Plugins](/docs/api/plugins) guide for more.
266+
219267
## Environment-Specific Configurations
220268

221269
You can create different configurations for different environments:
@@ -263,7 +311,9 @@ The coverage root option specifies the root directory for coverage instrumentati
263311

264312
```javascript
265313
{
266-
coverageRoot: '../', // Use parent directory as coverage root
314+
coverage: {
315+
root: '../',
316+
},
267317
}
268318
```
269319

@@ -275,8 +325,8 @@ This option is passed to babel-plugin-istanbul's `cwd` option and ensures that c
275325
- Libraries are structured with separate test and source directories
276326
- Projects have nested directory structures that don't align with the current working directory
277327

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.
279329

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.
282332
:::

website/src/docs/getting-started/quick-start.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Run the wizard from your project root:
3636
/>
3737

3838
The wizard will:
39+
3940
- Ask for your project type (Expo or React Native CLI)
4041
- Help you select platforms (Android, iOS, or Web)
4142
- Find available devices and simulators
@@ -196,6 +197,8 @@ Before running tests, you need to build your app in debug mode and install it on
196197

197198
Follow your framework's documentation to build and install the debug variant:
198199

200+
Harness uses your existing debug app build. It does not create release builds or replace your native app setup.
201+
199202
### React Native Community CLI
200203

201204
<PackageManagerTabs command="react-native run-android" />

website/src/docs/guides/ci-cd.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ The action accepts the following inputs:
4242
- `uploadVisualTestArtifacts` (optional): Whether to upload visual test diff and actual images as artifacts
4343
- `harnessArgs` (optional): Additional arguments to pass to the Harness CLI
4444
- `packageManager` (optional): Override package manager auto-detection. Supported values: `npm`, `yarn`, `pnpm`, `bun`, `deno`
45-
- `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`.
4646
- `preRunHook` (optional): Inline shell script run in `bash` immediately before Harness starts
4747
- `afterRunHook` (optional): Inline shell script run in `bash` immediately after Harness finishes and before artifacts are uploaded
4848

@@ -233,12 +233,28 @@ The official action can run optional shell hooks around the Harness invocation:
233233

234234
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.
235235

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+
236246
## Metro cache
237247

238248
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.
239249

240250
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`.
241251

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+
242258
## Build Artifact Caching
243259

244260
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.

website/src/docs/platforms/android.mdx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,39 @@ androidPlatform({
4343
feature_enabled: true,
4444
},
4545
},
46-
})
46+
});
4747
```
4848

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+
4969
#### Finding Emulator Names
70+
5071
You can list all available AVDs on your system using the `emulator` command:
5172

5273
```bash
5374
emulator -list-avds
5475
```
76+
5577
Output example:
78+
5679
```
5780
Pixel_6_API_33
5881
Pixel_8_API_35
@@ -72,7 +95,7 @@ androidPlatform({
7295
launch_mode: 'test',
7396
},
7497
},
75-
})
98+
});
7699
```
77100

78101
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
82105
- **ADB**: The Android Debug Bridge (`adb`) must be installed and in your system PATH.
83106
- **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.
84107

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+
85112
## App Launch Options
86113

87114
Android runners support `appLaunchOptions.extras`, which are passed as primitive extras to `adb shell am start`.

website/src/docs/platforms/ios.mdx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ Physical iOS devices always connect to the default Metro port (`8081`). Custom `
8282

8383
- **Xcode**: Xcode must be installed on your system.
8484
- **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.
8685
- **Development Build**: A debug build of your app must be installed on the simulator or device.
8786

8887
## App Launch Options
@@ -98,7 +97,7 @@ Harness maps them differently depending on the target:
9897

9998
Harness uses separate crash-monitoring implementations by target:
10099

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.
103102

104103
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

Comments
 (0)