@testing-library/react-native 7.2.0 → 9.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  height="80"
5
5
  width="80"
6
6
  alt="owl"
7
- src="https://raw.githubusercontent.com/callstack/react-native-testing-library/master/website/static/img/owl.png"
7
+ src="https://raw.githubusercontent.com/callstack/react-native-testing-library/main/website/static/img/owl.png"
8
8
  />
9
9
  <p>Simple and complete React Native testing utilities that encourage good testing practices.</P>
10
10
  </div>
@@ -46,7 +46,7 @@ npm install --save-dev @testing-library/react-native
46
46
 
47
47
  This library has a peerDependencies listing for `react-test-renderer` and, of course, `react`. Make sure to install them too!
48
48
 
49
- > In order to properly use helpers for async tests (`findBy` queries and `waitFor`) you need at least React >=16.9.0 (featuring async `act`) or React Native >=0.60 (which comes with React >=16.9.0).
49
+ > In order to properly use helpers for async tests (`findBy` queries and `waitFor`) you need at least React >=16.9.0 (featuring async `act`) or React Native >=0.61 (which comes with React >=16.9.0).
50
50
 
51
51
  ### Additional Jest matchers
52
52
 
@@ -73,6 +73,24 @@ Then automatically add it to your jest tests by using `setupFilesAfterEnv` optio
73
73
  }
74
74
  ```
75
75
 
76
+ ### Custom Jest Preset
77
+
78
+ > **important** if you use "modern" Fake Timers
79
+
80
+ We generally advise to use the "react-native" preset when testing with this library. However, if you use ["modern" Fake Timers](https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers) (default since Jest 27), you'll need to apply our custom Jest preset or awaiting promises, like `waitFor`, will timeout.
81
+
82
+ This is a [known issue](https://github.com/facebook/react-native/issues/29303). It happens because React Native's Jest preset overrides native Promise. Our preset restores it to defaults, which is not a problem in most apps out there.
83
+
84
+ Here's how you apply a custom preset in your Jest config:
85
+
86
+ ```json
87
+ {
88
+ "preset": "@testing-library/react-native"
89
+ }
90
+ ```
91
+
92
+ If this doesn't work for you, please fall back to using "legacy" fake timers.
93
+
76
94
  ### Flow
77
95
 
78
96
  Note for [Flow](https://flow.org) users – you'll also need to install typings for `react-test-renderer`:
@@ -108,7 +126,7 @@ test('form submits two answers', () => {
108
126
  });
109
127
  ```
110
128
 
