@react-native-harness/config 1.3.0 → 1.4.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.
- package/dist/__tests__/resolveMetroCacheEnabled.test.d.ts +2 -0
- package/dist/__tests__/resolveMetroCacheEnabled.test.d.ts.map +1 -0
- package/dist/__tests__/resolveMetroCacheEnabled.test.js +91 -0
- package/dist/__tests__/resolveSkipAlreadyIncludedModules.test.d.ts +2 -0
- package/dist/__tests__/resolveSkipAlreadyIncludedModules.test.d.ts.map +1 -0
- package/dist/__tests__/resolveSkipAlreadyIncludedModules.test.js +50 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/types.d.ts +99 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +137 -3
- package/eslint.config.mjs +1 -0
- package/package.json +3 -3
- package/src/__tests__/resolveMetroCacheEnabled.test.ts +126 -0
- package/src/__tests__/resolveSkipAlreadyIncludedModules.test.ts +74 -0
- package/src/index.ts +7 -1
- package/src/types.ts +178 -3
- package/vite.config.ts +18 -0
package/src/types.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { HarnessPlugin } from '@react-native-harness/plugins';
|
|
3
3
|
import { isHarnessPlugin } from '@react-native-harness/plugins';
|
|
4
|
+
import { logger } from '@react-native-harness/tools';
|
|
4
5
|
|
|
5
6
|
export const DEFAULT_METRO_PORT = 8081;
|
|
6
7
|
|
|
8
|
+
const configLogger = logger.child('config');
|
|
9
|
+
|
|
7
10
|
const RunnerSchema = z.object({
|
|
8
11
|
name: z
|
|
9
12
|
.string()
|
|
@@ -53,6 +56,11 @@ export const ConfigSchema = z
|
|
|
53
56
|
.min(1000, 'Bridge timeout must be at least 1 second')
|
|
54
57
|
.default(60000),
|
|
55
58
|
|
|
59
|
+
testTimeout: z
|
|
60
|
+
.number()
|
|
61
|
+
.min(1000, 'Test timeout must be at least 1 second')
|
|
62
|
+
.default(5000),
|
|
63
|
+
|
|
56
64
|
platformReadyTimeout: z
|
|
57
65
|
.number()
|
|
58
66
|
.min(1000, 'Platform ready timeout must be at least 1 second')
|
|
@@ -66,10 +74,76 @@ export const ConfigSchema = z
|
|
|
66
74
|
.number()
|
|
67
75
|
.min(0, 'Max app restarts must be at least 0')
|
|
68
76
|
.default(2),
|
|
77
|
+
eagerPrewarm: z
|
|
78
|
+
.boolean()
|
|
79
|
+
.optional()
|
|
80
|
+
.default(true)
|
|
81
|
+
.describe(
|
|
82
|
+
'Start building the Metro bundle while the platform (emulator, simulator, or browser) is still booting, ' +
|
|
83
|
+
'so the first bundle is ready sooner. Disable to defer the first bundle build until app startup.'
|
|
84
|
+
),
|
|
69
85
|
|
|
70
|
-
resetEnvironmentBetweenTestFiles: z
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
resetEnvironmentBetweenTestFiles: z
|
|
87
|
+
.union([z.boolean(), z.enum(['process', 'runtime'])])
|
|
88
|
+
.optional()
|
|
89
|
+
.default(true)
|
|
90
|
+
.describe(
|
|
91
|
+
'Controls how the environment is reset between test files. `true` (default) and `\'process\'` ' +
|
|
92
|
+
'kill and cold-restart the app process. `\'runtime\'` reloads the JS runtime in place ' +
|
|
93
|
+
'(DevSettings.reload() / window.location.reload()), which is cheaper but escalates to a ' +
|
|
94
|
+
'process restart if the reload fails or the app does not reconnect in time. `false` disables ' +
|
|
95
|
+
'resetting the environment between test files entirely.'
|
|
96
|
+
),
|
|
97
|
+
skipAlreadyIncludedModules: z
|
|
98
|
+
.boolean()
|
|
99
|
+
.optional()
|
|
100
|
+
.describe(
|
|
101
|
+
'Skip re-sending modules already served in the main app bundle when Metro serves ' +
|
|
102
|
+
"a per-test-file bundle. Defaults to true; set to false as an escape hatch if it " +
|
|
103
|
+
'causes issues. Left undefined (rather than defaulted here) so `resolveSkipAlreadyIncludedModules` ' +
|
|
104
|
+
'can tell "not set" apart from "explicitly set" when reconciling with the deprecated ' +
|
|
105
|
+
'`unstable__skipAlreadyIncludedModules` alias.'
|
|
106
|
+
),
|
|
107
|
+
// Deprecated alias for `skipAlreadyIncludedModules` -- see
|
|
108
|
+
// `resolveSkipAlreadyIncludedModules`. Left without a `.default()` for the
|
|
109
|
+
// same reason: a default value would be indistinguishable from the user
|
|
110
|
+
// never having set it, which would break alias-vs-explicit-flag precedence.
|
|
111
|
+
unstable__skipAlreadyIncludedModules: z
|
|
112
|
+
.boolean()
|
|
113
|
+
.optional()
|
|
114
|
+
.describe(
|
|
115
|
+
'Deprecated. Use `skipAlreadyIncludedModules` instead.'
|
|
116
|
+
),
|
|
117
|
+
cache: z
|
|
118
|
+
.object({
|
|
119
|
+
metro: z
|
|
120
|
+
.boolean()
|
|
121
|
+
.optional()
|
|
122
|
+
.describe(
|
|
123
|
+
'Enable persistent Metro transform and file-map caching under the .harness cache directory. ' +
|
|
124
|
+
'Defaults to true; set to false to always start with a cold Metro cache. ' +
|
|
125
|
+
'Left undefined (rather than defaulted here) so `resolveMetroCacheEnabled` can tell ' +
|
|
126
|
+
'"not set" apart from "explicitly set" when reconciling with the deprecated ' +
|
|
127
|
+
'`unstable__enableMetroCache` alias.'
|
|
128
|
+
),
|
|
129
|
+
version: z
|
|
130
|
+
.string()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe(
|
|
133
|
+
'User-controlled salt folded into the Metro cacheVersion. ' +
|
|
134
|
+
'Bump it to force-invalidate previously cached transforms.'
|
|
135
|
+
),
|
|
136
|
+
})
|
|
137
|
+
.optional(),
|
|
138
|
+
// Deprecated alias for `cache.metro` -- see `resolveMetroCacheEnabled`.
|
|
139
|
+
// Left without a `.default()` for the same reason as
|
|
140
|
+
// `unstable__skipAlreadyIncludedModules`: a default value would be
|
|
141
|
+
// indistinguishable from the user never having set it, which would break
|
|
142
|
+
// alias-vs-explicit-flag precedence.
|
|
143
|
+
unstable__enableMetroCache: z
|
|
144
|
+
.boolean()
|
|
145
|
+
.optional()
|
|
146
|
+
.describe('Deprecated. Use `cache.metro` instead.'),
|
|
73
147
|
permissions: z
|
|
74
148
|
.boolean()
|
|
75
149
|
.optional()
|
|
@@ -133,6 +207,17 @@ export const ConfigSchema = z
|
|
|
133
207
|
"When enabled, app console output is attached to the active test result's console output."
|
|
134
208
|
),
|
|
135
209
|
|
|
210
|
+
diagnostics: z
|
|
211
|
+
.boolean()
|
|
212
|
+
.optional()
|
|
213
|
+
.default(false)
|
|
214
|
+
.describe(
|
|
215
|
+
'Enable diagnostics tracing for the harness session. Records spans for ' +
|
|
216
|
+
'session setup, Metro bundling, bridge/client events, and per-file test runs, ' +
|
|
217
|
+
'then writes a Chrome Trace Event JSON file and prints a summary after each run. ' +
|
|
218
|
+
'Can also be enabled via the RN_HARNESS_DIAGNOSTICS environment variable.'
|
|
219
|
+
),
|
|
220
|
+
|
|
136
221
|
// Deprecated property - used for migration detection
|
|
137
222
|
include: z.array(z.string()).optional(),
|
|
138
223
|
})
|
|
@@ -152,3 +237,93 @@ export const ConfigSchema = z
|
|
|
152
237
|
);
|
|
153
238
|
|
|
154
239
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Resolves whether diagnostics tracing is enabled: either explicitly via the
|
|
243
|
+
* `diagnostics` config option, or via the `RN_HARNESS_DIAGNOSTICS` environment
|
|
244
|
+
* variable (any value other than unset, `''`, `'0'`, or `'false'`).
|
|
245
|
+
*/
|
|
246
|
+
export const isDiagnosticsEnabled = (
|
|
247
|
+
config: Pick<Config, 'diagnostics'> | undefined,
|
|
248
|
+
env: NodeJS.ProcessEnv = process.env
|
|
249
|
+
): boolean => {
|
|
250
|
+
if (config?.diagnostics === true) {
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const envValue = env.RN_HARNESS_DIAGNOSTICS;
|
|
255
|
+
return !!envValue && envValue !== '0' && envValue !== 'false';
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Resolves the effective value of `skipAlreadyIncludedModules`, reconciling
|
|
260
|
+
* it with the deprecated `unstable__skipAlreadyIncludedModules` alias:
|
|
261
|
+
*
|
|
262
|
+
* - The new flag, when explicitly set, always wins over the alias.
|
|
263
|
+
* - Otherwise, the alias's value is used (with a deprecation warning).
|
|
264
|
+
* - Otherwise, defaults to `true`.
|
|
265
|
+
*
|
|
266
|
+
* The default is applied here rather than in the zod schema so that "unset"
|
|
267
|
+
* and "explicitly set to the default value" remain distinguishable -- that
|
|
268
|
+
* distinction is what lets the deprecated alias keep working as an escape
|
|
269
|
+
* hatch (e.g. `unstable__skipAlreadyIncludedModules: false`) even though the
|
|
270
|
+
* new flag now defaults to `true`.
|
|
271
|
+
*/
|
|
272
|
+
export const resolveSkipAlreadyIncludedModules = (
|
|
273
|
+
config: Pick<
|
|
274
|
+
Config,
|
|
275
|
+
'skipAlreadyIncludedModules' | 'unstable__skipAlreadyIncludedModules'
|
|
276
|
+
>
|
|
277
|
+
): boolean => {
|
|
278
|
+
if (config.unstable__skipAlreadyIncludedModules !== undefined) {
|
|
279
|
+
configLogger.warn(
|
|
280
|
+
'`unstable__skipAlreadyIncludedModules` is deprecated and will be removed in a future release. ' +
|
|
281
|
+
'Use `skipAlreadyIncludedModules` instead.'
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (config.skipAlreadyIncludedModules !== undefined) {
|
|
286
|
+
return config.skipAlreadyIncludedModules;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (config.unstable__skipAlreadyIncludedModules !== undefined) {
|
|
290
|
+
return config.unstable__skipAlreadyIncludedModules;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return true;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Resolves whether persistent Metro caching is enabled, reconciling
|
|
298
|
+
* `cache.metro` with the deprecated `unstable__enableMetroCache` alias:
|
|
299
|
+
*
|
|
300
|
+
* - `cache.metro`, when explicitly set, always wins over the alias.
|
|
301
|
+
* - Otherwise, the alias's value is used (with a deprecation warning).
|
|
302
|
+
* - Otherwise, defaults to `true`.
|
|
303
|
+
*
|
|
304
|
+
* The default is applied here rather than in the zod schema so that "unset"
|
|
305
|
+
* and "explicitly set to the default value" remain distinguishable -- that
|
|
306
|
+
* distinction is what lets the deprecated alias keep working as an escape
|
|
307
|
+
* hatch (e.g. `unstable__enableMetroCache: false`) even though caching now
|
|
308
|
+
* defaults to on.
|
|
309
|
+
*/
|
|
310
|
+
export const resolveMetroCacheEnabled = (
|
|
311
|
+
config: Pick<Config, 'cache' | 'unstable__enableMetroCache'>
|
|
312
|
+
): boolean => {
|
|
313
|
+
if (config.unstable__enableMetroCache !== undefined) {
|
|
314
|
+
configLogger.warn(
|
|
315
|
+
'`unstable__enableMetroCache` is deprecated and will be removed in a future release. ' +
|
|
316
|
+
'Use `cache.metro` instead.'
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (config.cache?.metro !== undefined) {
|
|
321
|
+
return config.cache.metro;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (config.unstable__enableMetroCache !== undefined) {
|
|
325
|
+
return config.unstable__enableMetroCache;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return true;
|
|
329
|
+
};
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types='vitest' />
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
|
|
4
|
+
export default defineConfig(() => ({
|
|
5
|
+
root: __dirname,
|
|
6
|
+
cacheDir: '../../node_modules/.vite/packages/config',
|
|
7
|
+
test: {
|
|
8
|
+
watch: false,
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'node',
|
|
11
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
12
|
+
reporters: ['default'],
|
|
13
|
+
coverage: {
|
|
14
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
15
|
+
provider: 'v8' as const,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}));
|