@testing-library/react-native 7.1.0 → 8.0.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.
Files changed (52) hide show
  1. package/README.md +24 -4
  2. package/build/act.js.flow +2 -1
  3. package/build/fireEvent.js +24 -17
  4. package/build/fireEvent.js.flow +36 -28
  5. package/build/flushMicroTasks.js +3 -1
  6. package/build/flushMicroTasks.js.flow +1 -0
  7. package/build/helpers/a11yAPI.js +9 -10
  8. package/build/helpers/a11yAPI.js.flow +10 -12
  9. package/build/helpers/byDisplayValue.js +48 -0
  10. package/build/helpers/byDisplayValue.js.flow +56 -0
  11. package/build/helpers/byPlaceholderText.js +47 -0
  12. package/build/helpers/byPlaceholderText.js.flow +54 -0
  13. package/build/helpers/byTestId.js +36 -0
  14. package/build/helpers/byTestId.js.flow +46 -0
  15. package/build/helpers/byText.js +94 -0
  16. package/build/helpers/byText.js.flow +88 -0
  17. package/build/helpers/debugDeep.js +1 -1
  18. package/build/helpers/debugDeep.js.flow +1 -1
  19. package/build/helpers/debugShallow.js.flow +1 -1
  20. package/build/helpers/errors.js +6 -0
  21. package/build/helpers/errors.js.flow +10 -3
  22. package/build/helpers/filterNodeByType.js +10 -0
  23. package/build/helpers/filterNodeByType.js.flow +1 -0
  24. package/build/helpers/findByAPI.js +14 -46
  25. package/build/helpers/findByAPI.js.flow +43 -58
  26. package/build/helpers/format.js.flow +1 -1
  27. package/build/helpers/getByAPI.js +16 -184
  28. package/build/helpers/getByAPI.js.flow +52 -204
  29. package/build/helpers/{makeQuery.js → makeA11yQuery.js} +2 -2
  30. package/build/helpers/{makeQuery.js.flow → makeA11yQuery.js.flow} +5 -3
  31. package/build/helpers/makeQueries.js +78 -0
  32. package/build/helpers/makeQueries.js.flow +114 -0
  33. package/build/helpers/queryByAPI.js +16 -88
  34. package/build/helpers/queryByAPI.js.flow +57 -90
  35. package/build/helpers/timers.js +77 -0
  36. package/build/helpers/timers.js.flow +88 -0
  37. package/build/index.js +1 -0
  38. package/build/render.js +11 -4
  39. package/build/render.js.flow +32 -8
  40. package/build/shallow.js.flow +1 -1
  41. package/build/types.flow.js.flow +4 -0
  42. package/build/waitFor.js +148 -19
  43. package/build/waitFor.js.flow +159 -18
  44. package/build/waitForElementToBeRemoved.js +3 -1
  45. package/build/waitForElementToBeRemoved.js.flow +3 -2
  46. package/build/within.js +2 -4
  47. package/build/within.js.flow +7 -5
  48. package/jest-preset/index.js +10 -0
  49. package/jest-preset/restore-promise.js +1 -0
  50. package/jest-preset/save-promise.js +1 -0
  51. package/package.json +20 -15
  52. package/typings/index.d.ts +13 -4
@@ -3,10 +3,10 @@ import * as React from 'react';
3
3
  import TestRenderer, { type ReactTestRenderer } from 'react-test-renderer'; // eslint-disable-line import/no-extraneous-dependencies
4
4
  import act from './act';
5
5
  import { addToCleanupQueue } from './cleanup';
6
- import { getByAPI } from './helpers/getByAPI';
7
- import { queryByAPI } from './helpers/queryByAPI';
8
- import { findByAPI } from './helpers/findByAPI';
9
- import a11yAPI from './helpers/a11yAPI';
6
+ import { getByAPI, type GetByAPI } from './helpers/getByAPI';
7
+ import { queryByAPI, type QueryByAPI } from './helpers/queryByAPI';
8
+ import { findByAPI, type FindByAPI } from './helpers/findByAPI';
9
+ import { a11yAPI, type A11yAPI } from './helpers/a11yAPI';
10
10
  import debugShallow from './helpers/debugShallow';
