@react-native-harness/runtime 1.0.0-alpha.1

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 (229) hide show
  1. package/.babelrc.js +23 -0
  2. package/LICENSE +20 -0
  3. package/README.md +7 -0
  4. package/assets/logo.png +0 -0
  5. package/assets/moduleSystem.flow.js +1062 -0
  6. package/dist/bundler/bundle.d.ts +2 -0
  7. package/dist/bundler/bundle.d.ts.map +1 -0
  8. package/dist/bundler/bundle.js +16 -0
  9. package/dist/bundler/dev-server.d.ts +2 -0
  10. package/dist/bundler/dev-server.d.ts.map +1 -0
  11. package/dist/bundler/dev-server.js +5 -0
  12. package/dist/bundler/errors.d.ts +10 -0
  13. package/dist/bundler/errors.d.ts.map +1 -0
  14. package/dist/bundler/errors.js +18 -0
  15. package/dist/bundler/evaluate.d.ts +2 -0
  16. package/dist/bundler/evaluate.d.ts.map +1 -0
  17. package/dist/bundler/evaluate.js +18 -0
  18. package/dist/bundler/index.d.ts +3 -0
  19. package/dist/bundler/index.d.ts.map +1 -0
  20. package/dist/bundler/index.js +2 -0
  21. package/dist/client/factory.d.ts +2 -0
  22. package/dist/client/factory.d.ts.map +1 -0
  23. package/dist/client/factory.js +41 -0
  24. package/dist/client/getDeviceDescriptor.d.ts +8 -0
  25. package/dist/client/getDeviceDescriptor.d.ts.map +1 -0
  26. package/dist/client/getDeviceDescriptor.js +20 -0
  27. package/dist/client/getWSServer.d.ts +2 -0
  28. package/dist/client/getWSServer.d.ts.map +1 -0
  29. package/dist/client/getWSServer.js +7 -0
  30. package/dist/client/index.d.ts +2 -0
  31. package/dist/client/index.d.ts.map +1 -0
  32. package/dist/client/index.js +1 -0
  33. package/dist/collector/errors.d.ts +8 -0
  34. package/dist/collector/errors.d.ts.map +1 -0
  35. package/dist/collector/errors.js +20 -0
  36. package/dist/collector/factory.d.ts +3 -0
  37. package/dist/collector/factory.d.ts.map +1 -0
  38. package/dist/collector/factory.js +25 -0
  39. package/dist/collector/functions.d.ts +22 -0
  40. package/dist/collector/functions.d.ts.map +1 -0
  41. package/dist/collector/functions.js +271 -0
  42. package/dist/collector/index.d.ts +5 -0
  43. package/dist/collector/index.d.ts.map +1 -0
  44. package/dist/collector/index.js +3 -0
  45. package/dist/collector/types.d.ts +10 -0
  46. package/dist/collector/types.d.ts.map +1 -0
  47. package/dist/collector/types.js +1 -0
  48. package/dist/collector/validation.d.ts +4 -0
  49. package/dist/collector/validation.d.ts.map +1 -0
  50. package/dist/collector/validation.js +15 -0
  51. package/dist/constants.d.ts +3 -0
  52. package/dist/constants.d.ts.map +1 -0
  53. package/dist/constants.js +2 -0
  54. package/dist/errors.d.ts +6 -0
  55. package/dist/errors.d.ts.map +1 -0
  56. package/dist/errors.js +13 -0
  57. package/dist/expect/index.d.ts +9 -0
  58. package/dist/expect/index.d.ts.map +1 -0
  59. package/dist/expect/index.js +71 -0
  60. package/dist/expect/setup.d.ts +2 -0
  61. package/dist/expect/setup.d.ts.map +1 -0
  62. package/dist/expect/setup.js +5 -0
  63. package/dist/exports.d.ts +7 -0
  64. package/dist/exports.d.ts.map +1 -0
  65. package/dist/exports.js +6 -0
  66. package/dist/getEntryComponent.d.ts +6 -0
  67. package/dist/getEntryComponent.d.ts.map +1 -0
  68. package/dist/getEntryComponent.js +6 -0
  69. package/dist/globals.d.ts +5 -0
  70. package/dist/globals.d.ts.map +1 -0
  71. package/dist/globals.js +1 -0
  72. package/dist/index.d.ts +7 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +6 -0
  75. package/dist/initialize.d.ts +2 -0
  76. package/dist/initialize.d.ts.map +1 -0
  77. package/dist/initialize.js +16 -0
  78. package/dist/logger.d.ts +6 -0
  79. package/dist/logger.d.ts.map +1 -0
  80. package/dist/logger.js +14 -0
  81. package/dist/mock.d.ts +15 -0
  82. package/dist/mock.d.ts.map +1 -0
  83. package/dist/mock.js +37 -0
  84. package/dist/mocker/index.d.ts +2 -0
  85. package/dist/mocker/index.d.ts.map +1 -0
  86. package/dist/mocker/index.js +1 -0
  87. package/dist/mocker/registry.d.ts +7 -0
  88. package/dist/mocker/registry.d.ts.map +1 -0
  89. package/dist/mocker/registry.js +41 -0
  90. package/dist/mocker/types.d.ts +6 -0
  91. package/dist/mocker/types.d.ts.map +1 -0
  92. package/dist/mocker/types.js +1 -0
  93. package/dist/module.d.ts +3 -0
  94. package/dist/module.d.ts.map +1 -0
  95. package/dist/module.js +19 -0
  96. package/dist/module.web.d.ts +2 -0
  97. package/dist/module.web.d.ts.map +1 -0
  98. package/dist/module.web.js +12 -0
  99. package/dist/rntl/client.d.ts +3 -0
  100. package/dist/rntl/client.d.ts.map +1 -0
  101. package/dist/rntl/client.js +8 -0
  102. package/dist/rntl/describe.d.ts +2 -0
  103. package/dist/rntl/describe.d.ts.map +1 -0
  104. package/dist/rntl/describe.js +1 -0
  105. package/dist/rntl/expect.d.ts +128 -0
  106. package/dist/rntl/expect.d.ts.map +1 -0
  107. package/dist/rntl/expect.js +670 -0
  108. package/dist/rntl/fn.d.ts +2 -0
  109. package/dist/rntl/fn.d.ts.map +1 -0
  110. package/dist/rntl/fn.js +1 -0
  111. package/dist/rntl/mock.d.ts +2 -0
  112. package/dist/rntl/mock.d.ts.map +1 -0
  113. package/dist/rntl/mock.js +1 -0
  114. package/dist/rntl/render.d.ts +4 -0
  115. package/dist/rntl/render.d.ts.map +1 -0
  116. package/dist/rntl/render.js +11 -0
  117. package/dist/rntl/screen.d.ts +45 -0
  118. package/dist/rntl/screen.d.ts.map +1 -0
  119. package/dist/rntl/screen.js +31 -0
  120. package/dist/rntl/spies.d.ts +45 -0
  121. package/dist/rntl/spies.d.ts.map +1 -0
  122. package/dist/rntl/spies.js +553 -0
  123. package/dist/rntl/userEvent.d.ts +22 -0
  124. package/dist/rntl/userEvent.d.ts.map +1 -0
  125. package/dist/rntl/userEvent.js +19 -0
  126. package/dist/runner/errors.d.ts +9 -0
  127. package/dist/runner/errors.d.ts.map +1 -0
  128. package/dist/runner/errors.js +23 -0
  129. package/dist/runner/factory.d.ts +3 -0
  130. package/dist/runner/factory.d.ts.map +1 -0
  131. package/dist/runner/factory.js +17 -0
  132. package/dist/runner/hooks.d.ts +4 -0
  133. package/dist/runner/hooks.d.ts.map +1 -0
  134. package/dist/runner/hooks.js +39 -0
  135. package/dist/runner/index.d.ts +4 -0
  136. package/dist/runner/index.d.ts.map +1 -0
  137. package/dist/runner/index.js +2 -0
  138. package/dist/runner/runSuite.d.ts +4 -0
  139. package/dist/runner/runSuite.d.ts.map +1 -0
  140. package/dist/runner/runSuite.js +147 -0
  141. package/dist/runner/types.d.ts +13 -0
  142. package/dist/runner/types.d.ts.map +1 -0
  143. package/dist/runner/types.js +1 -0
  144. package/dist/runner.d.ts +7 -0
  145. package/dist/runner.d.ts.map +1 -0
  146. package/dist/runner.js +201 -0
  147. package/dist/runtime.d.ts +2 -0
  148. package/dist/runtime.d.ts.map +1 -0
  149. package/dist/runtime.js +44 -0
  150. package/dist/spy/index.d.ts +2 -0
  151. package/dist/spy/index.d.ts.map +1 -0
  152. package/dist/spy/index.js +2 -0
  153. package/dist/state.d.ts +25 -0
  154. package/dist/state.d.ts.map +1 -0
  155. package/dist/state.js +37 -0
  156. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  157. package/dist/ui/ReadyScreen.d.ts +2 -0
  158. package/dist/ui/ReadyScreen.d.ts.map +1 -0
  159. package/dist/ui/ReadyScreen.js +110 -0
  160. package/dist/ui/UI.d.ts +13 -0
  161. package/dist/ui/UI.d.ts.map +1 -0
  162. package/dist/ui/UI.js +121 -0
  163. package/dist/ui/WrongEnvironmentScreen.d.ts +2 -0
  164. package/dist/ui/WrongEnvironmentScreen.d.ts.map +1 -0
  165. package/dist/ui/WrongEnvironmentScreen.js +87 -0
  166. package/dist/ui/index.d.ts +2 -0
  167. package/dist/ui/index.d.ts.map +1 -0
  168. package/dist/ui/index.js +3 -0
  169. package/dist/ui/state.d.ts +7 -0
  170. package/dist/ui/state.d.ts.map +1 -0
  171. package/dist/ui/state.js +6 -0
  172. package/dist/utils/dev-server.d.ts +2 -0
  173. package/dist/utils/dev-server.d.ts.map +1 -0
  174. package/dist/utils/dev-server.js +5 -0
  175. package/dist/utils/emitter.d.ts +16 -0
  176. package/dist/utils/emitter.d.ts.map +1 -0
  177. package/dist/utils/emitter.js +39 -0
  178. package/eslint.config.mjs +16 -0
  179. package/package.json +38 -0
  180. package/src/__tests__/collector.test.ts +553 -0
  181. package/src/__tests__/error-handling.test.ts +132 -0
  182. package/src/__tests__/expect.test.ts +619 -0
  183. package/src/__tests__/spy.test.ts +538 -0
  184. package/src/bundler/bundle.ts +19 -0
  185. package/src/bundler/errors.ts +16 -0
  186. package/src/bundler/evaluate.ts +25 -0
  187. package/src/bundler/index.ts +2 -0
  188. package/src/client/factory.ts +56 -0
  189. package/src/client/getDeviceDescriptor.ts +30 -0
  190. package/src/client/getWSServer.ts +9 -0
  191. package/src/client/index.ts +1 -0
  192. package/src/collector/errors.ts +27 -0
  193. package/src/collector/factory.ts +32 -0
  194. package/src/collector/functions.ts +376 -0
  195. package/src/collector/index.ts +12 -0
  196. package/src/collector/types.ts +15 -0
  197. package/src/collector/validation.ts +21 -0
  198. package/src/constants.ts +2 -0
  199. package/src/errors.ts +12 -0
  200. package/src/expect/index.ts +117 -0
  201. package/src/expect/setup.ts +10 -0
  202. package/src/globals.ts +5 -0
  203. package/src/index.ts +7 -0
  204. package/src/initialize.ts +22 -0
  205. package/src/mocker/index.ts +1 -0
  206. package/src/mocker/metro-require.d.ts +5 -0
  207. package/src/mocker/registry.ts +58 -0
  208. package/src/mocker/types.ts +6 -0
  209. package/src/react-native.d.ts +16 -0
  210. package/src/runner/errors.ts +31 -0
  211. package/src/runner/factory.ts +21 -0
  212. package/src/runner/hooks.ts +51 -0
  213. package/src/runner/index.ts +7 -0
  214. package/src/runner/runSuite.ts +201 -0
  215. package/src/runner/types.ts +19 -0
  216. package/src/spy/index.ts +2 -0
  217. package/src/ui/ReadyScreen.tsx +151 -0
  218. package/src/ui/WrongEnvironmentScreen.tsx +113 -0
  219. package/src/ui/index.ts +3 -0
  220. package/src/ui/state.ts +13 -0
  221. package/src/utils/dev-server.ts +6 -0
  222. package/src/utils/emitter.ts +64 -0
  223. package/tsconfig.json +16 -0
  224. package/tsconfig.lib.json +33 -0
  225. package/tsconfig.spec.json +30 -0
  226. package/tsconfig.tsbuildinfo +1 -0
  227. package/types/global.d.ts +2 -0
  228. package/types/index.d.ts +1 -0
  229. package/vite.config.ts +27 -0