111
- You can find the source of `QuestionsBoard` component and this example [here](https://github.com/callstack/react-native-testing-library/blob/master/src/__tests__/questionsBoard.test.js).
129
+ You can find the source of `QuestionsBoard` component and this example [here](https://github.com/callstack/react-native-testing-library/blob/main/src/__tests__/questionsBoard.test.js).
112
130
 
113
131
  ## API / Usage
114
132
 
@@ -135,6 +153,8 @@ The [public API](https://callstack.github.io/react-native-testing-library/docs/a
135
153
 
136
154
  React Native Testing Library is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack](https://callstack.com) 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!
137
155
 
156
+ 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! 🔥
157
+
138
158
  ---
139
159
 
140
160
  Supported and used by [Rally Health](https://www.rallyhealth.com/careers-home).
@@ -7,8 +7,6 @@ exports.default = void 0;
7
7
 
8
8
  var _act = _interopRequireDefault(require("./act"));
9
9
 
10
- var _errors = require("./helpers/errors");
11
-
12
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
11
 
14
12
  const isHostElement = element => {
@@ -50,22 +48,16 @@ const isEventEnabled = (element, touchResponder) => {
50
48
  return touchStart === undefined && touchMove === undefined;
51
49
  };
52
50
 
53
- const findEventHandler = (element, eventName, callsite, nearestTouchResponder, hasDescendandHandler) => {
51
+ const findEventHandler = (element, eventName, callsite, nearestTouchResponder) => {
54
52
  const touchResponder = isTouchResponder(element) ? element : nearestTouchResponder;
55
53
  const handler = getEventHandler(element, eventName);
56
- if (handler && isEventEnabled(element, touchResponder)) return handler; // Do not bubble event to the root element
57
-
58
- const hasHandler = handler != null || hasDescendandHandler;
54
+ if (handler && isEventEnabled(element, touchResponder)) return handler;
59
55
 
60
56
  if (element.parent === null || element.parent.parent === null) {
61
- if (hasHandler) {
62
- return null;
63
- } else {
64
- throw new _errors.ErrorWithStack(`No handler function found for event: "${eventName}"`, callsite || invokeEvent);
65
- }
57
+ return null;
66
58
  }
67
59
 
68
- return findEventHandler(element.parent, eventName, callsite, touchResponder, hasHandler);
60
+ return findEventHandler(element.parent, eventName, callsite, touchResponder);
69
61
  };
70
62
 
71
63
  const getEventHandler = (element, eventName) => {
@@ -98,7 +90,7 @@ const invokeEvent = (element, eventName, callsite, ...data) => {
98
90
 
99
91
  const toEventHandlerName = eventName => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
100
92
 
101
- const pressHandler = element => invokeEvent(element, 'press', pressHandler);
93
+ const pressHandler = (element, ...data) => invokeEvent(element, 'press', pressHandler, ...data);
102
94
 
103
95
  const changeTextHandler = (element, ...data) => invokeEvent(element, 'changeText', changeTextHandler, ...data);
104
96
 
@@ -1,6 +1,5 @@
1
1
  // @flow
2
2
  import act from './act';
3
- import { ErrorWithStack } from './helpers/errors';
4
3
 
5
4
  const isHostElement = (element?: ReactTestInstance) => {
6
5
  return typeof element?.type === 'string';
@@ -53,8 +52,7 @@ const findEventHandler = (
53
52
  element: ReactTestInstance,
54
53
  eventName: string,
55
54
  callsite?: any,
56
- nearestTouchResponder?: ReactTestInstance,
57
- hasDescendandHandler?: boolean
55
+ nearestTouchResponder?: ReactTestInstance
58
56
  ) => {
59
57
  const touchResponder = isTouchResponder(element)
60
58
  ? element
@@ -63,26 +61,11 @@ const findEventHandler = (
63
61
  const handler = getEventHandler(element, eventName);
64
62
  if (handler && isEventEnabled(element, touchResponder)) return handler;
65
63
 
66
- // Do not bubble event to the root element
67
- const hasHandler = handler != null || hasDescendandHandler;
68
64
  if (element.parent === null || element.parent.parent === null) {
69
- if (hasHandler) {
70
- return null;
71
- } else {
72
- throw new ErrorWithStack(
73
- `No handler function found for event: "${eventName}"`,
74
- callsite || invokeEvent
75
- );
76
- }
65
+ return null;
77
66
  }
78
67
 
79
- return findEventHandler(
80
- element.parent,
81
- eventName,
82
- callsite,
83
- touchResponder,
84
- hasHandler
85
- );
68
+ return findEventHandler(element.parent, eventName, callsite, touchResponder);
86
69
  };
87
70
 
88
71
  const getEventHandler = (element: ReactTestInstance, eventName: string) => {
@@ -122,8 +105,8 @@ const invokeEvent = (
122
105
  const toEventHandlerName = (eventName: string) =>
123
106
  `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
124
107
 
125
- const pressHandler = (element: ReactTestInstance): void =>
126
- invokeEvent(element, 'press', pressHandler);
108
+ const pressHandler = (element: ReactTestInstance, ...data: Array<any>): void =>
109
+ invokeEvent(element, 'press', pressHandler, ...data);
127
110
  const changeTextHandler = (
128
111
  element: ReactTestInstance,
129
112
  ...data: Array<any>
@@ -8,6 +8,8 @@ exports.flushMicroTasks = flushMicroTasks;
8
8
 
9
9
  var _errors = require("./helpers/errors");
10
10
 
11
+ var _timers = require("./helpers/timers");
12
+
11
13
  /**
12
14
  * Wait for microtasks queue to flush
13
15
  */
@@ -21,7 +23,7 @@ function flushMicroTasks() {
21
23
  // using "thenable" instead of a Promise, because otherwise it breaks when
22
24
  // using "modern" fake timers
23
25
  then(resolve) {
24
- setImmediate(resolve);
26
+ (0, _timers.setImmediate)(resolve);
25
27
  }
26
28
 
27
29
  };
@@ -1,5 +1,6 @@
1
1
  // @flow
2
2
  import { printDeprecationWarning } from './helpers/errors';
3
+ import { setImmediate } from './helpers/timers';
3
4
 
4
5
  type Thenable<T> = { then: (() => T) => mixed };
5
6
 
@@ -5,27 +5,33 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.queryByDisplayValue = exports.queryAllByDisplayValue = exports.getByDisplayValue = exports.getAllByDisplayValue = exports.findByDisplayValue = exports.findAllByDisplayValue = void 0;
7
7
 
8
+ var _matches = require("../matches");
9
+
8
10
  var _makeQueries = require("./makeQueries");
9
11
 
10
12
  var _filterNodeByType = require("./filterNodeByType");
11
13
 
12
14
  var _errors = require("./errors");
13
15
 
14
- const getTextInputNodeByDisplayValue = (node, value) => {
16
+ const getTextInputNodeByDisplayValue = (node, value, options = {}) => {
15
17
  try {
16
18
  const {
17
19
  TextInput
18
20
  } = require('react-native');
19
21
 
22
+ const {
23
+ exact,
24
+ normalizer
25
+ } = options;
20
26
  const nodeValue = node.props.value !== undefined ? node.props.value : node.props.defaultValue;
21
- return (0, _filterNodeByType.filterNodeByType)(node, TextInput) && (typeof value === 'string' ? value === nodeValue : value.test(nodeValue));
27
+ return (0, _filterNodeByType.filterNodeByType)(node, TextInput) && (0, _matches.matches)(value, nodeValue, normalizer, exact);
22
28
  } catch (error) {
23
29
  throw (0, _errors.createLibraryNotSupportedError)(error);
24
30
  }
25
31
  };
26
32
 
27
- const queryAllByDisplayValue = instance => function queryAllByDisplayValueFn(displayValue) {
28
- return instance.findAll(node => getTextInputNodeByDisplayValue(node, displayValue));
33
+ const queryAllByDisplayValue = instance => function queryAllByDisplayValueFn(displayValue, queryOptions) {
34
+ return instance.findAll(node => getTextInputNodeByDisplayValue(node, displayValue, queryOptions));
29
35
  };
30
36
 
31
37
  exports.queryAllByDisplayValue = queryAllByDisplayValue;
@@ -1,19 +1,26 @@
1
1
  // @flow
2
+ import { matches } from '../matches';
2
3
  import { makeQueries } from './makeQueries';
3
4
  import type { Queries } from './makeQueries';
4
5
  import { filterNodeByType } from './filterNodeByType';
5
6
  import { createLibraryNotSupportedError } from './errors';
7
+ import type { TextMatchOptions } from './byText';
6
8
 
7
- const getTextInputNodeByDisplayValue = (node, value) => {
9
+ const getTextInputNodeByDisplayValue = (
10
+ node,
11
+ value,
12
+ options?: TextMatchOptions = {}
13
+ ) => {
8
14
  try {
9
15
  const { TextInput } = require('react-native');
16
+ const { exact, normalizer } = options;
10
17
  const nodeValue =
11
18
  node.props.value !== undefined
12
19
  ? node.props.value
13
20
  : node.props.defaultValue;
14
21
  return (
15
22
  filterNodeByType(node, TextInput) &&
16
- (typeof value === 'string' ? value === nodeValue : value.test(nodeValue))
23
+ matches(value, nodeValue, normalizer, exact)
17
24
  );
18
25
  } catch (error) {
19
26
  throw createLibraryNotSupportedError(error);
@@ -22,10 +29,13 @@ const getTextInputNodeByDisplayValue = (node, value) => {
22
29
 
23
30
  const queryAllByDisplayValue = (
24
31
  instance: ReactTestInstance
25
- ): ((displayValue: string | RegExp) => Array<ReactTestInstance>) =>
26
- function queryAllByDisplayValueFn(displayValue) {
32
+ ): ((
33
+ displayValue: string | RegExp,
34
+ queryOptions?: TextMatchOptions
35
+ ) => Array<ReactTestInstance>) =>
36
+ function queryAllByDisplayValueFn(displayValue, queryOptions) {
27
37
  return instance.findAll((node) =>
28
- getTextInputNodeByDisplayValue(node, displayValue)
38
+ getTextInputNodeByDisplayValue(node, displayValue, queryOptions)
29
39
  );
30
40
  };
31
41
 
@@ -5,26 +5,32 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.queryByPlaceholderText = exports.queryAllByPlaceholderText = exports.getByPlaceholderText = exports.getAllByPlaceholderText = exports.findByPlaceholderText = exports.findAllByPlaceholderText = void 0;
7
7
 
8
+ var _matches = require("../matches");
9
+
8
10
  var _makeQueries = require("./makeQueries");
9
11
 
10
12
  var _filterNodeByType = require("./filterNodeByType");
11
13
 
12
14
  var _errors = require("./errors");
13
15
 
14
- const getTextInputNodeByPlaceholderText = (node, placeholder) => {
16
+ const getTextInputNodeByPlaceholderText = (node, placeholder, options = {}) => {
15
17
  try {
16
18
  const {
17
19
  TextInput
18
20
  } = require('react-native');
19
21
 
20
- return (0, _filterNodeByType.filterNodeByType)(node, TextInput) && (typeof placeholder === 'string' ? placeholder === node.props.placeholder : placeholder.test(node.props.placeholder));
22
+ const {
23
+ exact,
24
+ normalizer
25
+ } = options;
26
+ return (0, _filterNodeByType.filterNodeByType)(node, TextInput) && (0, _matches.matches)(placeholder, node.props.placeholder, normalizer, exact);
21
27
  } catch (error) {
22
28
  throw (0, _errors.createLibraryNotSupportedError)(error);
23
29
  }
24
30
  };
25
31
 
26
- const queryAllByPlaceholderText = instance => function queryAllByPlaceholderFn(placeholder) {
27
- return instance.findAll(node => getTextInputNodeByPlaceholderText(node, placeholder));
32
+ const queryAllByPlaceholderText = instance => function queryAllByPlaceholderFn(placeholder, queryOptions) {
33
+ return instance.findAll(node => getTextInputNodeByPlaceholderText(node, placeholder, queryOptions));
28
34
  };
29
35
 
30
36
  exports.queryAllByPlaceholderText = queryAllByPlaceholderText;
@@ -1,17 +1,22 @@
1
1
  // @flow
2
+ import { matches } from '../matches';
2
3
  import { makeQueries } from './makeQueries';
3
4
  import type { Queries } from './makeQueries';
4
5
  import { filterNodeByType } from './filterNodeByType';
5
6
  import { createLibraryNotSupportedError } from './errors';
7
+ import type { TextMatchOptions } from './byText';
6
8
 
7
- const getTextInputNodeByPlaceholderText = (node, placeholder) => {
9
+ const getTextInputNodeByPlaceholderText = (
10
+ node,
11
+ placeholder,
12
+ options?: TextMatchOptions = {}
13
+ ) => {
8
14
  try {
9
15
  const { TextInput } = require('react-native');
16
+ const { exact, normalizer } = options;
10
17
  return (
11
18
  filterNodeByType(node, TextInput) &&
12
- (typeof placeholder === 'string'
13
- ? placeholder === node.props.placeholder
14
- : placeholder.test(node.props.placeholder))
19
+ matches(placeholder, node.props.placeholder, normalizer, exact)
15
20
  );
16
21
  } catch (error) {
17
22
  throw createLibraryNotSupportedError(error);
@@ -20,10 +25,13 @@ const getTextInputNodeByPlaceholderText = (node, placeholder) => {
20
25
 
21
26
  const queryAllByPlaceholderText = (
22
27
  instance: ReactTestInstance
23
- ): ((placeholder: string | RegExp) => Array<ReactTestInstance>) =>
24
- function queryAllByPlaceholderFn(placeholder) {
28
+ ): ((
29
+ placeholder: string | RegExp,
30
+ queryOptions?: TextMatchOptions
31
+ ) => Array<ReactTestInstance>) =>
32
+ function queryAllByPlaceholderFn(placeholder, queryOptions) {
25
33
  return instance.findAll((node) =>
26
- getTextInputNodeByPlaceholderText(node, placeholder)
34
+ getTextInputNodeByPlaceholderText(node, placeholder, queryOptions)
27
35
  );
28
36
  };
29
37
 
@@ -5,14 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.queryByTestId = exports.queryAllByTestId = exports.getByTestId = exports.getAllByTestId = exports.findByTestId = exports.findAllByTestId = void 0;
7
7
 
8
+ var _matches = require("../matches");
9
+
8
10
  var _makeQueries = require("./makeQueries");
9
11
 
10
- const getNodeByTestId = (node, testID) => {
11
- return typeof testID === 'string' ? testID === node.props.testID : testID.test(node.props.testID);
12
+ const getNodeByTestId = (node, testID, options = {}) => {
13
+ const {
14
+ exact,
15
+ normalizer
16
+ } = options;
17
+ return (0, _matches.matches)(testID, node.props.testID, normalizer, exact);
12
18
  };
13
19
 
14
- const queryAllByTestId = instance => function queryAllByTestIdFn(testId) {
15
- const results = instance.findAll(node => getNodeByTestId(node, testId)).filter(element => typeof element.type === 'string');
20
+ const queryAllByTestId = instance => function queryAllByTestIdFn(testId, queryOptions) {
21
+ const results = instance.findAll(node => getNodeByTestId(node, testId, queryOptions)).filter(element => typeof element.type === 'string');
16
22
  return results;
17
23
  };
18
24
 
@@ -1,19 +1,23 @@
1
1
  // @flow
2
+ import { matches } from '../matches';
2
3
  import { makeQueries } from './makeQueries';
3
4
  import type { Queries } from './makeQueries';
5
+ import type { TextMatchOptions } from './byText';
4
6
 
5
- const getNodeByTestId = (node, testID) => {
6
- return typeof testID === 'string'
7
- ? testID === node.props.testID
8
- : testID.test(node.props.testID);
7
+ const getNodeByTestId = (node, testID, options?: TextMatchOptions = {}) => {
8
+ const { exact, normalizer } = options;
9
+ return matches(testID, node.props.testID, normalizer, exact);
9
10
  };
10
11
 
11
12
  const queryAllByTestId = (
12
13
  instance: ReactTestInstance
13
- ): ((testId: string | RegExp) => Array<ReactTestInstance>) =>
14
- function queryAllByTestIdFn(testId) {
14
+ ): ((
15
+ testId: string | RegExp,
16
+ queryOptions?: TextMatchOptions
17
+ ) => Array<ReactTestInstance>) =>
18
+ function queryAllByTestIdFn(testId, queryOptions) {
15
19
  const results = instance
16
- .findAll((node) => getNodeByTestId(node, testId))
20
+ .findAll((node) => getNodeByTestId(node, testId, queryOptions))
17
21
  .filter((element) => typeof element.type === 'string');
18
22
 
19
23
  return results;
@@ -7,6 +7,8 @@ exports.queryByText = exports.queryAllByText = exports.getByText = exports.getAl
7
7
 
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
 
10
+ var _matches = require("../matches");
11
+
10
12
  var _makeQueries = require("./makeQueries");
11
13
 
12
14
  var _filterNodeByType = require("./filterNodeByType");
@@ -17,7 +19,8 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
17
19
 
18
20
  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; }
19
21
 
20
- const getChildrenAsText = (children, TextComponent, textContent = []) => {
22
+ const getChildrenAsText = (children, TextComponent) => {
23
+ const textContent = [];
21
24
  React.Children.forEach(children, child => {
22
25
  var _child$props;
23
26
 
@@ -40,13 +43,13 @@ const getChildrenAsText = (children, TextComponent, textContent = []) => {
40
43
  return;
41
44
  }
42
45
 
43
- getChildrenAsText(child.props.children, TextComponent, textContent);
46
+ getChildrenAsText(child.props.children, TextComponent);
44
47
  }
45
48
  });
46
49
  return textContent;
47
50
  };
48
51
 
49
- const getNodeByText = (node, text) => {
52
+ const getNodeByText = (node, text, options = {}) => {
50
53
  try {
51
54
  const {
52
55
  Text
@@ -59,7 +62,11 @@ const getNodeByText = (node, text) => {
59
62
 
60
63
  if (textChildren) {
61
64
  const textToTest = textChildren.join('');
62
- return typeof text === 'string' ? text === textToTest : text.test(textToTest);
65
+ const {
66
+ exact,
67
+ normalizer
68
+ } = options;
69
+ return (0, _matches.matches)(text, textToTest, normalizer, exact);
63
70
  }
64
71
  }
65
72
 
@@ -69,8 +76,8 @@ const getNodeByText = (node, text) => {
69
76
  }
70
77
  };
71
78
 
72
- const queryAllByText = instance => function queryAllByTextFn(text) {
73
- const results = instance.findAll(node => getNodeByText(node, text));
79
+ const queryAllByText = instance => function queryAllByTextFn(text, queryOptions) {
80
+ const results = instance.findAll(node => getNodeByText(node, text, queryOptions));
74
81
  return results;
75
82
  };
76
83
 
@@ -1,11 +1,19 @@
1
1
  // @flow
2
2
  import * as React from 'react';
3
+ import { matches } from '../matches';
4
+ import type { NormalizerFn } from '../matches';
3
5
  import { makeQueries } from './makeQueries';
4
6
  import type { Queries } from './makeQueries';
5
7
  import { filterNodeByType } from './filterNodeByType';
6
8
  import { createLibraryNotSupportedError } from './errors';
7
9
 
8
- const getChildrenAsText = (children, TextComponent, textContent = []) => {
10
+ export type TextMatchOptions = {
11
+ exact?: boolean,
12
+ normalizer?: NormalizerFn,
13
+ };
14
+
15
+ const getChildrenAsText = (children, TextComponent) => {
16
+ const textContent = [];
9
17
  React.Children.forEach(children, (child) => {
10
18
  if (typeof child === 'string') {
11
19
  textContent.push(child);
@@ -26,14 +34,18 @@ const getChildrenAsText = (children, TextComponent, textContent = []) => {
26
34
  return;
27
35
  }
28
36
 
29
- getChildrenAsText(child.props.children, TextComponent, textContent);
37
+ getChildrenAsText(child.props.children, TextComponent);
30
38
  }
31
39
  });
32
40
 
33
41
  return textContent;
34
42
  };
35
43
 
36
- const getNodeByText = (node, text: string | RegExp) => {
44
+ const getNodeByText = (
45
+ node,
46
+ text: string | RegExp,
47
+ options?: TextMatchOptions = {}
48
+ ) => {
37
49
  try {
38
50
  const { Text } = require('react-native');
39
51
  const isTextComponent = filterNodeByType(node, Text);
@@ -41,9 +53,8 @@ const getNodeByText = (node, text: string | RegExp) => {
41
53
  const textChildren = getChildrenAsText(node.props.children, Text);
42
54
  if (textChildren) {
43
55
  const textToTest = textChildren.join('');
44
- return typeof text === 'string'
45
- ? text === textToTest
46
- : text.test(textToTest);
56
+ const { exact, normalizer } = options;
57
+ return matches(text, textToTest, normalizer, exact);
47
58
  }
48
59
  }
49
60
  return false;
@@ -54,9 +65,14 @@ const getNodeByText = (node, text: string | RegExp) => {
54
65
 
55
66
  const queryAllByText = (
56
67
  instance: ReactTestInstance
57
- ): ((text: string | RegExp) => Array<ReactTestInstance>) =>
58
- function queryAllByTextFn(text) {
59
- const results = instance.findAll((node) => getNodeByText(node, text));
68
+ ): ((
69
+ text: string | RegExp,
70
+ queryOptions?: TextMatchOptions
71
+ ) => Array<ReactTestInstance>) =>
72
+ function queryAllByTextFn(text, queryOptions) {
73
+ const results = instance.findAll((node) =>
74
+ getNodeByText(node, text, queryOptions)
75
+ );
60
76
 
61
77
  return results;
62
78
  };
@@ -64,7 +64,8 @@ const warned = {};
64
64
  function printDeprecationWarning(functionName) {
65
65
  if (warned[functionName]) {
66
66
  return;
67
- }
67
+ } // eslint-disable-next-line no-console
68
+
68
69
 
69
70
  console.warn(`
70
71
  Deprecation Warning:
@@ -53,6 +53,7 @@ export function printDeprecationWarning(functionName: string) {
53
53
  return;
54
54
  }
55
55
 
56
+ // eslint-disable-next-line no-console
56
57
  console.warn(`
57
58
  Deprecation Warning:
58
59
  Use of ${functionName} is not recommended and will be deleted in future versions of @testing-library/react-native.
@@ -1,5 +1,6 @@
1
1
  // @flow
2
2
  import type { WaitForOptions } from '../waitFor';
3
+ import type { TextMatchOptions } from './byText';
3
4
  import { findAllByTestId, findByTestId } from './byTestId';
4
5
  import { findAllByText, findByText } from './byText';
5
6
  import {
@@ -12,36 +13,44 @@ import { throwRenamedFunctionError } from './errors';
12
13
  export type FindByAPI = {|
13
14
  findAllByDisplayValue: (
14
15
  value: string | RegExp,
16
+ queryOptions?: TextMatchOptions & WaitForOptions,
15
17
  waitForOptions?: WaitForOptions
16
18
  ) => Promise<Array<ReactTestInstance>>,
17
19
  findAllByPlaceholder: () => void,
18
20
  findAllByPlaceholderText: (
19
21
  placeholder: string | RegExp,
22
+ queryOptions?: TextMatchOptions & WaitForOptions,
20
23
  waitForOptions?: WaitForOptions
21
24
  ) => Promise<Array<ReactTestInstance>>,
22
25
  findAllByTestId: (
23
26
  testId: string | RegExp,
27
+ queryOptions?: TextMatchOptions & WaitForOptions,
24
28
  waitForOptions?: WaitForOptions
25
29
  ) => Promise<Array<ReactTestInstance>>,
26
30
  findAllByText: (
27
31
  text: string | RegExp,
32
+ queryOptions?: TextMatchOptions & WaitForOptions,
28
33
  waitForOptions?: WaitForOptions
29
34
  ) => Promise<Array<ReactTestInstance>>,
30
35
  findByDisplayValue: (
31
36
  value: string | RegExp,
37
+ queryOptions?: TextMatchOptions & WaitForOptions,
32
38
  waitForOptions?: WaitForOptions
33
39
  ) => Promise<ReactTestInstance>,
34
40
  findByPlaceholder: () => void,
35
41
  findByPlaceholderText: (
36
42
  placeholder: string | RegExp,
43
+ queryOptions?: TextMatchOptions & WaitForOptions,
37
44
  waitForOptions?: WaitForOptions
38
45
  ) => Promise<ReactTestInstance>,
39
46
  findByTestId: (
40
47
  testId: string | RegExp,
48
+ queryOptions?: TextMatchOptions & WaitForOptions,
41
49
  waitForOptions?: WaitForOptions
42
50
  ) => Promise<ReactTestInstance>,
43
51
  findByText: (
44
52
  text: string | RegExp,
53
+ queryOptions?: TextMatchOptions & WaitForOptions,
45
54
  waitForOptions?: WaitForOptions
46
55
  ) => Promise<ReactTestInstance>,
47
56
  |};
@@ -14,18 +14,41 @@ import {
14
14
  getByPlaceholderText,
15
15
  } from './byPlaceholderText';
16
16
  import { getAllByDisplayValue, getByDisplayValue } from './byDisplayValue';
17
+ import type { TextMatchOptions } from './byText';
17
18
 
18
19
  export type GetByAPI = {|
19
- getByText: (text: string | RegExp) => ReactTestInstance,
20
- getByPlaceholderText: (placeholder: string | RegExp) => ReactTestInstance,
21
- getByDisplayValue: (value: string | RegExp) => ReactTestInstance,
22
- getByTestId: (testID: string | RegExp) => ReactTestInstance,
23
- getAllByTestId: (testID: string | RegExp) => Array<ReactTestInstance>,
24
- getAllByText: (text: string | RegExp) => Array<ReactTestInstance>,
20
+ getByText: (
21
+ text: string | RegExp,
22
+ queryOptions?: TextMatchOptions
23
+ ) => ReactTestInstance,
24
+ getByPlaceholderText: (
25
+ placeholder: string | RegExp,
26
+ queryOptions?: TextMatchOptions
27
+ ) => ReactTestInstance,
28
+ getByDisplayValue: (
29
+ value: string | RegExp,
30
+ queryOptions?: TextMatchOptions
31
+ ) => ReactTestInstance,
32
+ getByTestId: (
33
+ testID: string | RegExp,
34
+ queryOptions?: TextMatchOptions
35
+ ) => ReactTestInstance,
36
+ getAllByTestId: (
37
+ testID: string | RegExp,
38
+ queryOptions?: TextMatchOptions
39
+ ) => Array<ReactTestInstance>,
40
+ getAllByText: (
41
+ text: string | RegExp,
42
+ queryOptions?: TextMatchOptions
43
+ ) => Array<ReactTestInstance>,
25
44
  getAllByPlaceholderText: (
26
- placeholder: string | RegExp
45
+ placeholder: string | RegExp,
46
+ queryOptions?: TextMatchOptions
47
+ ) => Array<ReactTestInstance>,
48
+ getAllByDisplayValue: (
49
+ value: string | RegExp,
50
+ queryOptions?: TextMatchOptions
27
51
  ) => Array<ReactTestInstance>,
28
- getAllByDisplayValue: (value: string | RegExp) => Array<ReactTestInstance>,
29
52
 
30
53
  // Unsafe aliases
31
54
  UNSAFE_getByType: <P>(type: React.ComponentType<P>) => ReactTestInstance,