11
11
  import debugDeep from './helpers/debugDeep';
12
12
 
@@ -25,7 +25,18 @@ type TestRendererOptions = {
25
25
  export default function render<T>(
26
26
  component: React.Element<T>,
27
27
  { wrapper: Wrapper, createNodeMock }: Options = {}
28
- ) {
28
+ ): {
29
+ ...FindByAPI,
30
+ ...QueryByAPI,
31
+ ...GetByAPI,
32
+ ...A11yAPI,
33
+ update: (component: React.Element<any>) => void,
34
+ container: ReactTestInstance,
35
+ rerender: (component: React.Element<any>) => void,
36
+ unmount: (nextElement?: React.Element<any>) => void,
37
+ toJSON: () => null | ReactTestRendererJSON,
38
+ debug: DebugFunction,
39
+ } {
29
40
  const wrap = (innerElement: React.Element<any>) =>
30
41
  Wrapper ? <Wrapper>{innerElement}</Wrapper> : innerElement;
31
42
 
@@ -35,8 +46,13 @@ export default function render<T>(
35
46
  );
36
47
  const update = updateWithAct(renderer, wrap);
37
48
  const instance = renderer.root;
49
+ const unmount = () => {
50
+ act(() => {
51
+ renderer.unmount();
52
+ });
53
+ };
38
54
 
39
- addToCleanupQueue(renderer.unmount);
55
+ addToCleanupQueue(unmount);
40
56
 
41
57
  return {
42
58
  ...getByAPI(instance),
@@ -44,9 +60,9 @@ export default function render<T>(
44
60
  ...findByAPI(instance),
45
61
  ...a11yAPI(instance),
46
62
  update,
63
+ unmount,
47
64
  container: instance,
48
65
  rerender: update, // alias for `update`
49
- unmount: renderer.unmount,
50
66
  toJSON: renderer.toJSON,
51
67
  debug: debug(instance, renderer),
52
68
  };
@@ -76,7 +92,15 @@ function updateWithAct(
76
92
  };
77
93
  }
78
94
 
79
- function debug(instance: ReactTestInstance, renderer) {
95
+ interface DebugFunction {
96
+ (message?: string): void;
97
+ shallow: (message?: string) => void;
98
+ }
99
+
100
+ function debug(
101
+ instance: ReactTestInstance,
102
+ renderer: ReactTestRenderer
103
+ ): DebugFunction {
80
104
  function debugImpl(message?: string) {
81
105
  return debugDeep(renderer.toJSON(), message);
82
106
  }
@@ -8,7 +8,7 @@ import { throwRemovedFunctionError } from './helpers/errors';
8
8
  */
9
9
  export function shallowInternal(
10
10
  instance: ReactTestInstance | React.Element<any>
11
- ) {
11
+ ): {| output: any |} {
12
12
  const renderer = new ShallowRenderer();
13
13
 
14
14
  renderer.render(React.createElement(instance.type, instance.props));
@@ -1,5 +1,9 @@
1
1
  // @flow
2
2
 
3
+ export type Thenable = {
4
+ then(resolve: () => mixed, reject?: () => mixed): mixed,
5
+ };
6
+
3
7
  export type A11yRole =
4
8
  | 'none'
5
9
  | 'button'
package/build/waitFor.js CHANGED
@@ -12,13 +12,16 @@ var _act = _interopRequireDefault(require("./act"));
12
12
 
13
13
  var _errors = require("./helpers/errors");
14
14
 
15
+ var _timers = require("./helpers/timers");
16
+
15
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
18
 
17
19
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
18
20
 
19
21
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
22
 
21
- const DEFAULT_TIMEOUT = 4500;
23
+ /* globals jest */
24
+ const DEFAULT_TIMEOUT = 1000;
22
25
  const DEFAULT_INTERVAL = 50;
23
26
 
24
27
  function checkReactVersionAtLeast(major, minor) {
@@ -27,44 +30,170 @@ function checkReactVersionAtLeast(major, minor) {
27
30
  return actualMajor > major || actualMajor === major && actualMinor >= minor;
28
31
  }
29
32
 
30
- function waitForInternal(expectation, options) {
31
- var _options$timeout, _options$interval;
33
+ function waitForInternal(expectation, {
34
+ timeout = DEFAULT_TIMEOUT,
35
+ interval = DEFAULT_INTERVAL,
36
+ stackTraceError
37
+ }) {
38
+ if (typeof expectation !== 'function') {
39
+ throw new TypeError('Received `expectation` arg must be a function');
40
+ } // eslint-disable-next-line no-async-promise-executor
41
+
42
+
43
+ return new Promise(async (resolve, reject) => {
44
+ let lastError, intervalId;
45
+ let finished = false;
46
+ let promiseStatus = 'idle';
47
+ const overallTimeoutTimer = (0, _timers.setTimeout)(handleTimeout, timeout);
48
+ const usingFakeTimers = (0, _timers.jestFakeTimersAreEnabled)();
49
+
50
+ if (usingFakeTimers) {
51
+ checkExpectation(); // this is a dangerous rule to disable because it could lead to an
52
+ // infinite loop. However, eslint isn't smart enough to know that we're
53
+ // setting finished inside `onDone` which will be called when we're done
54
+ // waiting or when we've timed out.
55
+ // eslint-disable-next-line no-unmodified-loop-condition
56
+
57
+ let fakeTimeRemaining = timeout;
58
+
59
+ while (!finished) {
60
+ if (!(0, _timers.jestFakeTimersAreEnabled)()) {
61
+ const error = new Error(`Changed from using fake timers to real timers while using waitFor. This is not allowed and will result in very strange behavior. Please ensure you're awaiting all async things your test is doing before changing to real timers. For more info, please go to https://github.com/testing-library/dom-testing-library/issues/830`);
62
+
63
+ if (stackTraceError) {
64
+ (0, _errors.copyStackTrace)(error, stackTraceError);
65
+ }
66
+
67
+ reject(error);
68
+ return;
69
+ } // when fake timers are used we want to simulate the interval time passing
70
+
71
+
72
+ if (fakeTimeRemaining <= 0) {
73
+ return;
74
+ } else {
75
+ fakeTimeRemaining -= interval;
76
+ } // we *could* (maybe should?) use `advanceTimersToNextTimer` but it's
77
+ // possible that could make this loop go on forever if someone is using
78
+ // third party code that's setting up recursive timers so rapidly that
79
+ // the user's timer's don't get a chance to resolve. So we'll advance
80
+ // by an interval instead. (We have a test for this case).
81
+
82
+
83
+ jest.advanceTimersByTime(interval); // It's really important that checkExpectation is run *before* we flush
84
+ // in-flight promises. To be honest, I'm not sure why, and I can't quite
85
+ // think of a way to reproduce the problem in a test, but I spent
86
+ // an entire day banging my head against a wall on this.
87
+
88
+ checkExpectation(); // In this rare case, we *need* to wait for in-flight promises
89
+ // to resolve before continuing. We don't need to take advantage
90
+ // of parallelization so we're fine.
91
+ // https://stackoverflow.com/a/59243586/971592
92
+ // eslint-disable-next-line no-await-in-loop
93
+
94
+ await new Promise(resolve => (0, _timers.setImmediate)(resolve));
95
+ }
96
+ } else {
97
+ intervalId = setInterval(checkRealTimersCallback, interval);
98
+ checkExpectation();
99
+ }
100
+
101
+ function onDone(error, result) {
102
+ finished = true;
103
+ (0, _timers.clearTimeout)(overallTimeoutTimer);
104
+
105
+ if (!usingFakeTimers) {
106
+ clearInterval(intervalId);
107
+ }
32
108
 
33
- const timeout = (_options$timeout = options === null || options === void 0 ? void 0 : options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : DEFAULT_TIMEOUT;
34
- const interval = (_options$interval = options === null || options === void 0 ? void 0 : options.interval) !== null && _options$interval !== void 0 ? _options$interval : DEFAULT_INTERVAL;
35
- const startTime = Date.now();
36
- return new Promise((resolve, reject) => {
37
- const rejectOrRerun = error => {
38
- if (Date.now() - startTime >= timeout) {
109
+ if (error) {
39
110
  reject(error);
40
- return;
111
+ } else {
112
+ // $FlowIgnore[incompatible-return] error and result are mutually exclusive
113
+ resolve(result);
114
+ }
115
+ }
116
+
117
+ function checkRealTimersCallback() {
118
+ if ((0, _timers.jestFakeTimersAreEnabled)()) {
119
+ const error = new Error(`Changed from using real timers to fake timers while using waitFor. This is not allowed and will result in very strange behavior. Please ensure you're awaiting all async things your test is doing before changing to fake timers. For more info, please go to https://github.com/testing-library/dom-testing-library/issues/830`);
120
+
121
+ if (stackTraceError) {
122
+ (0, _errors.copyStackTrace)(error, stackTraceError);
123
+ }
124
+
125
+ return reject(error);
126
+ } else {
127
+ return checkExpectation();
41
128
  }
129
+ }
42
130
 
43
- setTimeout(runExpectation, interval);
44
- };
131
+ function checkExpectation() {
132
+ if (promiseStatus === 'pending') return;
45
133
 
46
- function runExpectation() {
47
134
  try {
48
- const result = expectation();
49
- resolve(result);
135
+ const result = expectation(); // $FlowIgnore[incompatible-type]
136
+
137
+ if (typeof (result === null || result === void 0 ? void 0 : result.then) === 'function') {
138
+ promiseStatus = 'pending'; // eslint-disable-next-line promise/catch-or-return
139
+
140
+ result.then(resolvedValue => {
141
+ promiseStatus = 'resolved';
142
+ onDone(null, resolvedValue);
143
+ return;
144
+ }, rejectedValue => {
145
+ promiseStatus = 'rejected';
146
+ lastError = rejectedValue;
147
+ return;
148
+ });
149
+ } else {
150
+ onDone(null, result);
151
+ } // If `callback` throws, wait for the next mutation, interval, or timeout.
152
+
50
153
  } catch (error) {
51
- rejectOrRerun(error);
154
+ // Save the most recent callback error to reject the promise with it in the event of a timeout
155
+ lastError = error;
52
156
  }
53
157
  }
54
158
 
55
- setTimeout(runExpectation, 0);
159
+ function handleTimeout() {
160
+ let error;
161
+
162
+ if (lastError) {
163
+ error = lastError;
164
+
165
+ if (stackTraceError) {
166
+ (0, _errors.copyStackTrace)(error, stackTraceError);
167
+ }
168
+ } else {
169
+ error = new Error('Timed out in waitFor.');
170
+
171
+ if (stackTraceError) {
172
+ (0, _errors.copyStackTrace)(error, stackTraceError);
173
+ }
174
+ }
175
+
176
+ onDone(error, null);
177
+ }
56
178
  });
57
179
  }
58
180
 
59
181
  async function waitFor(expectation, options) {
182
+ // Being able to display a useful stack trace requires generating it before doing anything async
183
+ const stackTraceError = new _errors.ErrorWithStack('STACK_TRACE_ERROR', waitFor);
184
+ const optionsWithStackTrace = {
185
+ stackTraceError,
186
+ ...options
187
+ };
188
+
60
189
  if (!checkReactVersionAtLeast(16, 9)) {
61
- return waitForInternal(expectation, options);
190
+ return waitForInternal(expectation, optionsWithStackTrace);
62
191
  }
63
192
 
64
193
  let result; //$FlowFixMe: `act` has incorrect flow typing
65
194
 
66
195
  await (0, _act.default)(async () => {
67
- result = await waitForInternal(expectation, options);
196
+ result = await waitForInternal(expectation, optionsWithStackTrace);
68
197
  }); //$FlowFixMe: either we have result or `waitFor` threw error
69
198
 
70
199
  return result;
@@ -1,10 +1,21 @@
1
1
  // @flow
2
+ /* globals jest */
2
3
 
3
4
  import * as React from 'react';
4
5
  import act from './act';
5
- import { throwRemovedFunctionError } from './helpers/errors';
6
+ import {
7
+ ErrorWithStack,
8
+ throwRemovedFunctionError,
9
+ copyStackTrace,
10
+ } from './helpers/errors';
11
+ import {
12
+ setTimeout,
13
+ clearTimeout,
14
+ setImmediate,
15
+ jestFakeTimersAreEnabled,
16
+ } from './helpers/timers';
6
17
 
7
- const DEFAULT_TIMEOUT = 4500;
18
+ const DEFAULT_TIMEOUT = 1000;
8
19
  const DEFAULT_INTERVAL = 50;
9
20
 
10
21
  function checkReactVersionAtLeast(major: number, minor: number): boolean {
@@ -17,33 +28,159 @@ function checkReactVersionAtLeast(major: number, minor: number): boolean {
17
28
  export type WaitForOptions = {
18
29
  timeout?: number,
19
30
  interval?: number,
31
+ stackTraceError?: ErrorWithStack,
20
32
  };
21
33
 
22
34
  function waitForInternal<T>(
23
35
  expectation: () => T,
24
- options?: WaitForOptions
36
+ {
37
+ timeout = DEFAULT_TIMEOUT,
38
+ interval = DEFAULT_INTERVAL,
39
+ stackTraceError,
40
+ }: WaitForOptions
25
41
  ): Promise<T> {
26
- const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
27
- const interval = options?.interval ?? DEFAULT_INTERVAL;
28
- const startTime = Date.now();
42
+ if (typeof expectation !== 'function') {
43
+ throw new TypeError('Received `expectation` arg must be a function');
44
+ }
45
+
46
+ // eslint-disable-next-line no-async-promise-executor
47
+ return new Promise(async (resolve, reject) => {
48
+ let lastError, intervalId;
49
+ let finished = false;
50
+ let promiseStatus = 'idle';
51
+
52
+ const overallTimeoutTimer = setTimeout(handleTimeout, timeout);
53
+
54
+ const usingFakeTimers = jestFakeTimersAreEnabled();
55
+
56
+ if (usingFakeTimers) {
57
+ checkExpectation();
58
+ // this is a dangerous rule to disable because it could lead to an
59
+ // infinite loop. However, eslint isn't smart enough to know that we're
60
+ // setting finished inside `onDone` which will be called when we're done
61
+ // waiting or when we've timed out.
62
+ // eslint-disable-next-line no-unmodified-loop-condition
63
+ let fakeTimeRemaining = timeout;
64
+ while (!finished) {
65
+ if (!jestFakeTimersAreEnabled()) {
66
+ const error = new Error(
67
+ `Changed from using fake timers to real timers while using waitFor. This is not allowed and will result in very strange behavior. Please ensure you're awaiting all async things your test is doing before changing to real timers. For more info, please go to https://github.com/testing-library/dom-testing-library/issues/830`
68
+ );
69
+ if (stackTraceError) {
70
+ copyStackTrace(error, stackTraceError);
71
+ }
72
+ reject(error);
73
+ return;
74
+ }
75
+
76
+ // when fake timers are used we want to simulate the interval time passing
77
+ if (fakeTimeRemaining <= 0) {
78
+ return;
79
+ } else {
80
+ fakeTimeRemaining -= interval;
81
+ }
29
82
 
30
- return new Promise((resolve, reject) => {
31
- const rejectOrRerun = (error) => {
32
- if (Date.now() - startTime >= timeout) {
83
+ // we *could* (maybe should?) use `advanceTimersToNextTimer` but it's
84
+ // possible that could make this loop go on forever if someone is using
85
+ // third party code that's setting up recursive timers so rapidly that
86
+ // the user's timer's don't get a chance to resolve. So we'll advance
87
+ // by an interval instead. (We have a test for this case).
88
+ jest.advanceTimersByTime(interval);
89
+
90
+ // It's really important that checkExpectation is run *before* we flush
91
+ // in-flight promises. To be honest, I'm not sure why, and I can't quite
92
+ // think of a way to reproduce the problem in a test, but I spent
93
+ // an entire day banging my head against a wall on this.
94
+ checkExpectation();
95
+
96
+ // In this rare case, we *need* to wait for in-flight promises
97
+ // to resolve before continuing. We don't need to take advantage
98
+ // of parallelization so we're fine.
99
+ // https://stackoverflow.com/a/59243586/971592
100
+ // eslint-disable-next-line no-await-in-loop
101
+ await new Promise((resolve) => setImmediate(resolve));
102
+ }
103
+ } else {
104
+ intervalId = setInterval(checkRealTimersCallback, interval);
105
+ checkExpectation();
106
+ }
107
+
108
+ function onDone(error, result) {
109
+ finished = true;
110
+ clearTimeout(overallTimeoutTimer);
111
+
112
+ if (!usingFakeTimers) {
113
+ clearInterval(intervalId);
114
+ }
115
+
116
+ if (error) {
33
117
  reject(error);
34
- return;
118
+ } else {
119
+ // $FlowIgnore[incompatible-return] error and result are mutually exclusive
120
+ resolve(result);
35
121
  }
36
- setTimeout(runExpectation, interval);
37
- };
38
- function runExpectation() {
122
+ }
123
+
124
+ function checkRealTimersCallback() {
125
+ if (jestFakeTimersAreEnabled()) {
126
+ const error = new Error(
127
+ `Changed from using real timers to fake timers while using waitFor. This is not allowed and will result in very strange behavior. Please ensure you're awaiting all async things your test is doing before changing to fake timers. For more info, please go to https://github.com/testing-library/dom-testing-library/issues/830`
128
+ );
129
+ if (stackTraceError) {
130
+ copyStackTrace(error, stackTraceError);
131
+ }
132
+ return reject(error);
133
+ } else {
134
+ return checkExpectation();
135
+ }
136
+ }
137
+
138
+ function checkExpectation() {
139
+ if (promiseStatus === 'pending') return;
39
140
  try {
40
141
  const result = expectation();
41
- resolve(result);
142
+
143
+ // $FlowIgnore[incompatible-type]
144
+ if (typeof result?.then === 'function') {
145
+ promiseStatus = 'pending';
146
+ // eslint-disable-next-line promise/catch-or-return
147
+ result.then(
148
+ (resolvedValue) => {
149
+ promiseStatus = 'resolved';
150
+ onDone(null, resolvedValue);
151
+ return;
152
+ },
153
+ (rejectedValue) => {
154
+ promiseStatus = 'rejected';
155
+ lastError = rejectedValue;
156
+ return;
157
+ }
158
+ );
159
+ } else {
160
+ onDone(null, result);
161
+ }
162
+ // If `callback` throws, wait for the next mutation, interval, or timeout.
42
163
  } catch (error) {
43
- rejectOrRerun(error);
164
+ // Save the most recent callback error to reject the promise with it in the event of a timeout
165
+ lastError = error;
166
+ }
167
+ }
168
+
169
+ function handleTimeout() {
170
+ let error;
171
+ if (lastError) {
172
+ error = lastError;
173
+ if (stackTraceError) {
174
+ copyStackTrace(error, stackTraceError);
175
+ }
176
+ } else {
177
+ error = new Error('Timed out in waitFor.');
178
+ if (stackTraceError) {
179
+ copyStackTrace(error, stackTraceError);
180
+ }
44
181
  }
182
+ onDone(error, null);
45
183
  }
46
- setTimeout(runExpectation, 0);
47
184
  });
48
185
  }
49
186
 
@@ -51,15 +188,19 @@ export default async function waitFor<T>(
51
188
  expectation: () => T,
52
189
  options?: WaitForOptions
53
190
  ): Promise<T> {
191
+ // Being able to display a useful stack trace requires generating it before doing anything async
192
+ const stackTraceError = new ErrorWithStack('STACK_TRACE_ERROR', waitFor);
193
+ const optionsWithStackTrace = { stackTraceError, ...options };
194
+
54
195
  if (!checkReactVersionAtLeast(16, 9)) {
55
- return waitForInternal(expectation, options);
196
+ return waitForInternal(expectation, optionsWithStackTrace);
56
197
  }
57
198
 
58
199
  let result: T;
59
200
 
60
201
  //$FlowFixMe: `act` has incorrect flow typing
61
202
  await act(async () => {
62
- result = await waitForInternal(expectation, options);
203
+ result = await waitForInternal(expectation, optionsWithStackTrace);
63
204
  });
64
205
 
65
206
  //$FlowFixMe: either we have result or `waitFor` threw error
@@ -11,7 +11,9 @@ var _errors = require("./helpers/errors");
11
11
 
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
13
 
14
- const isRemoved = result => !result || Array.isArray(result) && !result.length;
14
+ function isRemoved(result) {
15
+ return !result || Array.isArray(result) && !result.length;
16
+ }
15
17
 
16
18
  async function waitForElementToBeRemoved(expectation, options) {
17
19
  // Created here so we get a nice stacktrace
@@ -2,8 +2,9 @@
2
2
  import waitFor, { type WaitForOptions } from './waitFor';
3
3
  import { ErrorWithStack } from './helpers/errors';
4
4
 
5
- const isRemoved = (result) =>
6
- !result || (Array.isArray(result) && !result.length);
5
+ function isRemoved<T>(result: T): boolean {
6
+ return !result || (Array.isArray(result) && !result.length);
7
+ }
7
8
 
8
9
  export default async function waitForElementToBeRemoved<T>(
9
10
  expectation: () => T,
package/build/within.js CHANGED
@@ -12,15 +12,13 @@ var _queryByAPI = require("./helpers/queryByAPI");
12
12
 
13
13
  var _findByAPI = require("./helpers/findByAPI");
14
14
 
15
- var _a11yAPI = _interopRequireDefault(require("./helpers/a11yAPI"));
16
-
17
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ var _a11yAPI = require("./helpers/a11yAPI");
18
16
 
19
17
  function within(instance) {
20
18
  return { ...(0, _getByAPI.getByAPI)(instance),
21
19
  ...(0, _queryByAPI.queryByAPI)(instance),
22
20
  ...(0, _findByAPI.findByAPI)(instance),
23
- ...(0, _a11yAPI.default)(instance)
21
+ ...(0, _a11yAPI.a11yAPI)(instance)
24
22
  };
25
23
  }
26
24
 
@@ -1,10 +1,12 @@
1
1
  // @flow
2
- import { getByAPI } from './helpers/getByAPI';
3
- import { queryByAPI } from './helpers/queryByAPI';
4
- import { findByAPI } from './helpers/findByAPI';
5
- import a11yAPI from './helpers/a11yAPI';
2
+ import { getByAPI, type GetByAPI } from './helpers/getByAPI';
3
+ import { queryByAPI, type QueryByAPI } from './helpers/queryByAPI';
4
+ import { findByAPI, type FindByAPI } from './helpers/findByAPI';
5
+ import { a11yAPI, type A11yAPI } from './helpers/a11yAPI';
6
6
 
7
- export function within(instance: ReactTestInstance) {
7
+ export function within(
8
+ instance: ReactTestInstance
9
+ ): { ...FindByAPI, ...QueryByAPI, ...GetByAPI, ...A11yAPI } {
8
10
  return {
9
11
  ...getByAPI(instance),
10
12
  ...queryByAPI(instance),
@@ -0,0 +1,10 @@
1
+ const reactNativePreset = require('react-native/jest-preset');
2
+
3
+ module.exports = {
4
+ ...reactNativePreset,
5
+ // this is needed to make modern fake timers work
6
+ // because the react-native preset overrides global.Promise
7
+ setupFiles: [require.resolve('./save-promise.js')]
8
+ .concat(reactNativePreset.setupFiles)
9
+ .concat([require.resolve('./restore-promise.js')]),
10
+ };
@@ -0,0 +1 @@
1
+ global.Promise = global.RNTL_ORIGINAL_PROMISE;
@@ -0,0 +1 @@
1
+ global.RNTL_ORIGINAL_PROMISE = Promise;