@react-native-harness/runtime 1.0.0-alpha.8 → 1.0.0-canary.1761046904277

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 (203) hide show
  1. package/README.md +23 -4
  2. package/assets/moduleSystem.flow.js +23 -3
  3. package/dist/bundler/bundle.d.ts.map +1 -1
  4. package/dist/bundler/bundle.js +1 -0
  5. package/dist/bundler/evaluate.d.ts.map +1 -1
  6. package/dist/bundler/evaluate.js +7 -7
  7. package/dist/bundler/factory.d.ts +3 -0
  8. package/dist/bundler/factory.d.ts.map +1 -0
  9. package/dist/bundler/factory.js +36 -0
  10. package/dist/bundler/index.d.ts +2 -1
  11. package/dist/bundler/index.d.ts.map +1 -1
  12. package/dist/bundler/index.js +1 -1
  13. package/dist/bundler/types.d.ts +7 -0
  14. package/dist/bundler/types.d.ts.map +1 -0
  15. package/dist/bundler/types.js +1 -0
  16. package/dist/client/factory.d.ts.map +1 -1
  17. package/dist/client/factory.js +75 -11
  18. package/dist/client/getDeviceDescriptor.d.ts +1 -1
  19. package/dist/client/getDeviceDescriptor.d.ts.map +1 -1
  20. package/dist/client/getDeviceDescriptor.js +18 -6
  21. package/dist/collector/functions.d.ts.map +1 -1
  22. package/dist/collector/functions.js +8 -0
  23. package/dist/entry-point.d.ts +2 -0
  24. package/dist/entry-point.d.ts.map +1 -0
  25. package/dist/entry-point.js +4 -0
  26. package/dist/expect/index.d.ts.map +1 -1
  27. package/dist/expect/index.js +2 -0
  28. package/dist/expect/setup.js +2 -0
  29. package/dist/filtering/index.d.ts +2 -0
  30. package/dist/filtering/index.d.ts.map +1 -0
  31. package/dist/filtering/index.js +1 -0
  32. package/dist/filtering/testNameFilter.d.ts +12 -0
  33. package/dist/filtering/testNameFilter.d.ts.map +1 -0
  34. package/dist/filtering/testNameFilter.js +56 -0
  35. package/dist/globals.d.ts +5 -2
  36. package/dist/globals.d.ts.map +1 -1
  37. package/dist/globals.js +7 -1
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -0
  41. package/dist/initialize.js +7 -0
  42. package/dist/jest-mock.d.ts +2 -0
  43. package/dist/jest-mock.d.ts.map +1 -0
  44. package/dist/jest-mock.js +25 -0
  45. package/dist/mocker/index.d.ts +1 -1
  46. package/dist/mocker/index.d.ts.map +1 -1
  47. package/dist/mocker/index.js +1 -1
  48. package/dist/mocker/registry.d.ts +2 -2
  49. package/dist/mocker/registry.d.ts.map +1 -1
  50. package/dist/mocker/registry.js +10 -4
  51. package/dist/namespace.d.ts +18 -0
  52. package/dist/namespace.d.ts.map +1 -0
  53. package/dist/namespace.js +19 -0
  54. package/dist/runner/factory.d.ts.map +1 -1
  55. package/dist/runner/factory.js +6 -1
  56. package/dist/runner/runSuite.d.ts.map +1 -1
  57. package/dist/runner/runSuite.js +37 -0
  58. package/dist/symbolicate.d.ts.map +1 -1
  59. package/dist/symbolicate.js +5 -4
  60. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  61. package/dist/utils/emitter.d.ts.map +1 -1
  62. package/dist/waitFor.d.ts +21 -0
  63. package/dist/waitFor.d.ts.map +1 -0
  64. package/dist/waitFor.js +137 -0
  65. package/eslint.config.mjs +1 -7
  66. package/out-tsc/vitest/src/__tests__/collector.test.d.ts +2 -0
  67. package/out-tsc/vitest/src/__tests__/collector.test.d.ts.map +1 -0
  68. package/out-tsc/vitest/src/__tests__/error-handling.test.d.ts +2 -0
  69. package/out-tsc/vitest/src/__tests__/error-handling.test.d.ts.map +1 -0
  70. package/out-tsc/vitest/src/__tests__/expect.test.d.ts +2 -0
  71. package/out-tsc/vitest/src/__tests__/expect.test.d.ts.map +1 -0
  72. package/out-tsc/vitest/src/__tests__/spy.test.d.ts +2 -0
  73. package/out-tsc/vitest/src/__tests__/spy.test.d.ts.map +1 -0
  74. package/out-tsc/vitest/src/bundler/bundle.d.ts +2 -0
  75. package/out-tsc/vitest/src/bundler/bundle.d.ts.map +1 -0
  76. package/out-tsc/vitest/src/bundler/errors.d.ts +15 -0
  77. package/out-tsc/vitest/src/bundler/errors.d.ts.map +1 -0
  78. package/out-tsc/vitest/src/bundler/evaluate.d.ts +2 -0
  79. package/out-tsc/vitest/src/bundler/evaluate.d.ts.map +1 -0
  80. package/out-tsc/vitest/src/bundler/factory.d.ts +3 -0
  81. package/out-tsc/vitest/src/bundler/factory.d.ts.map +1 -0
  82. package/out-tsc/vitest/src/bundler/index.d.ts +4 -0
  83. package/out-tsc/vitest/src/bundler/index.d.ts.map +1 -0
  84. package/out-tsc/vitest/src/bundler/types.d.ts +7 -0
  85. package/out-tsc/vitest/src/bundler/types.d.ts.map +1 -0
  86. package/out-tsc/vitest/src/client/factory.d.ts +2 -0
  87. package/out-tsc/vitest/src/client/factory.d.ts.map +1 -0
  88. package/out-tsc/vitest/src/client/getDeviceDescriptor.d.ts +8 -0
  89. package/out-tsc/vitest/src/client/getDeviceDescriptor.d.ts.map +1 -0
  90. package/out-tsc/vitest/src/client/getWSServer.d.ts +2 -0
  91. package/out-tsc/vitest/src/client/getWSServer.d.ts.map +1 -0
  92. package/out-tsc/vitest/src/client/index.d.ts +2 -0
  93. package/out-tsc/vitest/src/client/index.d.ts.map +1 -0
  94. package/out-tsc/vitest/src/collector/errors.d.ts +8 -0
  95. package/out-tsc/vitest/src/collector/errors.d.ts.map +1 -0
  96. package/out-tsc/vitest/src/collector/factory.d.ts +3 -0
  97. package/out-tsc/vitest/src/collector/factory.d.ts.map +1 -0
  98. package/out-tsc/vitest/src/collector/functions.d.ts +22 -0
  99. package/out-tsc/vitest/src/collector/functions.d.ts.map +1 -0
  100. package/out-tsc/vitest/src/collector/index.d.ts +5 -0
  101. package/out-tsc/vitest/src/collector/index.d.ts.map +1 -0
  102. package/out-tsc/vitest/src/collector/types.d.ts +10 -0
  103. package/out-tsc/vitest/src/collector/types.d.ts.map +1 -0
  104. package/out-tsc/vitest/src/collector/validation.d.ts +4 -0
  105. package/out-tsc/vitest/src/collector/validation.d.ts.map +1 -0
  106. package/out-tsc/vitest/src/constants.d.ts +3 -0
  107. package/out-tsc/vitest/src/constants.d.ts.map +1 -0
  108. package/out-tsc/vitest/src/entry-point.d.ts +2 -0
  109. package/out-tsc/vitest/src/entry-point.d.ts.map +1 -0
  110. package/out-tsc/vitest/src/errors.d.ts +6 -0
  111. package/out-tsc/vitest/src/errors.d.ts.map +1 -0
  112. package/out-tsc/vitest/src/expect/index.d.ts +9 -0
  113. package/out-tsc/vitest/src/expect/index.d.ts.map +1 -0
  114. package/out-tsc/vitest/src/expect/setup.d.ts +2 -0
  115. package/out-tsc/vitest/src/expect/setup.d.ts.map +1 -0
  116. package/out-tsc/vitest/src/filtering/index.d.ts +2 -0
  117. package/out-tsc/vitest/src/filtering/index.d.ts.map +1 -0
  118. package/out-tsc/vitest/src/filtering/testNameFilter.d.ts +12 -0
  119. package/out-tsc/vitest/src/filtering/testNameFilter.d.ts.map +1 -0
  120. package/out-tsc/vitest/src/globals.d.ts +8 -0
  121. package/out-tsc/vitest/src/globals.d.ts.map +1 -0
  122. package/out-tsc/vitest/src/index.d.ts +9 -0
  123. package/out-tsc/vitest/src/index.d.ts.map +1 -0
  124. package/out-tsc/vitest/src/initialize.d.ts +2 -0
  125. package/out-tsc/vitest/src/initialize.d.ts.map +1 -0
  126. package/out-tsc/vitest/src/mocker/index.d.ts +2 -0
  127. package/out-tsc/vitest/src/mocker/index.d.ts.map +1 -0
  128. package/out-tsc/vitest/src/mocker/registry.d.ts +7 -0
  129. package/out-tsc/vitest/src/mocker/registry.d.ts.map +1 -0
  130. package/out-tsc/vitest/src/mocker/types.d.ts +6 -0
  131. package/out-tsc/vitest/src/mocker/types.d.ts.map +1 -0
  132. package/out-tsc/vitest/src/namespace.d.ts +18 -0
  133. package/out-tsc/vitest/src/namespace.d.ts.map +1 -0
  134. package/out-tsc/vitest/src/runner/errors.d.ts +11 -0
  135. package/out-tsc/vitest/src/runner/errors.d.ts.map +1 -0
  136. package/out-tsc/vitest/src/runner/factory.d.ts +3 -0
  137. package/out-tsc/vitest/src/runner/factory.d.ts.map +1 -0
  138. package/out-tsc/vitest/src/runner/hooks.d.ts +4 -0
  139. package/out-tsc/vitest/src/runner/hooks.d.ts.map +1 -0
  140. package/out-tsc/vitest/src/runner/index.d.ts +4 -0
  141. package/out-tsc/vitest/src/runner/index.d.ts.map +1 -0
  142. package/out-tsc/vitest/src/runner/runSuite.d.ts +4 -0
  143. package/out-tsc/vitest/src/runner/runSuite.d.ts.map +1 -0
  144. package/out-tsc/vitest/src/runner/types.d.ts +13 -0
  145. package/out-tsc/vitest/src/runner/types.d.ts.map +1 -0
  146. package/out-tsc/vitest/src/spy/index.d.ts +2 -0
  147. package/out-tsc/vitest/src/spy/index.d.ts.map +1 -0
  148. package/out-tsc/vitest/src/symbolicate.d.ts +3 -0
  149. package/out-tsc/vitest/src/symbolicate.d.ts.map +1 -0
  150. package/out-tsc/vitest/src/ui/ReadyScreen.d.ts +2 -0
  151. package/out-tsc/vitest/src/ui/ReadyScreen.d.ts.map +1 -0
  152. package/out-tsc/vitest/src/ui/WrongEnvironmentScreen.d.ts +2 -0
  153. package/out-tsc/vitest/src/ui/WrongEnvironmentScreen.d.ts.map +1 -0
  154. package/out-tsc/vitest/src/ui/index.d.ts +2 -0
  155. package/out-tsc/vitest/src/ui/index.d.ts.map +1 -0
  156. package/out-tsc/vitest/src/ui/state.d.ts +7 -0
  157. package/out-tsc/vitest/src/ui/state.d.ts.map +1 -0
  158. package/out-tsc/vitest/src/utils/dev-server.d.ts +2 -0
  159. package/out-tsc/vitest/src/utils/dev-server.d.ts.map +1 -0
  160. package/out-tsc/vitest/src/utils/emitter.d.ts +16 -0
  161. package/out-tsc/vitest/src/utils/emitter.d.ts.map +1 -0
  162. package/out-tsc/vitest/src/waitFor.d.ts +21 -0
  163. package/out-tsc/vitest/src/waitFor.d.ts.map +1 -0
  164. package/out-tsc/vitest/tsconfig.spec.tsbuildinfo +1 -0
  165. package/out-tsc/vitest/vite.config.d.ts +3 -0
  166. package/out-tsc/vitest/vite.config.d.ts.map +1 -0
  167. package/package.json +15 -7
  168. package/src/__tests__/expect.test.ts +13 -5
  169. package/src/bundler/bundle.ts +1 -0
  170. package/src/bundler/evaluate.ts +9 -9
  171. package/src/bundler/factory.ts +43 -0
  172. package/src/bundler/index.ts +2 -1
  173. package/src/bundler/types.ts +7 -0
  174. package/src/client/factory.ts +95 -12
  175. package/src/client/getDeviceDescriptor.ts +29 -8
  176. package/src/collector/functions.ts +14 -0
  177. package/src/entry-point.ts +8 -0
  178. package/src/expect/index.ts +8 -2
  179. package/src/expect/setup.ts +3 -0
  180. package/src/filtering/index.ts +4 -0
  181. package/src/filtering/testNameFilter.ts +82 -0
  182. package/src/globals.ts +14 -2
  183. package/src/index.ts +2 -0
  184. package/src/initialize.ts +11 -1
  185. package/src/jest-mock.ts +32 -0
  186. package/src/mocker/index.ts +7 -1
  187. package/src/mocker/metro-require.d.ts +2 -0
  188. package/src/mocker/registry.ts +13 -5
  189. package/src/namespace.ts +41 -0
  190. package/src/react-native.d.ts +2 -10
  191. package/src/runner/factory.ts +8 -1
  192. package/src/runner/runSuite.ts +43 -0
  193. package/src/symbolicate.ts +6 -4
  194. package/src/utils/emitter.ts +1 -0
  195. package/src/waitFor.ts +199 -0
  196. package/tsconfig.spec.json +7 -3
  197. package/tsconfig.tsbuildinfo +1 -1
  198. package/dist/utils/progressLogger.d.ts +0 -8
  199. package/dist/utils/progressLogger.d.ts.map +0 -1
  200. package/dist/utils/progressLogger.js +0 -73
  201. package/src/utils/progressLogger.ts +0 -91
  202. package/types/global.d.ts +0 -2
  203. package/types/index.d.ts +0 -1