@@ -0,0 +1,553 @@
1
+ import * as sinon from 'sinon';
2
+ // 'any' is needed to accept 'any' functions
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ const sandbox = sinon.createSandbox();
5
+ export const clearAllSpies = () => {
6
+ sandbox.restore();
7
+ };
8
+ export const fn = (implementation) => {
9
+ const stub = sandbox.stub();
10
+ // Arrays to track instances and contexts manually
11
+ const instances = [];
12
+ const contexts = [];
13
+ // Store the original implementation
14
+ const originalImplementation = implementation;
15
+ // Create a wrapper that captures context and instances
16
+ const wrappedFunction = function (...args) {
17
+ // Capture the context (this value)
18
+ contexts.push(this);
19
+ // If called as constructor, capture the instance
20
+ if (new.target) {
21
+ const instance = Object.create(this.constructor?.prototype || {});
22
+ instances.push(instance);
23
+ // If there's an implementation, call it in constructor context
24
+ if (originalImplementation) {
25
+ const result = originalImplementation.apply(instance, args);
26
+ return result !== undefined ? result : instance;
27
+ }
28
+ return instance;
29
+ }
30
+ // Normal function call - call the original implementation if available
31
+ if (originalImplementation) {
32
+ return originalImplementation.apply(this, args);
33
+ }
34
+ // No implementation, return undefined
35
+ return undefined;
36
+ };
37
+ // Set up the initial behavior
38
+ stub.callsFake(wrappedFunction);
39
+ const jestSpy = Object.assign(stub, {
40
+ mock: {
41
+ calls: [],
42
+ instances,
43
+ contexts,
44
+ results: [],
45
+ lastCall: null,
46
+ },
47
+ mockClear: () => {
48
+ // Clear sinon internal data (the getters will now return empty arrays)
49
+ stub.resetHistory();
50
+ // Clear other mock tracking data that we manage directly
51
+ instances.length = 0;
52
+ contexts.length = 0;
53
+ return jestSpy;
54
+ },
55
+ mockReset: () => {
56
+ jestSpy.mockClear();
57
+ stub.resetBehavior();
58
+ return jestSpy;
59
+ },
60
+ mockRestore: () => {
61
+ if (stub.restore) {
62
+ stub.restore();
63
+ }
64
+ return jestSpy;
65
+ },
66
+ mockReturnValue: (value) => {
67
+ // Update the wrapper to always return the specified value
68
+ const returnWrapper = function (...args) {
69
+ contexts.push(this);
70
+ if (new.target) {
71
+ const instance = Object.create({});
72
+ instances.push(instance);
73
+ return value !== undefined ? value : instance;
74
+ }
75
+ return value;
76
+ };
77
+ stub.callsFake(returnWrapper);
78
+ return jestSpy;
79
+ },
80
+ mockReturnValueOnce: (value) => {
81
+ stub
82
+ .onCall(stub.callCount)
83
+ .callsFake(function (...args) {
84
+ contexts.push(this);
85
+ if (new.target) {
86
+ const instance = Object.create({});
87
+ instances.push(instance);
88
+ return value !== undefined ? value : instance;
89
+ }
90
+ return value;
91
+ });
92
+ return jestSpy;
93
+ },
94
+ mockResolvedValue: (value) => {
95
+ const promiseWrapper = function (...args) {
96
+ contexts.push(this);
97
+ if (new.target) {
98
+ const instance = Object.create({});
99
+ instances.push(instance);
100
+ return Promise.resolve(value);
101
+ }
102
+ return Promise.resolve(value);
103
+ };
104
+ stub.callsFake(promiseWrapper);
105
+ return jestSpy;
106
+ },
107
+ mockResolvedValueOnce: (value) => {
108
+ stub
109
+ .onCall(stub.callCount)
110
+ .callsFake(function (...args) {
111
+ contexts.push(this);
112
+ if (new.target) {
113
+ const instance = Object.create({});
114
+ instances.push(instance);
115
+ return Promise.resolve(value);
116
+ }
117
+ return Promise.resolve(value);
118
+ });
119
+ return jestSpy;
120
+ },
121
+ mockRejectedValue: (value) => {
122
+ const rejectWrapper = function (...args) {
123
+ contexts.push(this);
124
+ if (new.target) {
125
+ const instance = Object.create({});
126
+ instances.push(instance);
127
+ return Promise.reject(value);
128
+ }
129
+ return Promise.reject(value);
130
+ };
131
+ stub.callsFake(rejectWrapper);
132
+ return jestSpy;
133
+ },
134
+ mockRejectedValueOnce: (value) => {
135
+ stub
136
+ .onCall(stub.callCount)
137
+ .callsFake(function (...args) {
138
+ contexts.push(this);
139
+ if (new.target) {
140
+ const instance = Object.create({});
141
+ instances.push(instance);
142
+ return Promise.reject(value);
143
+ }
144
+ return Promise.reject(value);
145
+ });
146
+ return jestSpy;
147
+ },
148
+ mockImplementation: (fn) => {
149
+ // Update the wrapper to use the new implementation
150
+ const newWrapper = function (...args) {
151
+ contexts.push(this);
152
+ if (new.target) {
153
+ const instance = Object.create(fn.prototype || {});
154
+ instances.push(instance);
155
+ const result = fn.apply(instance, args);
156
+ return result !== undefined ? result : instance;
157
+ }
158
+ return fn.apply(this, args);
159
+ };
160
+ stub.callsFake(newWrapper);
161
+ return jestSpy;
162
+ },
163
+ mockImplementationOnce: (fn) => {
164
+ stub.onCall(stub.callCount).callsFake(fn);
165
+ return jestSpy;
166
+ },
167
+ // Convenience methods for Jest compatibility
168
+ toHaveBeenCalled: () => stub.called,
169
+ toHaveBeenCalledTimes: (expected) => stub.callCount === expected,
170
+ toHaveBeenCalledWith: (...args) => {
171
+ return stub
172
+ .getCalls()
173
+ .some((call) => call.args.length === args.length &&
174
+ call.args.every((arg, index) => arg === args[index]));
175
+ },
176
+ toHaveBeenLastCalledWith: (...args) => {
177
+ const calls = stub.getCalls();
178
+ if (calls.length === 0)
179
+ return false;
180
+ const lastCall = calls[calls.length - 1];
181
+ return (lastCall.args.length === args.length &&
182
+ lastCall.args.every((arg, index) => arg === args[index]));
183
+ },
184
+ toHaveBeenNthCalledWith: (nthCall, ...args) => {
185
+ const calls = stub.getCalls();
186
+ if (nthCall < 1 || nthCall > calls.length)
187
+ return false;
188
+ const call = calls[nthCall - 1];
189
+ return (call.args.length === args.length &&
190
+ call.args.every((arg, index) => arg === args[index]));
191
+ },
192
+ toHaveReturnedWith: (value) => {
193
+ return stub.getCalls().some((call) => call.returnValue === value);
194
+ },
195
+ toHaveLastReturnedWith: (value) => {
196
+ const calls = stub.getCalls();
197
+ if (calls.length === 0)
198
+ return false;
199
+ return calls[calls.length - 1].returnValue === value;
200
+ },
201
+ toHaveNthReturnedWith: (nthCall, value) => {
202
+ const calls = stub.getCalls();
203
+ if (nthCall < 1 || nthCall > calls.length)
204
+ return false;
205
+ return calls[nthCall - 1].returnValue === value;
206
+ },
207
+ toHaveReturnedTimes: (expected) => {
208
+ return (stub.getCalls().filter((call) => !call.exception).length === expected);
209
+ },
210
+ // Promise-specific helpers
211
+ toHaveResolvedWith: async (value) => {
212
+ const calls = stub.getCalls();
213
+ for (const call of calls) {
214
+ if (call.returnValue && typeof call.returnValue.then === 'function') {
215
+ try {
216
+ const resolved = await call.returnValue;
217
+ if (resolved === value)
218
+ return true;
219
+ }
220
+ catch {
221
+ // Promise rejected, skip
222
+ }
223
+ }
224
+ }
225
+ return false;
226
+ },
227
+ toHaveRejectedWith: async (value) => {
228
+ const calls = stub.getCalls();
229
+ for (const call of calls) {
230
+ if (call.returnValue && typeof call.returnValue.catch === 'function') {
231
+ try {
232
+ await call.returnValue;
233
+ // Promise resolved, skip
234
+ }
235
+ catch (error) {
236
+ if (error === value)
237
+ return true;
238
+ }
239
+ }
240
+ }
241
+ return false;
242
+ },
243
+ mockReturnThis: () => {
244
+ const thisWrapper = function (...args) {
245
+ contexts.push(this);
246
+ if (new.target) {
247
+ const instance = Object.create({});
248
+ instances.push(instance);
249
+ return instance;
250
+ }
251
+ return this;
252
+ };
253
+ stub.callsFake(thisWrapper);
254
+ return jestSpy;
255
+ },
256
+ });
257
+ // Override the mock object's getters to provide real-time data
258
+ Object.defineProperty(jestSpy.mock, 'calls', {
259
+ get: () => {
260
+ return stub.getCalls().map((call) => call.args);
261
+ },
262
+ enumerable: true,
263
+ });
264
+ Object.defineProperty(jestSpy.mock, 'lastCall', {
265
+ get: () => {
266
+ const calls = stub.getCalls().map((call) => call.args);
267
+ return calls.length > 0 ? calls[calls.length - 1] : null;
268
+ },
269
+ enumerable: true,
270
+ });
271
+ Object.defineProperty(jestSpy.mock, 'results', {
272
+ get: () => {
273
+ return stub.getCalls().map((call) => {
274
+ if (call.exception) {
275
+ return { type: 'throw', value: call.exception };
276
+ }
277
+ return { type: 'return', value: call.returnValue };
278
+ });
279
+ },
280
+ enumerable: true,
281
+ });
282
+ return jestSpy;
283
+ };
284
+ export const spyOn = (obj, method) => {
285
+ const stub = sandbox.stub(obj, method);
286
+ // Arrays to track instances and contexts manually
287
+ const instances = [];
288
+ const contexts = [];
289
+ // Store original method to capture context and instances
290
+ const originalMethod = obj[method];
291
+ // Create a wrapper that captures context and instances
292
+ const spyWrapper = function (...args) {
293
+ // Capture the context (this value)
294
+ contexts.push(this);
295
+ // If called as constructor, capture the instance
296
+ if (new.target && typeof originalMethod === 'function') {
297
+ const instance = Object.create(originalMethod.prototype || {});
298
+ instances.push(instance);
299
+ // Call original method as constructor
300
+ return originalMethod.apply(instance, args) || instance;
301
+ }
302
+ // Normal function call - use the original method
303
+ return originalMethod.apply(this, args);
304
+ };
305
+ // Set up the spy wrapper
306
+ stub.callsFake(spyWrapper);
307
+ const jestSpy = Object.assign(stub, {
308
+ mock: {
309
+ calls: [],
310
+ instances,
311
+ contexts,
312
+ results: [],
313
+ lastCall: null,
314
+ },
315
+ mockClear: () => {
316
+ // Clear sinon internal data (the getters will now return empty arrays)
317
+ stub.resetHistory();
318
+ // Clear other mock tracking data that we manage directly
319
+ jestSpy.mock.instances = [];
320
+ jestSpy.mock.contexts = [];
321
+ jestSpy.mock.calls = [];
322
+ jestSpy.mock.results = [];
323
+ jestSpy.mock.lastCall = null;
324
+ return jestSpy;
325
+ },
326
+ mockReset: () => {
327
+ jestSpy.mockClear();
328
+ stub.resetBehavior();
329
+ return jestSpy;
330
+ },
331
+ mockRestore: () => {
332
+ if (stub.restore) {
333
+ stub.restore();
334
+ }
335
+ return jestSpy;
336
+ },
337
+ mockReturnValue: (value) => {
338
+ const returnWrapper = function (...args) {
339
+ contexts.push(this);
340
+ if (new.target) {
341
+ const instance = Object.create({});
342
+ instances.push(instance);
343
+ return value !== undefined ? value : instance;
344
+ }
345
+ return value;
346
+ };
347
+ stub.callsFake(returnWrapper);
348
+ return jestSpy;
349
+ },
350
+ mockReturnValueOnce: (value) => {
351
+ stub
352
+ .onCall(stub.callCount)
353
+ .callsFake(function (...args) {
354
+ contexts.push(this);
355
+ if (new.target) {
356
+ const instance = Object.create({});
357
+ instances.push(instance);
358
+ return value !== undefined ? value : instance;
359
+ }
360
+ return value;
361
+ });
362
+ return jestSpy;
363
+ },
364
+ mockResolvedValue: (value) => {
365
+ const promiseWrapper = function (...args) {
366
+ contexts.push(this);
367
+ if (new.target) {
368
+ const instance = Object.create({});
369
+ instances.push(instance);
370
+ return Promise.resolve(value);
371
+ }
372
+ return Promise.resolve(value);
373
+ };
374
+ stub.callsFake(promiseWrapper);
375
+ return jestSpy;
376
+ },
377
+ mockResolvedValueOnce: (value) => {
378
+ stub
379
+ .onCall(stub.callCount)
380
+ .callsFake(function (...args) {
381
+ contexts.push(this);
382
+ if (new.target) {
383
+ const instance = Object.create({});
384
+ instances.push(instance);
385
+ return Promise.resolve(value);
386
+ }
387
+ return Promise.resolve(value);
388
+ });
389
+ return jestSpy;
390
+ },
391
+ mockRejectedValue: (value) => {
392
+ const rejectWrapper = function (...args) {
393
+ contexts.push(this);
394
+ if (new.target) {
395
+ const instance = Object.create({});
396
+ instances.push(instance);
397
+ return Promise.reject(value);
398
+ }
399
+ return Promise.reject(value);
400
+ };
401
+ stub.callsFake(rejectWrapper);
402
+ return jestSpy;
403
+ },
404
+ mockRejectedValueOnce: (value) => {
405
+ stub
406
+ .onCall(stub.callCount)
407
+ .callsFake(function (...args) {
408
+ contexts.push(this);
409
+ if (new.target) {
410
+ const instance = Object.create({});
411
+ instances.push(instance);
412
+ return Promise.reject(value);
413
+ }
414
+ return Promise.reject(value);
415
+ });
416
+ return jestSpy;
417
+ },
418
+ mockImplementation: (fn) => {
419
+ // Update the wrapper to use the new implementation
420
+ const newWrapper = function (...args) {
421
+ contexts.push(this);
422
+ if (new.target && typeof fn === 'function') {
423
+ const instance = Object.create(fn.prototype || {});
424
+ instances.push(instance);
425
+ const result = fn.apply(instance, args);
426
+ return result !== undefined ? result : instance;
427
+ }
428
+ return fn.apply(this, args);
429
+ };
430
+ stub.callsFake(newWrapper);
431
+ return jestSpy;
432
+ },
433
+ mockImplementationOnce: (fn) => {
434
+ stub.onCall(stub.callCount).callsFake(fn);
435
+ return jestSpy;
436
+ },
437
+ // Convenience methods for Jest compatibility
438
+ toHaveBeenCalled: () => stub.called,
439
+ toHaveBeenCalledTimes: (expected) => stub.callCount === expected,
440
+ toHaveBeenCalledWith: (...args) => {
441
+ return stub
442
+ .getCalls()
443
+ .some((call) => call.args.length === args.length &&
444
+ call.args.every((arg, index) => arg === args[index]));
445
+ },
446
+ toHaveBeenLastCalledWith: (...args) => {
447
+ const calls = stub.getCalls();
448
+ if (calls.length === 0)
449
+ return false;
450
+ const lastCall = calls[calls.length - 1];
451
+ return (lastCall.args.length === args.length &&
452
+ lastCall.args.every((arg, index) => arg === args[index]));
453
+ },
454
+ toHaveBeenNthCalledWith: (nthCall, ...args) => {
455
+ const calls = stub.getCalls();
456
+ if (nthCall < 1 || nthCall > calls.length)
457
+ return false;
458
+ const call = calls[nthCall - 1];
459
+ return (call.args.length === args.length &&
460
+ call.args.every((arg, index) => arg === args[index]));
461
+ },
462
+ toHaveReturnedWith: (value) => {
463
+ return stub.getCalls().some((call) => call.returnValue === value);
464
+ },
465
+ toHaveLastReturnedWith: (value) => {
466
+ const calls = stub.getCalls();
467
+ if (calls.length === 0)
468
+ return false;
469
+ return calls[calls.length - 1].returnValue === value;
470
+ },
471
+ toHaveNthReturnedWith: (nthCall, value) => {
472
+ const calls = stub.getCalls();
473
+ if (nthCall < 1 || nthCall > calls.length)
474
+ return false;
475
+ return calls[nthCall - 1].returnValue === value;
476
+ },
477
+ toHaveReturnedTimes: (expected) => {
478
+ return (stub.getCalls().filter((call) => !call.exception).length === expected);
479
+ },
480
+ // Promise-specific helpers
481
+ toHaveResolvedWith: async (value) => {
482
+ const calls = stub.getCalls();
483
+ for (const call of calls) {
484
+ if (call.returnValue && typeof call.returnValue.then === 'function') {
485
+ try {
486
+ const resolved = await call.returnValue;
487
+ if (resolved === value)
488
+ return true;
489
+ }
490
+ catch {
491
+ // Promise rejected, skip
492
+ }
493
+ }
494
+ }
495
+ return false;
496
+ },
497
+ toHaveRejectedWith: async (value) => {
498
+ const calls = stub.getCalls();
499
+ for (const call of calls) {
500
+ if (call.returnValue && typeof call.returnValue.catch === 'function') {
501
+ try {
502
+ await call.returnValue;
503
+ // Promise resolved, skip
504
+ }
505
+ catch (error) {
506
+ if (error === value)
507
+ return true;
508
+ }
509
+ }
510
+ }
511
+ return false;
512
+ },
513
+ mockReturnThis: () => {
514
+ const thisWrapper = function (...args) {
515
+ contexts.push(this);
516
+ if (new.target) {
517
+ const instance = Object.create({});
518
+ instances.push(instance);
519
+ return instance;
520
+ }
521
+ return this;
522
+ };
523
+ stub.callsFake(thisWrapper);
524
+ return jestSpy;
525
+ },
526
+ });
527
+ Object.defineProperty(jestSpy.mock, 'calls', {
528
+ get: () => {
529
+ return stub.getCalls().map((call) => call.args);
530
+ },
531
+ enumerable: true,
532
+ });
533
+ Object.defineProperty(jestSpy.mock, 'lastCall', {
534
+ get: () => {
535
+ const calls = stub.getCalls().map((call) => call.args);
536
+ return calls.length > 0 ? calls[calls.length - 1] : null;
537
+ },
538
+ enumerable: true,
539
+ });
540
+ Object.defineProperty(jestSpy.mock, 'results', {
541
+ get: () => {
542
+ return stub.getCalls().map((call) => {
543
+ if (call.exception) {
544
+ return { type: 'throw', value: call.exception };
545
+ }
546
+ return { type: 'return', value: call.returnValue };
547
+ });
548
+ },
549
+ enumerable: true,
550
+ });
551
+ return jestSpy;
552
+ };
553
+ export const spy = sinon.spy;
@@ -0,0 +1,22 @@
1
+ import { ElementRef } from '@react-native-harness/interaction-engine';
2
+ export declare const userEvent: {
3
+ press: (elementRef: ElementRef, options?: Omit<{
4
+ elementRef: ElementRef;
5
+ }, "elementRef"> | undefined) => Promise<void>;
6
+ longPress: (elementRef: ElementRef, options?: Omit<{
7
+ elementRef: ElementRef;
8
+ }, "elementRef"> | undefined) => Promise<void>;
9
+ type: (elementRef: ElementRef, options?: Omit<{
10
+ elementRef: ElementRef;
11
+ text: string;
12
+ }, "elementRef"> | undefined) => Promise<void>;
13
+ clear: (elementRef: ElementRef, options?: Omit<{
14
+ elementRef: ElementRef;
15
+ }, "elementRef"> | undefined) => Promise<void>;
16
+ scroll: (elementRef: ElementRef, options?: Omit<{
17
+ elementRef: ElementRef;
18
+ direction: "up" | "down" | "left" | "right";
19
+ distance: number;
20
+ }, "elementRef"> | undefined) => Promise<void>;
21
+ };
22
+ //# sourceMappingURL=userEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userEvent.d.ts","sourceRoot":"","sources":["../../src/rntl/userEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EACX,MAAM,0CAA0C,CAAC;AAkBlD,eAAO,MAAM,SAAS;wBAbN,UAAU;;;4BAAV,UAAU;;;uBAAV,UAAU;;;;wBAAV,UAAU;;;yBAAV,UAAU;;;;;CAmBzB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { getClient } from './client.js';
2
+ const getUserEventAction = (actionType) => {
3
+ return (elementRef, options) => {
4
+ return getClient().rpc.executeAction({
5
+ type: actionType,
6
+ payload: {
7
+ elementRef,
8
+ ...(options || {}),
9
+ },
10
+ });
11
+ };
12
+ };
13
+ export const userEvent = {
14
+ press: getUserEventAction('press'),
15
+ longPress: getUserEventAction('longPress'),
16
+ type: getUserEventAction('type'),
17
+ clear: getUserEventAction('clear'),
18
+ scroll: getUserEventAction('scroll'),
19
+ };
@@ -0,0 +1,9 @@
1
+ import type { SerializedError } from '@react-native-harness/bridge';
2
+ export declare class TestExecutionError extends Error {
3
+ file: string;
4
+ suite: string;
5
+ test: string;
6
+ constructor(error: unknown, file: string, suite: string, test: string);
7
+ toSerializedJSON(): SerializedError;
8
+ }
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/runner/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;gBAED,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IASrE,gBAAgB,IAAI,eAAe;CAcpC"}
@@ -0,0 +1,23 @@
1
+ export class TestExecutionError extends Error {
2
+ file;
3
+ suite;
4
+ test;
5
+ constructor(error, file, suite, test) {
6
+ super('Test execution error');
7
+ this.name = 'TestExecutionError';
8
+ this.file = file;
9
+ this.suite = suite;
10
+ this.test = test;
11
+ this.cause = error;
12
+ }
13
+ toSerializedJSON() {
14
+ const causeName = this.cause instanceof Error ? this.cause.name : 'Unknown name';
15
+ const causeMessage = this.cause instanceof Error ? this.cause.message : 'Unknown message';
16
+ const causeStack = this.cause instanceof Error ? this.cause.stack : undefined;
17
+ return {
18
+ name: causeName,
19
+ message: causeMessage,
20
+ stack: causeStack,
21
+ };
22
+ }
23
+ }
@@ -0,0 +1,3 @@
1
+ import { TestRunner } from './types.js';
2
+ export declare const getTestRunner: () => TestRunner;
3
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/runner/factory.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,aAAa,QAAO,UAehC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { getEmitter } from '../utils/emitter.js';
2
+ import { runSuite } from './runSuite.js';
3
+ export const getTestRunner = () => {
4
+ const events = getEmitter();
5
+ return {
6
+ events,
7
+ run: async (testSuite, testFilePath) => {
8
+ return runSuite(testSuite, {
9
+ events,
10
+ testFilePath,
11
+ });
12
+ },
13
+ dispose: () => {
14
+ events.clearAllListeners();
15
+ },
16
+ };
17
+ };
@@ -0,0 +1,4 @@
1
+ import type { TestSuite } from '@react-native-harness/bridge';
2
+ export type HookType = 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll';
3
+ export declare const runHooks: (suite: TestSuite, hookType: HookType) => Promise<void>;
4
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/runner/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AAuC7E,eAAO,MAAM,QAAQ,GACnB,OAAO,SAAS,EAChB,UAAU,QAAQ,KACjB,OAAO,CAAC,IAAI,CAMd,CAAC"}