Skip to content

Commit f58df9e

Browse files
authored
feat: prompt users to migrate (#19)
This pull request adds a migration guide to help users transition from the old CLI to the new Jest-based workflow. If an unsupported configuration property, include, is detected, the user will be prompted to migrate.
1 parent da4de69 commit f58df9e

File tree

5 files changed

+227
-53
lines changed

5 files changed

+227
-53
lines changed

packages/cli/src/index.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
import { run, yargsOptions } from 'jest-cli';
2+
import { getConfig } from '@react-native-harness/config';
3+
4+
const checkForOldConfig = async () => {
5+
try {
6+
const { config } = await getConfig(process.cwd());
7+
8+
if (config.include) {
9+
console.error('\n❌ Migration Required\n');
10+
console.error('React Native Harness has migrated to the Jest CLI.');
11+
console.error(
12+
'The "include" property in your rn-harness.config file is no longer supported.\n'
13+
);
14+
console.error(
15+
'Please follow the migration guide to update your configuration:'
16+
);
17+
console.error(
18+
'https://react-native-harness.dev/docs/guides/migration-guide\n'
19+
);
20+
process.exit(1);
21+
}
22+
} catch {
23+
// Swallow the error - if we can't load the config, let Jest CLI handle it
24+
}
25+
};
226

327
const patchYargsOptions = () => {
428
yargsOptions.harnessRunner = {
@@ -44,4 +68,4 @@ const patchYargsOptions = () => {
4468
};
4569

4670
patchYargsOptions();
47-
run();
71+
checkForOldConfig().then(() => run());

packages/config/src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ export const ConfigSchema = z
6969

7070
resetEnvironmentBetweenTestFiles: z.boolean().optional().default(true),
7171
unstable__skipAlreadyIncludedModules: z.boolean().optional().default(false),
72+
73+
// Deprecated property - used for migration detection
74+
include: z.array(z.string()).optional(),
7275
})
7376
.refine(
7477
(config) => {

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

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ AppRegistry.registerComponent('MyApp', () => App);
8080
// Optional: Default runner to use when none specified
8181
defaultRunner?: string;
8282

83-
// Optional: Custom reporter for test results
84-
reporter?: Reporter;
85-
8683
// Optional: Bridge timeout in milliseconds (default: 60000)
8784
bridgeTimeout?: number;
8885

@@ -186,54 +183,6 @@ Increase this value if you experience timeout errors, especially on:
186183
- Slower devices or simulators
187184
- Complex test suites with heavy setup
188185

189-
## Custom Reporters
190-
191-
React Native Harness supports custom reporters to format and output test results. By default, it uses a console-based reporter, but you can customize this behavior.
192-
193-
### Built-in Reporters
194-
195-
**Default Reporter:**
196-
197-
```javascript
198-
import { defaultReporter } from '@react-native-harness/reporters';
199-
200-
export default {
201-
reporter: defaultReporter,
202-
};
203-
```
204-
205-
**JUnit Reporter:**
206-
207-
```javascript
208-
import { junitReporter } from '@react-native-harness/reporters';
209-
210-
export default {
211-
reporter: junitReporter, // Outputs junit.xml file
212-
};
213-
```
214-
215-
### Custom Reporter
216-
217-
You can create a custom reporter by implementing the `Reporter` interface:
218-
219-
```javascript
220-
const customReporter = {
221-
report: async (results) => {
222-
// Process test results
223-
for (const suite of results) {
224-
console.log(`Suite: ${suite.name}`);
225-
for (const test of suite.tests) {
226-
console.log(` ${test.name}: ${test.status}`);
227-
}
228-
}
229-
},
230-
};
231-
232-
export default {
233-
reporter: customReporter,
234-
};
235-
```
236-
237186
## Environment-Specific Configurations
238187

239188
You can create different configurations for different environments:
@@ -266,7 +215,6 @@ const config = {
266215
],
267216

268217
bridgeTimeout: isCI ? 180000 : 60000, // Longer timeout in CI
269-
reporter: isCI ? junitReporter : defaultReporter,
270218
};
271219

272220
export default config;

website/src/docs/guides/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This section contains comprehensive guides for advanced React Native Harness usa
44

55
## Available Guides
66

7+
- [**Migration Guide**](./migration-guide.md) - Learn how to migrate from the old CLI-based workflow to the new Jest-based workflow
78
- [**CI/CD Integration**](./ci-cd.md) - Learn how to run React Native Harness tests in GitHub Actions and other CI/CD environments
89

910
## Contributing
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Migration Guide
2+
3+
This guide helps you migrate from the old CLI-based workflow to the new Jest-based workflow in React Native Harness. The new workflow provides better integration with Jest's testing ecosystem and simplifies the testing setup.
4+
5+
## Overview of Changes
6+
7+
The new Jest-based workflow introduces several key changes:
8+
9+
- **Jest Integration**: React Native Harness now uses Jest as the test runner, giving you access to Jest's full testing capabilities
10+
- **Simplified Configuration**: Less configuration required in your app code
11+
- **Better Test Selection**: Use Jest's powerful test matching patterns instead of a custom `include` property
12+
- **Standardized Setup**: Follows Jest conventions for test configuration
13+
14+
## Migration Steps
15+
16+
### 1. Remove Babel Preset
17+
18+
The `react-native-harness/babel-preset` is **no longer needed** in the new workflow. Remove it from your project:
19+
20+
**Remove from babel.config.js:**
21+
22+
```javascript title="babel.config.js"
23+
module.exports = {
24+
presets: [
25+
-'react-native-harness/babel-preset',
26+
// your other presets
27+
],
28+
};
29+
```
30+
31+
### 2. Remove RN_HARNESS Condition
32+
33+
Previously, you needed to conditionally wrap your app with test setup code using the `RN_HARNESS` global variable. This is **no longer required**.
34+
35+
**Before:**
36+
37+
```javascript title="index.js"
38+
import { AppRegistry } from 'react-native';
39+
import App from './App';
40+
41+
// Old approach with RN_HARNESS condition
42+
AppRegistry.registerComponent('MyApp', () =>
43+
global.RN_HARNESS
44+
? require('react-native-harness').ReactNativeHarness
45+
: require('./App').default
46+
);
47+
```
48+
49+
**After:**
50+
51+
```javascript title="index.js"
52+
import { AppRegistry } from 'react-native';
53+
import App from './App';
54+
55+
// New approach - just register your app normally
56+
AppRegistry.registerComponent('MyApp', () => App);
57+
```
58+
59+
React Native Harness now handles the test setup internally, so you can write your entry point as if Harness doesn't exist. This makes your code cleaner and easier to maintain.
60+
61+
### 3. Update Configuration File
62+
63+
Update your `rn-harness.config.mjs` to include the new required properties.
64+
65+
#### Add Required Properties
66+
67+
Add `entryPoint` and `appRegistryComponentName` to your configuration:
68+
69+
```javascript title="rn-harness.config.mjs"
70+
const config = {
71+
// NEW: Required properties
72+
entryPoint: './index.js', // Path to your app's entry point
73+
appRegistryComponentName: 'MyApp', // Name used in AppRegistry.registerComponent
74+
75+
runners: [
76+
{
77+
name: 'android',
78+
platform: 'android',
79+
deviceId: 'Pixel_8_API_35',
80+
bundleId: 'com.myapp',
81+
},
82+
{
83+
name: 'ios',
84+
platform: 'ios',
85+
deviceId: 'iPhone 16 Pro',
86+
bundleId: 'com.myapp',
87+
systemVersion: '18.0',
88+
},
89+
],
90+
};
91+
92+
export default config;
93+
```
94+
95+
#### Properties Explained
96+
97+
- **`entryPoint`**: The path to your React Native app's entry point file (typically `index.js` or `src/main.tsx`)
98+
- **`appRegistryComponentName`**: The name you use when calling `AppRegistry.registerComponent('MyApp', () => App)` in your entry point
99+
100+
These properties allow React Native Harness to properly locate and integrate with your app without requiring conditional code in your entry point.
101+
102+
#### Remove `include` Property
103+
104+
The `include` property in `rn-harness.config.mjs` is **no longer supported**. If you were using it to specify which test files to run, remove it:
105+
106+
**Before:**
107+
108+
```javascript title="rn-harness.config.mjs"
109+
const config = {
110+
include: ['src/**/*.harness.ts', 'tests/**/*.test.ts'], // ❌ No longer supported
111+
runners: [
112+
/* ... */
113+
],
114+
};
115+
```
116+
117+
**After:**
118+
119+
```javascript title="rn-harness.config.mjs"
120+
const config = {
121+
// Remove the 'include' property entirely
122+
runners: [
123+
/* ... */
124+
],
125+
};
126+
```
127+
128+
#### Remove `reporter` Property
129+
130+
The `reporter` property in `rn-harness.config.mjs` is **no longer supported**. Test result reporting is now handled by Jest's built-in reporter system.
131+
132+
**Before:**
133+
134+
```javascript title="rn-harness.config.mjs"
135+
import { junitReporter } from '@react-native-harness/reporters';
136+
137+
const config = {
138+
reporter: junitReporter, // ❌ No longer supported
139+
runners: [
140+
/* ... */
141+
],
142+
};
143+
144+
export default config;
145+
```
146+
147+
**After:**
148+
149+
```javascript title="rn-harness.config.mjs"
150+
const config = {
151+
// Remove the 'reporter' property entirely
152+
runners: [
153+
/* ... */
154+
],
155+
};
156+
157+
export default config;
158+
```
159+
160+
To configure test result reporting, use Jest's `reporters` configuration instead (see step 4 below).
161+
162+
### 4. Configure Jest
163+
164+
Create or update your `jest.config.js` to use the React Native Harness preset and configure which test files to run.
165+
166+
```javascript title="jest.config.js"
167+
module.exports = {
168+
projects: [
169+
{
170+
preset: 'react-native-harness', // Required preset
171+
testMatch: [
172+
// Configure which files Jest should run
173+
'<rootDir>/src/__tests__/**/*.(test|spec|harness).(js|jsx|ts|tsx)',
174+
'<rootDir>/tests/**/*.harness.(js|jsx|ts|tsx)',
175+
],
176+
setupFiles: ['./src/setupFile.ts'], // Optional
177+
setupFilesAfterEnv: ['./src/setupFileAfterEnv.ts'], // Optional
178+
},
179+
],
180+
};
181+
```
182+
183+
## Getting Help
184+
185+
If you run into issues during migration:
186+
187+
- Check the [Configuration documentation](../getting-started/configuration.mdx) for detailed setup information
188+
- Review the [Quick Start guide](../getting-started/quick-start.mdx) for a complete setup example
189+
- Visit the [GitHub repository](https://github.com/callstackincubator/react-native-harness) to report issues or ask questions
190+
191+
---
192+
193+
Since React Native Harness now uses Jest as its test runner, you have access to all of Jest's powerful features and configuration options. For advanced Jest configuration, testing patterns, and troubleshooting, refer to the official [Jest documentation](https://jestjs.io/docs/getting-started). The Jest docs provide comprehensive guides on topics like:
194+
195+
- [Configuring Jest](https://jestjs.io/docs/configuration) for advanced test setups
196+
- [Reporters](https://jestjs.io/docs/configuration#reporters-arraymodulename--modulename-options) for customizing test output
197+
198+
The Jest ecosystem is mature and well-documented, making it easier to find solutions and integrate with other tools in your development workflow.

0 commit comments

Comments
 (0)