package/README.md CHANGED
@@ -1,7 +1,26 @@
1
- # @react-native-harness/runtime
1
+ ![harness-banner](https://react-native-harness.dev/harness-banner.jpg)
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ ### Test Runtime for React Native Harness
4
4
 
5
- ## Running unit tests
5
+ [![mit licence][license-badge]][license]
6
+ [![npm downloads][npm-downloads-badge]][npm-downloads]
7
+ [![Chat][chat-badge]][chat]
8
+ [![PRs Welcome][prs-welcome-badge]][prs-welcome]
6
9
 
7
- Run `nx test @react-native-harness/runtime` to execute the unit tests via [Jest](https://jestjs.io).
10
+ The core test runtime that executes on React Native devices, providing Jest-compatible APIs (describe, it, expect) and managing test collection, execution, and result reporting in native environments.
11
+
12
+ ## Made with ❤️ at Callstack
13
+
14
+ `@react-native-harness/runtime` is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack][callstack-readme-with-love] is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!
15
+
16
+ Like the project? ⚛️ [Join the team](https://callstack.com/careers/?utm_campaign=Senior_RN&utm_source=github&utm_medium=readme) who does amazing stuff for clients and drives React Native Open Source! 🔥
17
+
18
+ [callstack-readme-with-love]: https://callstack.com/?utm_source=github.com&utm_medium=referral&utm_campaign=react-native-harness&utm_term=readme-with-love
19
+ [license-badge]: https://img.shields.io/npm/l/@react-native-harness/runtime?style=for-the-badge
20
+ [license]: https://github.com/callstackincubator/react-native-harness/blob/main/LICENSE
21
+ [npm-downloads-badge]: https://img.shields.io/npm/dm/@react-native-harness/runtime?style=for-the-badge
22
+ [npm-downloads]: https://www.npmjs.com/package/@react-native-harness/runtime
23
+ [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
24
+ [prs-welcome]: ../../CONTRIBUTING.md
25
+ [chat-badge]: https://img.shields.io/discord/426714625279524876.svg?style=for-the-badge
26
+ [chat]: https://discord.gg/xgGt7KAjxv
@@ -84,9 +84,26 @@ global.__r = (metroRequire: RequireFn);
84
84
  global[`${__METRO_GLOBAL_PREFIX__}__d`] = (define: DefineFn);
85
85
  global.__c = clear;
86
86
  global.__registerSegment = registerSegment;
87
+ global.__resetAllModules = resetAllModules;
88
+ global.__clearModule = clearModule;
87
89
 
88
90
  var modules = clear();
89
91
 
92
+ function resetAllModules() {
93
+ modules.forEach((mod) => {
94
+ // Mutating existing module doesn't work for some reason
95
+ modules.set(mod.id, { ...mod, isInitialized: false });
96
+ });
97
+ }
98
+
99
+ function clearModule(moduleId: ModuleID) {
100
+ if (!modules.has(moduleId)) {
101
+ return;
102
+ }
103
+
104
+ modules.delete(moduleId);
105
+ }
106
+
90
107
  // Don't use a Symbol here, it would pull in an extra polyfill with all sorts of
91
108
  // additional stuff (e.g. Array.from).
92
109
  const EMPTY = {};
@@ -485,11 +502,14 @@ function loadModuleImplementation(
485
502
  // keep args in sync with with defineModuleCode in
486
503
  // metro/src/Resolver/index.js
487
504
  // and metro/src/ModuleGraph/worker.js
505
+ const capturedRequire = (...args) => global.__r(...args);
506
+ Object.assign(capturedRequire, global.__r);
507
+
488
508
  factory(
489
509
  global,
490
- (...args) => global.__r(...args),
491
- (...args) => global.__r.importDefault(...args),
492
- (...args) => global.__r.importAll(...args),
510
+ capturedRequire,
511
+ capturedRequire.importDefault,
512
+ capturedRequire.importAll,
493
513
  moduleObject,
494
514
  moduleObject.exports,
495
515
  dependencyMap
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/bundler/bundle.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAUlE,CAAC"}
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/bundler/bundle.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAUlE,CAAC"}
@@ -7,6 +7,7 @@ const getModuleUrl = (fileName) => {
7
7
  const urlSearchParams = new URLSearchParams({
8
8
  modulesOnly: 'true',
9
9
  platform: Platform.OS,
10
+ 'resolver.isHarness': 'true',
10
11
  });
11
12
  return `${devServerUrl}/${bundleName}?${urlSearchParams.toString()}`;
12
13
  };
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/bundler/evaluate.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,EAAE,YAAY,MAAM,KAAG,IAqBrE,CAAC"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/bundler/evaluate.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,EAAE,YAAY,MAAM,KAAG,IAsBrE,CAAC"}
@@ -1,18 +1,18 @@
1
1
  import { MalformedModuleError } from './errors.js';
2
- import { EnvironmentError } from '../errors.js';
3
2
  export const evaluateModule = (moduleJs, modulePath) => {
4
- const __rMatch = moduleJs.match(/__r\((\d+)\)/);
5
- if (!__rMatch) {
3
+ const __rMatches = Array.from(moduleJs.matchAll(/__r\((\d+)\)/g));
4
+ if (__rMatches.length === 0) {
6
5
  throw new MalformedModuleError(modulePath, 'No __r function found');
7
6
  }
7
+ // Get the last match as there may be many require calls
8
+ const __rMatch = __rMatches[__rMatches.length - 1];
8
9
  const __rParam = __rMatch[1];
9
10
  if (!__rParam) {
10
11
  throw new MalformedModuleError(modulePath, 'No __r parameter found');
11
12
  }
13
+ const moduleId = Number(__rParam);
14
+ // This is important as if module was already initialized, it would not be re-initialized
15
+ global.__clearModule(moduleId);
12
16
  // eslint-disable-next-line no-eval
13
17
  eval(moduleJs);
14
- if (!__r) {
15
- throw new EnvironmentError('module evaluation', '__r is not defined');
16
- }
17
- __r(Number(__rParam));
18
18
  };
@@ -0,0 +1,3 @@
1
+ import { Bundler } from './types.js';
2
+ export declare const getBundler: () => Bundler;
3
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/bundler/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIrC,eAAO,MAAM,UAAU,QAAO,OAoC7B,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { getEmitter } from '../utils/emitter.js';
2
+ import { fetchModule } from './bundle.js';
3
+ import { BundlingFailedError } from './errors.js';
4
+ export const getBundler = () => {
5
+ const events = getEmitter();
6
+ return {
7
+ events,
8
+ getModule: async (filePath) => {
9
+ const bundlingStartTime = Date.now();
10
+ events.emit({
11
+ type: 'module-bundling-started',
12
+ file: filePath,
13
+ });
14
+ try {
15
+ const moduleJs = await fetchModule(filePath);
16
+ events.emit({
17
+ type: 'module-bundling-finished',
18
+ file: filePath,
19
+ duration: Date.now() - bundlingStartTime,
20
+ });
21
+ return moduleJs;
22
+ }
23
+ catch (error) {
24
+ events.emit({
25
+ type: 'module-bundling-failed',
26
+ file: filePath,
27
+ duration: Date.now() - bundlingStartTime,
28
+ error: error instanceof BundlingFailedError
29
+ ? error.reason
30
+ : 'Unknown error',
31
+ });
32
+ throw error;
33
+ }
34
+ },
35
+ };
36
+ };
@@ -1,3 +1,4 @@
1
- export { fetchModule } from './bundle.js';
2
1
  export { evaluateModule } from './evaluate.js';
2
+ export { getBundler } from './factory.js';
3
+ export type { Bundler } from './types.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
@@ -1,2 +1,2 @@
1
- export { fetchModule } from './bundle.js';
2
1
  export { evaluateModule } from './evaluate.js';
2
+ export { getBundler } from './factory.js';
@@ -0,0 +1,7 @@
1
+ import { BundlerEvents } from '@react-native-harness/bridge';
2
+ import { EventEmitter } from '../utils/emitter.js';
3
+ export type Bundler = {
4
+ events: EventEmitter<BundlerEvents>;
5
+ getModule: (filePath: string) => Promise<string>;
6
+ };
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bundler/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IACpC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,2EAiDrB,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,SAAS,2EAkIrB,CAAC"}
@@ -3,16 +3,16 @@ import { store } from '../ui/state.js';
3
3
  import { getTestRunner } from '../runner/index.js';
4
4
  import { getTestCollector } from '../collector/index.js';
5
5
  import { combineEventEmitters } from '../utils/emitter.js';
6
- import { attachProgressLogger } from '../utils/progressLogger.js';
7
6
  import { getWSServer } from './getWSServer.js';
8
- import { fetchModule, evaluateModule } from '../bundler/index.js';
7
+ import { getBundler, evaluateModule } from '../bundler/index.js';
8
+ import { markTestsAsSkippedByName } from '../filtering/index.js';
9
9
  export const getClient = async () => {
10
10
  const client = await getBridgeClient(getWSServer(), {
11
11
  runTests: async () => {
12
12
  throw new Error('Not implemented');
13
13
  },
14
14
  });
15
- client.rpc.$functions.runTests = async (path) => {
15
+ client.rpc.$functions.runTests = async (path, options = {}) => {
16
16
  if (store.getState().status === 'running') {
17
17
  throw new Error('Already running tests');
18
18
  }
@@ -20,23 +20,87 @@ export const getClient = async () => {
20
20
  let collector = null;
21
21
  let runner = null;
22
22
  let events = null;
23
+ let bundler = null;
23
24
  try {
24
25
  collector = getTestCollector();
25
26
  runner = getTestRunner();
26
- events = combineEventEmitters(collector.events, runner.events);
27
+ bundler = getBundler();
28
+ events = combineEventEmitters(collector.events, runner.events, bundler.events);
27
29
  events.addListener((event) => {
28
30
  client.rpc.emitEvent(event.type, event);
29
31
  });
30
- // Add console logging for progress information
31
- attachProgressLogger(events, path);
32
- const moduleJs = await fetchModule(path);
32
+ // Execute setup files before test collection
33
+ if (options.setupFiles) {
34
+ for (const setupFile of options.setupFiles) {
35
+ const startTime = Date.now();
36
+ events.emit({
37
+ type: 'setup-file-bundling-started',
38
+ file: setupFile,
39
+ setupType: 'setupFiles',
40
+ });
41
+ try {
42
+ const setupModuleJs = await bundler.getModule(setupFile);
43
+ events.emit({
44
+ type: 'setup-file-bundling-finished',
45
+ file: setupFile,
46
+ setupType: 'setupFiles',
47
+ duration: Date.now() - startTime,
48
+ });
49
+ evaluateModule(setupModuleJs, setupFile);
50
+ }
51
+ catch (error) {
52
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
53
+ events.emit({
54
+ type: 'setup-file-bundling-failed',
55
+ file: setupFile,
56
+ setupType: 'setupFiles',
57
+ duration: Date.now() - startTime,
58
+ error: errorMessage,
59
+ });
60
+ throw error;
61
+ }
62
+ }
63
+ }
64
+ if (options.setupFilesAfterEnv) {
65
+ for (const setupFile of options.setupFilesAfterEnv) {
66
+ const startTime = Date.now();
67
+ events.emit({
68
+ type: 'setup-file-bundling-started',
69
+ file: setupFile,
70
+ setupType: 'setupFilesAfterEnv',
71
+ });
72
+ try {
73
+ const setupModuleJs = await bundler.getModule(setupFile);
74
+ events.emit({
75
+ type: 'setup-file-bundling-finished',
76
+ file: setupFile,
77
+ setupType: 'setupFilesAfterEnv',
78
+ duration: Date.now() - startTime,
79
+ });
80
+ evaluateModule(setupModuleJs, setupFile);
81
+ }
82
+ catch (error) {
83
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
84
+ events.emit({
85
+ type: 'setup-file-bundling-failed',
86
+ file: setupFile,
87
+ setupType: 'setupFilesAfterEnv',
88
+ duration: Date.now() - startTime,
89
+ error: errorMessage,
90
+ });
91
+ throw error;
92
+ }
93
+ }
94
+ }
95
+ const moduleJs = await bundler.getModule(path);
33
96
  const collectionResult = await collector.collect(() => evaluateModule(moduleJs, path), path);
34
- const result = await runner.run(collectionResult.testSuite, path);
97
+ // Apply test name pattern by marking non-matching tests as skipped
98
+ const processedTestSuite = options.testNamePattern
99
+ ? markTestsAsSkippedByName(collectionResult.testSuite, options.testNamePattern)
100
+ : collectionResult.testSuite;
101
+ const result = await runner.run(processedTestSuite, path);
35
102
  return result;
36
103
  }
37
- catch (error) {
38
- throw error;
39
- }
40
104
  finally {
41
105
  collector?.dispose();
42
106
  runner?.dispose();
@@ -1,5 +1,5 @@
1
1
  export type DeviceDescriptor = {
2
- platform: 'ios' | 'android';
2
+ platform: 'ios' | 'android' | 'vega';
3
3
  manufacturer: string;
4
4
  model: string;
5
5
  osVersion: string;
@@ -1 +1 @@
1
- {"version":3,"file":"getDeviceDescriptor.d.ts","sourceRoot":"","sources":["../../src/client/getDeviceDescriptor.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,gBAoBtC,CAAC"}
1
+ {"version":3,"file":"getDeviceDescriptor.d.ts","sourceRoot":"","sources":["../../src/client/getDeviceDescriptor.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,gBA+BtC,CAAC"}
@@ -1,19 +1,31 @@
1
1
  import { Platform } from 'react-native';
2
+ const getPlatform = () => {
3
+ return Platform;
4
+ };
2
5
  export const getDeviceDescriptor = () => {
3
- if (Platform.OS === 'ios') {
6
+ const platform = getPlatform();
7
+ if (platform.OS === 'ios') {
4
8
  return {
5
9
  platform: 'ios',
6
10
  manufacturer: 'Apple',
7
11
  model: 'Unknown',
8
- osVersion: Platform.constants.osVersion,
12
+ osVersion: platform.constants.osVersion,
9
13
  };
10
14
  }
11
- if (Platform.OS === 'android') {
15
+ if (platform.OS === 'android') {
12
16
  return {
13
17
  platform: 'android',
14
- manufacturer: Platform.constants.Manufacturer,
15
- model: Platform.constants.Model,
16
- osVersion: Platform.constants.Release,
18
+ manufacturer: platform.constants.Manufacturer,
19
+ model: platform.constants.Model,
20
+ osVersion: platform.constants.Release,
21
+ };
22
+ }
23
+ if (platform.OS === 'kepler') {
24
+ return {
25
+ platform: 'vega',
26
+ manufacturer: '',
27
+ model: '',
28
+ osVersion: '',
17
29
  };
18
30
  }
19
31
  throw new Error('Unsupported platform');
@@ -1 +1 @@
1
- {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA8KzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,IAAI,KAAG,gBAiB7C,CAAC"}
1
+ {"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA4LzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,IAAI,KAAG,gBAiB7C,CAAC"}
@@ -17,6 +17,14 @@ const computeSuiteStatus = (suite, parentContext) => {
17
17
  return 'skipped';
18
18
  if (suite.options.only)
19
19
  return 'active';
20
+ // Check if this suite has any focused content (tests or child suites)
21
+ const hasFocusedTests = suite.tests.some((test) => test.options.only);
22
+ const hasFocusedChildren = suite.suites.some((childSuite) => childSuite.options.only ||
23
+ childSuite.tests.some((test) => test.options.only));
24
+ // If this suite has focused content, it should be active
25
+ if (hasFocusedTests || hasFocusedChildren)
26
+ return 'active';
27
+ // If parent has focused children and this suite has no focused content, skip it
20
28
  if (parentContext.hasFocusedChildren)
21
29
  return 'skipped';
22
30
  return 'active';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=entry-point.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point.d.ts","sourceRoot":"","sources":["../src/entry-point.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { AppRegistry } from 'react-native';
2
+ import { getHarnessGlobal } from './globals.js';
3
+ import { UI } from './ui/index.js';
4
+ AppRegistry.registerComponent(getHarnessGlobal().appRegistryComponentName, () => UI);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/expect/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,YAAY,EAAgB,MAAM,gBAAgB,CAAC;AAS5E,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,YAAY,CAAC;AAEpB,wBAAgB,YAAY,IAAI,YAAY,CAkF3C;AAED,QAAA,MAAM,YAAY,EAAE,YAA6B,CAAC;AAQlD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,YAAY,IAAI,MAAM,EAAE,CAAC;AAExC,YAAY,EACV,SAAS,EACT,4BAA4B,EAC5B,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,QAAQ,GACT,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/expect/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAa,YAAY,EAAgB,MAAM,gBAAgB,CAAC;AAS5E,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,YAAY,CAAC;AAEpB,wBAAgB,YAAY,IAAI,YAAY,CAqF3C;AAED,QAAA,MAAM,YAAY,EAAE,YAA6B,CAAC;AAQlD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,YAAY,IAAI,MAAM,EAAE,CAAC;AAExC,YAAY,EACV,SAAS,EACT,4BAA4B,EAC5B,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,QAAQ,GACT,MAAM,gBAAgB,CAAC"}
@@ -1,3 +1,5 @@
1
+ // This is adapted version of https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/integrations/chai/index.ts
2
+ // Credits to Vitest team for the original implementation.
1
3
  import { addCustomEqualityTesters, ASYMMETRIC_MATCHERS_OBJECT, customMatchers, getState, GLOBAL_EXPECT, setState, } from '@vitest/expect';
2
4
  import * as chai from 'chai';
3
5
  // Setup additional matchers
@@ -1,3 +1,5 @@
1
+ // This is adapted version of https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/integrations/chai/setup.ts
2
+ // Credits to Vitest team for the original implementation.
1
3
  import { JestAsymmetricMatchers, JestChaiExpect, JestExtend, } from '@vitest/expect';
2
4
  import * as chai from 'chai';
3
5
  chai.use(JestExtend);
@@ -0,0 +1,2 @@
1
+ export { filterTestsByName, markTestsAsSkippedByName, } from './testNameFilter.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filtering/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { filterTestsByName, markTestsAsSkippedByName, } from './testNameFilter.js';
@@ -0,0 +1,12 @@
1
+ import { TestSuite } from '@react-native-harness/bridge';
2
+ /**
3
+ * Filters tests by name pattern, matching against test names and suite+test combinations
4
+ * @deprecated Use markTestsAsSkippedByName instead - this function will be removed in a future version
5
+ */
6
+ export declare const filterTestsByName: (suite: TestSuite, testNamePattern: string) => TestSuite;
7
+ /**
8
+ * Marks tests as skipped based on name pattern, keeping all tests in the structure
9
+ * but setting non-matching tests to 'skipped' status
10
+ */
11
+ export declare const markTestsAsSkippedByName: (suite: TestSuite, testNamePattern: string) => TestSuite;
12
+ //# sourceMappingURL=testNameFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testNameFilter.d.ts","sourceRoot":"","sources":["../../src/filtering/testNameFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,SAAS,EAChB,iBAAiB,MAAM,KACtB,SAGF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,SAAS,EAChB,iBAAiB,MAAM,KACtB,SAGF,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Filters tests by name pattern, matching against test names and suite+test combinations
3
+ * @deprecated Use markTestsAsSkippedByName instead - this function will be removed in a future version
4
+ */
5
+ export const filterTestsByName = (suite, testNamePattern) => {
6
+ const regex = new RegExp(testNamePattern);
7
+ return filterSuiteRecursively(suite, regex);
8
+ };
9
+ /**
10
+ * Marks tests as skipped based on name pattern, keeping all tests in the structure
11
+ * but setting non-matching tests to 'skipped' status
12
+ */
13
+ export const markTestsAsSkippedByName = (suite, testNamePattern) => {
14
+ const regex = new RegExp(testNamePattern);
15
+ return markTestsRecursively(suite, regex);
16
+ };
17
+ const markTestsRecursively = (suite, regex) => {
18
+ // Mark tests in current suite - skip tests that don't match the pattern
19
+ const updatedTests = suite.tests.map((test) => {
20
+ const matches = regex.test(test.name) || regex.test(`${suite.name} ${test.name}`);
21
+ // If test doesn't match pattern and is currently active, mark it as skipped
22
+ if (!matches && test.status === 'active') {
23
+ return {
24
+ ...test,
25
+ status: 'skipped',
26
+ };
27
+ }
28
+ // Keep original status for matching tests or already skipped/todo tests
29
+ return test;
30
+ });
31
+ // Recursively process child suites
32
+ const updatedChildSuites = suite.suites.map((childSuite) => markTestsRecursively(childSuite, regex));
33
+ return {
34
+ ...suite,
35
+ tests: updatedTests,
36
+ suites: updatedChildSuites,
37
+ };
38
+ };
39
+ const filterSuiteRecursively = (suite, regex) => {
40
+ // Filter tests in current suite - match against test name or "suite test" combination
41
+ const filteredTests = suite.tests.filter((test) => regex.test(test.name) || regex.test(`${suite.name} ${test.name}`));
42
+ // Recursively filter child suites
43
+ const filteredChildSuites = suite.suites
44
+ .map((childSuite) => filterSuiteRecursively(childSuite, regex))
45
+ .filter((childSuite) => hasAnyActiveTests(childSuite));
46
+ return {
47
+ ...suite,
48
+ tests: filteredTests,
49
+ suites: filteredChildSuites,
50
+ };
51
+ };
52
+ const hasAnyActiveTests = (suite) => {
53
+ const hasDirectTests = suite.tests.some((test) => test.status === 'active');
54
+ const hasChildTests = suite.suites.some((childSuite) => hasAnyActiveTests(childSuite));
55
+ return hasDirectTests || hasChildTests;
56
+ };
package/dist/globals.d.ts CHANGED
@@ -1,5 +1,8 @@
1
+ export type HarnessGlobal = {
2
+ appRegistryComponentName: string;
3
+ };
1
4
  declare global {
2
- var RN_HARNESS: boolean | undefined;
5
+ var RN_HARNESS: HarnessGlobal | undefined;
3
6
  }
4
- export {};
7
+ export declare const getHarnessGlobal: () => HarnessGlobal;
5
8
  //# sourceMappingURL=globals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,wBAAwB,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,UAAU,EAAE,aAAa,GAAG,SAAS,CAAC;CAC3C;AAED,eAAO,MAAM,gBAAgB,QAAO,aAQnC,CAAC"}
package/dist/globals.js CHANGED
@@ -1 +1,7 @@
1
- export {};
1
+ export const getHarnessGlobal = () => {
2
+ const harnessGlobal = global.RN_HARNESS;
3
+ if (!harnessGlobal) {
4
+ throw new Error('RN_HARNESS global is not set');
5
+ }
6
+ return harnessGlobal;
7
+ };
package/dist/index.d.ts CHANGED
@@ -4,4 +4,6 @@ export * from './spy/index.js';
4
4
  export * from './expect/index.js';
5
5
  export * from './collector/index.js';
6
6
  export * from './mocker/index.js';
7
+ export * from './namespace.js';
8
+ export * from './waitFor.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -4,3 +4,5 @@ export * from './spy/index.js';
4
4
  export * from './expect/index.js';
5
5
  export * from './collector/index.js';
6
6
  export * from './mocker/index.js';
7
+ export * from './namespace.js';
8
+ export * from './waitFor.js';
@@ -1,9 +1,12 @@
1
1
  import { getDeviceDescriptor } from './client/getDeviceDescriptor.js';
2
2
  import { getClient } from './client/index.js';
3
+ import { setupJestMock } from './jest-mock.js';
3
4
  // Polyfill for EventTarget
4
5
  const Shim = require('event-target-shim');
5
6
  globalThis.Event = Shim.Event;
6
7
  globalThis.EventTarget = Shim.EventTarget;
8
+ // Setup jest mock to warn users about using Jest APIs
9
+ setupJestMock();
7
10
  // Turn off LogBox
8
11
  const { LogBox } = require('react-native');
9
12
  LogBox.ignoreAllLogs(true);
@@ -16,3 +19,7 @@ setTimeout(() => {
16
19
  // Initialize the React Native Harness
17
20
  void getClient().then((client) => client.rpc.reportReady(getDeviceDescriptor()));
18
21
  });
22
+ // Re-throw fatal errors
23
+ ErrorUtils.setGlobalHandler((error) => {
24
+ throw error;
25
+ });
@@ -0,0 +1,2 @@
1
+ export declare const setupJestMock: () => void;
2
+ //# sourceMappingURL=jest-mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jest-mock.d.ts","sourceRoot":"","sources":["../src/jest-mock.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,aAAa,QAAO,IA8BhC,CAAC"}
@@ -0,0 +1,25 @@
1
+ // Mock jest global to warn users about using Jest APIs in Harness tests
2
+ export const setupJestMock = () => {
3
+ function throwError() {
4
+ throw new Error(`Jest globals are not available in Harness tests. Import from 'react-native-harness' instead (e.g., import { harness } from 'react-native-harness'; harness.fn())`);
5
+ }
6
+ const jestMock = new Proxy({}, {
7
+ get() {
8
+ throwError();
9
+ },
10
+ set() {
11
+ throwError();
12
+ },
13
+ has() {
14
+ throwError();
15
+ },
16
+ ownKeys() {
17
+ throwError();
18
+ },
19
+ });
20
+ Object.defineProperty(globalThis, 'jest', {
21
+ value: jestMock,
22
+ writable: false,
23
+ configurable: false,
24
+ });
25
+ };
@@ -1,2 +1,2 @@
1
- export { mock, requireActual, clearMocks } from './registry.js';
1
+ export { mock, requireActual, clearMocks, unmock, resetModules, } from './registry.js';
2
2
  //# sourceMappingURL=index.d.ts.map