@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.
- package/README.md +24 -4
- package/build/act.js.flow +2 -1
- package/build/fireEvent.js +24 -17
- package/build/fireEvent.js.flow +36 -28
- package/build/flushMicroTasks.js +3 -1
- package/build/flushMicroTasks.js.flow +1 -0
- package/build/helpers/a11yAPI.js +9 -10
- package/build/helpers/a11yAPI.js.flow +10 -12
- package/build/helpers/byDisplayValue.js +48 -0
- package/build/helpers/byDisplayValue.js.flow +56 -0
- package/build/helpers/byPlaceholderText.js +47 -0
- package/build/helpers/byPlaceholderText.js.flow +54 -0
- package/build/helpers/byTestId.js +36 -0
- package/build/helpers/byTestId.js.flow +46 -0
- package/build/helpers/byText.js +94 -0
- package/build/helpers/byText.js.flow +88 -0
- package/build/helpers/debugDeep.js +1 -1
- package/build/helpers/debugDeep.js.flow +1 -1
- package/build/helpers/debugShallow.js.flow +1 -1
- package/build/helpers/errors.js +6 -0
- package/build/helpers/errors.js.flow +10 -3
- package/build/helpers/filterNodeByType.js +10 -0
- package/build/helpers/filterNodeByType.js.flow +1 -0
- package/build/helpers/findByAPI.js +14 -46
- package/build/helpers/findByAPI.js.flow +43 -58
- package/build/helpers/format.js.flow +1 -1
- package/build/helpers/getByAPI.js +16 -184
- package/build/helpers/getByAPI.js.flow +52 -204
- package/build/helpers/{makeQuery.js → makeA11yQuery.js} +2 -2
- package/build/helpers/{makeQuery.js.flow → makeA11yQuery.js.flow} +5 -3
- package/build/helpers/makeQueries.js +78 -0
- package/build/helpers/makeQueries.js.flow +114 -0
- package/build/helpers/queryByAPI.js +16 -88
- package/build/helpers/queryByAPI.js.flow +57 -90
- package/build/helpers/timers.js +77 -0
- package/build/helpers/timers.js.flow +88 -0
- package/build/index.js +1 -0
- package/build/render.js +11 -4
- package/build/render.js.flow +32 -8
- package/build/shallow.js.flow +1 -1
- package/build/types.flow.js.flow +4 -0
- package/build/waitFor.js +148 -19
- package/build/waitFor.js.flow +159 -18
- package/build/waitForElementToBeRemoved.js +3 -1
- package/build/waitForElementToBeRemoved.js.flow +3 -2
- package/build/within.js +2 -4
- package/build/within.js.flow +7 -5
- package/jest-preset/index.js +10 -0
- package/jest-preset/restore-promise.js +1 -0
- package/jest-preset/save-promise.js +1 -0
- package/package.json +20 -15
- package/typings/index.d.ts +13 -4
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/
|
|
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.
|
|
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
|
|
|
@@ -64,7 +64,7 @@ yarn add --dev @testing-library/jest-native
|
|
|
64
64
|
npm install --save-dev @testing-library/jest-native
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
Then automatically add it to your jest tests by using `setupFilesAfterEnv` option in your Jest configuration (it's usually located either in `package.json` under `"jest"` key or in a `jest.config.
|
|
67
|
+
Then automatically add it to your jest tests by using `setupFilesAfterEnv` option in your Jest configuration (it's usually located either in `package.json` under `"jest"` key or in a `jest.config.json` file):
|
|
68
68
|
|
|
69
69
|
```json
|
|
70
70
|
{
|
|
@@ -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/
|
|
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).
|
package/build/act.js.flow
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import { act } from 'react-test-renderer';
|
|
3
|
+
import type { Thenable } from './types.flow';
|
|
3
4
|
|
|
4
5
|
const actMock = (callback: () => void) => {
|
|
5
6
|
callback();
|
|
6
7
|
};
|
|
7
8
|
|
|
8
|
-
export default act || actMock;
|
|
9
|
+
export default (act || actMock: (callback: () => void) => Thenable);
|
package/build/fireEvent.js
CHANGED
|
@@ -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 => {
|
|
@@ -25,32 +23,41 @@ const isTextInput = element => {
|
|
|
25
23
|
|
|
26
24
|
const isTouchResponder = element => {
|
|
27
25
|
if (!isHostElement(element)) return false;
|
|
28
|
-
return !!(element
|
|
26
|
+
return !!(element !== null && element !== void 0 && element.props.onStartShouldSetResponder) || isTextInput(element);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const isPointerEventEnabled = (element, isParent) => {
|
|
30
|
+
const parentCondition = isParent ? (element === null || element === void 0 ? void 0 : element.props.pointerEvents) === 'box-only' : (element === null || element === void 0 ? void 0 : element.props.pointerEvents) === 'box-none';
|
|
31
|
+
|
|
32
|
+
if ((element === null || element === void 0 ? void 0 : element.props.pointerEvents) === 'none' || parentCondition) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!(element !== null && element !== void 0 && element.parent)) return true;
|
|
37
|
+
return isPointerEventEnabled(element.parent, true);
|
|
29
38
|
};
|
|
30
39
|
|
|
31
40
|
const isEventEnabled = (element, touchResponder) => {
|
|
32
|
-
var _touchResponder$props, _touchResponder$props2;
|
|
41
|
+
var _touchResponder$props, _touchResponder$props2, _touchResponder$props3, _touchResponder$props4;
|
|
33
42
|
|
|
34
43
|
if (isTextInput(element)) return (element === null || element === void 0 ? void 0 : element.props.editable) !== false;
|
|
35
|
-
|
|
44
|
+
if (!isPointerEventEnabled(element)) return false;
|
|
45
|
+
const touchStart = touchResponder === null || touchResponder === void 0 ? void 0 : (_touchResponder$props = (_touchResponder$props2 = touchResponder.props).onStartShouldSetResponder) === null || _touchResponder$props === void 0 ? void 0 : _touchResponder$props.call(_touchResponder$props2);
|
|
46
|
+
const touchMove = touchResponder === null || touchResponder === void 0 ? void 0 : (_touchResponder$props3 = (_touchResponder$props4 = touchResponder.props).onMoveShouldSetResponder) === null || _touchResponder$props3 === void 0 ? void 0 : _touchResponder$props3.call(_touchResponder$props4);
|
|
47
|
+
if (touchStart || touchMove) return true;
|
|
48
|
+
return touchStart === undefined && touchMove === undefined;
|
|
36
49
|
};
|
|
37
50
|
|
|
38
|
-
const findEventHandler = (element, eventName, callsite, nearestTouchResponder
|
|
51
|
+
const findEventHandler = (element, eventName, callsite, nearestTouchResponder) => {
|
|
39
52
|
const touchResponder = isTouchResponder(element) ? element : nearestTouchResponder;
|
|
40
53
|
const handler = getEventHandler(element, eventName);
|
|
41
|
-
if (handler && isEventEnabled(element, touchResponder)) return handler;
|
|
42
|
-
|
|
43
|
-
const hasHandler = handler != null || hasDescendandHandler;
|
|
54
|
+
if (handler && isEventEnabled(element, touchResponder)) return handler;
|
|
44
55
|
|
|
45
56
|
if (element.parent === null || element.parent.parent === null) {
|
|
46
|
-
|
|
47
|
-
return null;
|
|
48
|
-
} else {
|
|
49
|
-
throw new _errors.ErrorWithStack(`No handler function found for event: "${eventName}"`, callsite || invokeEvent);
|
|
50
|
-
}
|
|
57
|
+
return null;
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
return findEventHandler(element.parent, eventName, callsite, touchResponder
|
|
60
|
+
return findEventHandler(element.parent, eventName, callsite, touchResponder);
|
|
54
61
|
};
|
|
55
62
|
|
|
56
63
|
const getEventHandler = (element, eventName) => {
|
|
@@ -71,7 +78,7 @@ const invokeEvent = (element, eventName, callsite, ...data) => {
|
|
|
71
78
|
const handler = findEventHandler(element, eventName, callsite);
|
|
72
79
|
|
|
73
80
|
if (!handler) {
|
|
74
|
-
return
|
|
81
|
+
return;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
let returnValue;
|
|
@@ -83,7 +90,7 @@ const invokeEvent = (element, eventName, callsite, ...data) => {
|
|
|
83
90
|
|
|
84
91
|
const toEventHandlerName = eventName => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
|
|
85
92
|
|
|
86
|
-
const pressHandler = element => invokeEvent(element, 'press', pressHandler);
|
|
93
|
+
const pressHandler = (element, ...data) => invokeEvent(element, 'press', pressHandler, ...data);
|
|
87
94
|
|
|
88
95
|
const changeTextHandler = (element, ...data) => invokeEvent(element, 'changeText', changeTextHandler, ...data);
|
|
89
96
|
|
package/build/fireEvent.js.flow
CHANGED
|
@@ -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';
|
|
@@ -17,21 +16,43 @@ const isTouchResponder = (element?: ReactTestInstance) => {
|
|
|
17
16
|
return !!element?.props.onStartShouldSetResponder || isTextInput(element);
|
|
18
17
|
};
|
|
19
18
|
|
|
19
|
+
const isPointerEventEnabled = (
|
|
20
|
+
element?: ReactTestInstance,
|
|
21
|
+
isParent?: boolean
|
|
22
|
+
) => {
|
|
23
|
+
const parentCondition = isParent
|
|
24
|
+
? element?.props.pointerEvents === 'box-only'
|
|
25
|
+
: element?.props.pointerEvents === 'box-none';
|
|
26
|
+
|
|
27
|
+
if (element?.props.pointerEvents === 'none' || parentCondition) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!element?.parent) return true;
|
|
32
|
+
|
|
33
|
+
return isPointerEventEnabled(element.parent, true);
|
|
34
|
+
};
|
|
35
|
+
|
|
20
36
|
const isEventEnabled = (
|
|
21
37
|
element?: ReactTestInstance,
|
|
22
38
|
touchResponder?: ReactTestInstance
|
|
23
39
|
) => {
|
|
24
40
|
if (isTextInput(element)) return element?.props.editable !== false;
|
|
41
|
+
if (!isPointerEventEnabled(element)) return false;
|
|
42
|
+
|
|
43
|
+
const touchStart = touchResponder?.props.onStartShouldSetResponder?.();
|
|
44
|
+
const touchMove = touchResponder?.props.onMoveShouldSetResponder?.();
|
|
25
45
|
|
|
26
|
-
|
|
46
|
+
if (touchStart || touchMove) return true;
|
|
47
|
+
|
|
48
|
+
return touchStart === undefined && touchMove === undefined;
|
|
27
49
|
};
|
|
28
50
|
|
|
29
51
|
const findEventHandler = (
|
|
30
52
|
element: ReactTestInstance,
|
|
31
53
|
eventName: string,
|
|
32
54
|
callsite?: any,
|
|
33
|
-
nearestTouchResponder?: ReactTestInstance
|
|
34
|
-
hasDescendandHandler?: boolean
|
|
55
|
+
nearestTouchResponder?: ReactTestInstance
|
|
35
56
|
) => {
|
|
36
57
|
const touchResponder = isTouchResponder(element)
|
|
37
58
|
? element
|
|
@@ -40,26 +61,11 @@ const findEventHandler = (
|
|
|
40
61
|
const handler = getEventHandler(element, eventName);
|
|
41
62
|
if (handler && isEventEnabled(element, touchResponder)) return handler;
|
|
42
63
|
|
|
43
|
-
// Do not bubble event to the root element
|
|
44
|
-
const hasHandler = handler != null || hasDescendandHandler;
|
|
45
64
|
if (element.parent === null || element.parent.parent === null) {
|
|
46
|
-
|
|
47
|
-
return null;
|
|
48
|
-
} else {
|
|
49
|
-
throw new ErrorWithStack(
|
|
50
|
-
`No handler function found for event: "${eventName}"`,
|
|
51
|
-
callsite || invokeEvent
|
|
52
|
-
);
|
|
53
|
-
}
|
|
65
|
+
return null;
|
|
54
66
|
}
|
|
55
67
|
|
|
56
|
-
return findEventHandler(
|
|
57
|
-
element.parent,
|
|
58
|
-
eventName,
|
|
59
|
-
callsite,
|
|
60
|
-
touchResponder,
|
|
61
|
-
hasHandler
|
|
62
|
-
);
|
|
68
|
+
return findEventHandler(element.parent, eventName, callsite, touchResponder);
|
|
63
69
|
};
|
|
64
70
|
|
|
65
71
|
const getEventHandler = (element: ReactTestInstance, eventName: string) => {
|
|
@@ -84,7 +90,7 @@ const invokeEvent = (
|
|
|
84
90
|
const handler = findEventHandler(element, eventName, callsite);
|
|
85
91
|
|
|
86
92
|
if (!handler) {
|
|
87
|
-
return
|
|
93
|
+
return;
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
let returnValue;
|
|
@@ -99,18 +105,20 @@ const invokeEvent = (
|
|
|
99
105
|
const toEventHandlerName = (eventName: string) =>
|
|
100
106
|
`on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
|
|
101
107
|
|
|
102
|
-
const pressHandler = (element: ReactTestInstance) =>
|
|
103
|
-
invokeEvent(element, 'press', pressHandler);
|
|
104
|
-
const changeTextHandler = (
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
const pressHandler = (element: ReactTestInstance, ...data: Array<any>): void =>
|
|
109
|
+
invokeEvent(element, 'press', pressHandler, ...data);
|
|
110
|
+
const changeTextHandler = (
|
|
111
|
+
element: ReactTestInstance,
|
|
112
|
+
...data: Array<any>
|
|
113
|
+
): void => invokeEvent(element, 'changeText', changeTextHandler, ...data);
|
|
114
|
+
const scrollHandler = (element: ReactTestInstance, ...data: Array<any>): void =>
|
|
107
115
|
invokeEvent(element, 'scroll', scrollHandler, ...data);
|
|
108
116
|
|
|
109
117
|
const fireEvent = (
|
|
110
118
|
element: ReactTestInstance,
|
|
111
119
|
eventName: string,
|
|
112
120
|
...data: Array<any>
|
|
113
|
-
) => invokeEvent(element, eventName, fireEvent, ...data);
|
|
121
|
+
): void => invokeEvent(element, eventName, fireEvent, ...data);
|
|
114
122
|
|
|
115
123
|
fireEvent.press = pressHandler;
|
|
116
124
|
fireEvent.changeText = changeTextHandler;
|
package/build/flushMicroTasks.js
CHANGED
|
@@ -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
|
};
|
package/build/helpers/a11yAPI.js
CHANGED
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.matchStringValue = matchStringValue;
|
|
7
7
|
exports.matchArrayValue = matchArrayValue;
|
|
8
8
|
exports.matchObject = matchObject;
|
|
9
|
-
exports.
|
|
9
|
+
exports.a11yAPI = void 0;
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _makeA11yQuery = _interopRequireDefault(require("./makeA11yQuery"));
|
|
12
12
|
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
14
|
|
|
@@ -40,7 +40,7 @@ function matchObject(prop, matcher) {
|
|
|
40
40
|
return prop ? Object.keys(matcher).length !== 0 && Object.keys(prop).length !== 0 && !Object.keys(matcher).some(key => prop[key] !== matcher[key]) : false;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const a11yAPI = instance => ({ ...(0,
|
|
43
|
+
const a11yAPI = instance => ({ ...(0, _makeA11yQuery.default)('accessibilityLabel', {
|
|
44
44
|
getBy: ['getByA11yLabel', 'getByAccessibilityLabel', 'getByLabelText'],
|
|
45
45
|
getAllBy: ['getAllByA11yLabel', 'getAllByAccessibilityLabel', 'getAllByLabelText'],
|
|
46
46
|
queryBy: ['queryByA11yLabel', 'queryByAccessibilityLabel', 'queryByLabelText'],
|
|
@@ -48,7 +48,7 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
48
48
|
findBy: ['findByA11yLabel', 'findByAccessibilityLabel', 'findByLabelText'],
|
|
49
49
|
findAllBy: ['findAllByA11yLabel', 'findAllByAccessibilityLabel', 'findAllByLabelText']
|
|
50
50
|
}, matchStringValue)(instance),
|
|
51
|
-
...(0,
|
|
51
|
+
...(0, _makeA11yQuery.default)('accessibilityHint', {
|
|
52
52
|
getBy: ['getByA11yHint', 'getByAccessibilityHint', 'getByHintText'],
|
|
53
53
|
getAllBy: ['getAllByA11yHint', 'getAllByAccessibilityHint', 'getAllByHintText'],
|
|
54
54
|
queryBy: ['queryByA11yHint', 'queryByAccessibilityHint', 'queryByHintText'],
|
|
@@ -56,7 +56,7 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
56
56
|
findBy: ['findByA11yHint', 'findByAccessibilityHint', 'findByHintText'],
|
|
57
57
|
findAllBy: ['findAllByA11yHint', 'findAllByAccessibilityHint', 'findAllByHintText']
|
|
58
58
|
}, matchStringValue)(instance),
|
|
59
|
-
...(0,
|
|
59
|
+
...(0, _makeA11yQuery.default)('accessibilityRole', {
|
|
60
60
|
getBy: ['getByA11yRole', 'getByAccessibilityRole', 'getByRole'],
|
|
61
61
|
getAllBy: ['getAllByA11yRole', 'getAllByAccessibilityRole', 'getAllByRole'],
|
|
62
62
|
queryBy: ['queryByA11yRole', 'queryByAccessibilityRole', 'queryByRole'],
|
|
@@ -64,7 +64,7 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
64
64
|
findBy: ['findByA11yRole', 'findByAccessibilityRole', 'findByRole'],
|
|
65
65
|
findAllBy: ['findAllByA11yRole', 'findAllByAccessibilityRole', 'findAllByRole']
|
|
66
66
|
}, matchStringValue)(instance),
|
|
67
|
-
...(0,
|
|
67
|
+
...(0, _makeA11yQuery.default)('accessibilityStates', {
|
|
68
68
|
getBy: ['getByA11yStates', 'getByAccessibilityStates'],
|
|
69
69
|
getAllBy: ['getAllByA11yStates', 'getAllByAccessibilityStates'],
|
|
70
70
|
queryBy: ['queryByA11yStates', 'queryByAccessibilityStates'],
|
|
@@ -72,7 +72,7 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
72
72
|
findBy: ['findByA11yStates', 'findByAccessibilityStates'],
|
|
73
73
|
findAllBy: ['findAllByA11yStates', 'findAllByAccessibilityStates']
|
|
74
74
|
}, matchArrayValue)(instance),
|
|
75
|
-
...(0,
|
|
75
|
+
...(0, _makeA11yQuery.default)('accessibilityState', {
|
|
76
76
|
getBy: ['getByA11yState', 'getByAccessibilityState'],
|
|
77
77
|
getAllBy: ['getAllByA11yState', 'getAllByAccessibilityState'],
|
|
78
78
|
queryBy: ['queryByA11yState', 'queryByAccessibilityState'],
|
|
@@ -80,7 +80,7 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
80
80
|
findBy: ['findByA11yState', 'findByAccessibilityState'],
|
|
81
81
|
findAllBy: ['findAllByA11yState', 'findAllByAccessibilityState']
|
|
82
82
|
}, matchObject)(instance),
|
|
83
|
-
...(0,
|
|
83
|
+
...(0, _makeA11yQuery.default)('accessibilityValue', {
|
|
84
84
|
getBy: ['getByA11yValue', 'getByAccessibilityValue'],
|
|
85
85
|
getAllBy: ['getAllByA11yValue', 'getAllByAccessibilityValue'],
|
|
86
86
|
queryBy: ['queryByA11yValue', 'queryByAccessibilityValue'],
|
|
@@ -90,5 +90,4 @@ const a11yAPI = instance => ({ ...(0, _makeQuery.default)('accessibilityLabel',
|
|
|
90
90
|
}, matchObject)(instance)
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
exports.default = _default;
|
|
93
|
+
exports.a11yAPI = a11yAPI;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import type { A11yRole, A11yStates, A11yState, A11yValue } from '../types.flow';
|
|
3
3
|
import type { WaitForOptions } from '../waitFor';
|
|
4
|
-
import
|
|
4
|
+
import makeA11yQuery from './makeA11yQuery';
|
|
5
5
|
|
|
6
6
|
type GetReturn = ReactTestInstance;
|
|
7
7
|
type GetAllReturn = Array<ReactTestInstance>;
|
|
8
8
|
type QueryReturn = ReactTestInstance | null;
|
|
9
|
-
type QueryAllReturn = Array<ReactTestInstance
|
|
9
|
+
type QueryAllReturn = Array<ReactTestInstance>;
|
|
10
10
|
type FindReturn = Promise<GetReturn>;
|
|
11
11
|
type FindAllReturn = Promise<GetAllReturn>;
|
|
12
12
|
|
|
13
|
-
type A11yAPI = {|
|
|
13
|
+
export type A11yAPI = {|
|
|
14
14
|
// Label
|
|
15
15
|
getByA11yLabel: (string | RegExp) => GetReturn,
|
|
16
16
|
getByLabelText: (string | RegExp) => GetReturn,
|
|
@@ -116,9 +116,9 @@ export function matchObject<T: {}>(prop?: T, matcher: T): boolean {
|
|
|
116
116
|
: false;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
119
|
+
export const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
120
120
|
({
|
|
121
|
-
...
|
|
121
|
+
...makeA11yQuery(
|
|
122
122
|
'accessibilityLabel',
|
|
123
123
|
{
|
|
124
124
|
getBy: ['getByA11yLabel', 'getByAccessibilityLabel', 'getByLabelText'],
|
|
@@ -150,7 +150,7 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
150
150
|
},
|
|
151
151
|
matchStringValue
|
|
152
152
|
)(instance),
|
|
153
|
-
...
|
|
153
|
+
...makeA11yQuery(
|
|
154
154
|
'accessibilityHint',
|
|
155
155
|
{
|
|
156
156
|
getBy: ['getByA11yHint', 'getByAccessibilityHint', 'getByHintText'],
|
|
@@ -178,7 +178,7 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
178
178
|
},
|
|
179
179
|
matchStringValue
|
|
180
180
|
)(instance),
|
|
181
|
-
...
|
|
181
|
+
...makeA11yQuery(
|
|
182
182
|
'accessibilityRole',
|
|
183
183
|
{
|
|
184
184
|
getBy: ['getByA11yRole', 'getByAccessibilityRole', 'getByRole'],
|
|
@@ -202,7 +202,7 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
202
202
|
},
|
|
203
203
|
matchStringValue
|
|
204
204
|
)(instance),
|
|
205
|
-
...
|
|
205
|
+
...makeA11yQuery(
|
|
206
206
|
'accessibilityStates',
|
|
207
207
|
{
|
|
208
208
|
getBy: ['getByA11yStates', 'getByAccessibilityStates'],
|
|
@@ -214,7 +214,7 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
214
214
|
},
|
|
215
215
|
matchArrayValue
|
|
216
216
|
)(instance),
|
|
217
|
-
...
|
|
217
|
+
...makeA11yQuery(
|
|
218
218
|
'accessibilityState',
|
|
219
219
|
{
|
|
220
220
|
getBy: ['getByA11yState', 'getByAccessibilityState'],
|
|
@@ -226,7 +226,7 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
226
226
|
},
|
|
227
227
|
matchObject
|
|
228
228
|
)(instance),
|
|
229
|
-
...
|
|
229
|
+
...makeA11yQuery(
|
|
230
230
|
'accessibilityValue',
|
|
231
231
|
{
|
|
232
232
|
getBy: ['getByA11yValue', 'getByAccessibilityValue'],
|
|
@@ -239,5 +239,3 @@ const a11yAPI = (instance: ReactTestInstance): A11yAPI =>
|
|
|
239
239
|
matchObject
|
|
240
240
|
)(instance),
|
|
241
241
|
}: any);
|
|
242
|
-
|
|
243
|
-
export default a11yAPI;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.queryByDisplayValue = exports.queryAllByDisplayValue = exports.getByDisplayValue = exports.getAllByDisplayValue = exports.findByDisplayValue = exports.findAllByDisplayValue = void 0;
|
|
7
|
+
|
|
8
|
+
var _makeQueries = require("./makeQueries");
|
|
9
|
+
|
|
10
|
+
var _filterNodeByType = require("./filterNodeByType");
|
|
11
|
+
|
|
12
|
+
var _errors = require("./errors");
|
|
13
|
+
|
|
14
|
+
const getTextInputNodeByDisplayValue = (node, value) => {
|
|
15
|
+
try {
|
|
16
|
+
const {
|
|
17
|
+
TextInput
|
|
18
|
+
} = require('react-native');
|
|
19
|
+
|
|
20
|
+
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));
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw (0, _errors.createLibraryNotSupportedError)(error);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const queryAllByDisplayValue = instance => function queryAllByDisplayValueFn(displayValue) {
|
|
28
|
+
return instance.findAll(node => getTextInputNodeByDisplayValue(node, displayValue));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
exports.queryAllByDisplayValue = queryAllByDisplayValue;
|
|
32
|
+
|
|
33
|
+
const getMultipleError = displayValue => `Found multiple elements with display value: ${String(displayValue)} `;
|
|
34
|
+
|
|
35
|
+
const getMissingError = displayValue => `Unable to find an element with displayValue: ${String(displayValue)}`;
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
getBy: getByDisplayValue,
|
|
39
|
+
getAllBy: getAllByDisplayValue,
|
|
40
|
+
queryBy: queryByDisplayValue,
|
|
41
|
+
findBy: findByDisplayValue,
|
|
42
|
+
findAllBy: findAllByDisplayValue
|
|
43
|
+
} = (0, _makeQueries.makeQueries)(queryAllByDisplayValue, getMissingError, getMultipleError);
|
|
44
|
+
exports.findAllByDisplayValue = findAllByDisplayValue;
|
|
45
|
+
exports.findByDisplayValue = findByDisplayValue;
|
|
46
|
+
exports.queryByDisplayValue = queryByDisplayValue;
|
|
47
|
+
exports.getAllByDisplayValue = getAllByDisplayValue;
|
|
48
|
+
exports.getByDisplayValue = getByDisplayValue;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { makeQueries } from './makeQueries';
|
|
3
|
+
import type { Queries } from './makeQueries';
|
|
4
|
+
import { filterNodeByType } from './filterNodeByType';
|
|
5
|
+
import { createLibraryNotSupportedError } from './errors';
|
|
6
|
+
|
|
7
|
+
const getTextInputNodeByDisplayValue = (node, value) => {
|
|
8
|
+
try {
|
|
9
|
+
const { TextInput } = require('react-native');
|
|
10
|
+
const nodeValue =
|
|
11
|
+
node.props.value !== undefined
|
|
12
|
+
? node.props.value
|
|
13
|
+
: node.props.defaultValue;
|
|
14
|
+
return (
|
|
15
|
+
filterNodeByType(node, TextInput) &&
|
|
16
|
+
(typeof value === 'string' ? value === nodeValue : value.test(nodeValue))
|
|
17
|
+
);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw createLibraryNotSupportedError(error);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const queryAllByDisplayValue = (
|
|
24
|
+
instance: ReactTestInstance
|
|
25
|
+
): ((displayValue: string | RegExp) => Array<ReactTestInstance>) =>
|
|
26
|
+
function queryAllByDisplayValueFn(displayValue) {
|
|
27
|
+
return instance.findAll((node) =>
|
|
28
|
+
getTextInputNodeByDisplayValue(node, displayValue)
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getMultipleError = (displayValue: string | RegExp) =>
|
|
33
|
+
`Found multiple elements with display value: ${String(displayValue)} `;
|
|
34
|
+
const getMissingError = (displayValue: string | RegExp) =>
|
|
35
|
+
`Unable to find an element with displayValue: ${String(displayValue)}`;
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
getBy: getByDisplayValue,
|
|
39
|
+
getAllBy: getAllByDisplayValue,
|
|
40
|
+
queryBy: queryByDisplayValue,
|
|
41
|
+
findBy: findByDisplayValue,
|
|
42
|
+
findAllBy: findAllByDisplayValue,
|
|
43
|
+
}: Queries<string | RegExp> = makeQueries(
|
|
44
|
+
queryAllByDisplayValue,
|
|
45
|
+
getMissingError,
|
|
46
|
+
getMultipleError
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
findAllByDisplayValue,
|
|
51
|
+
findByDisplayValue,
|
|
52
|
+
getAllByDisplayValue,
|
|
53
|
+
getByDisplayValue,
|
|
54
|
+
queryAllByDisplayValue,
|
|
55
|
+
queryByDisplayValue,
|
|
56
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.queryByPlaceholderText = exports.queryAllByPlaceholderText = exports.getByPlaceholderText = exports.getAllByPlaceholderText = exports.findByPlaceholderText = exports.findAllByPlaceholderText = void 0;
|
|
7
|
+
|
|
8
|
+
var _makeQueries = require("./makeQueries");
|
|
9
|
+
|
|
10
|
+
var _filterNodeByType = require("./filterNodeByType");
|
|
11
|
+
|
|
12
|
+
var _errors = require("./errors");
|
|
13
|
+
|
|
14
|
+
const getTextInputNodeByPlaceholderText = (node, placeholder) => {
|
|
15
|
+
try {
|
|
16
|
+
const {
|
|
17
|
+
TextInput
|
|
18
|
+
} = require('react-native');
|
|
19
|
+
|
|
20
|
+
return (0, _filterNodeByType.filterNodeByType)(node, TextInput) && (typeof placeholder === 'string' ? placeholder === node.props.placeholder : placeholder.test(node.props.placeholder));
|
|
21
|
+
} catch (error) {
|
|
22
|
+
throw (0, _errors.createLibraryNotSupportedError)(error);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const queryAllByPlaceholderText = instance => function queryAllByPlaceholderFn(placeholder) {
|
|
27
|
+
return instance.findAll(node => getTextInputNodeByPlaceholderText(node, placeholder));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
exports.queryAllByPlaceholderText = queryAllByPlaceholderText;
|
|
31
|
+
|
|
32
|
+
const getMultipleError = placeholder => `Found multiple elements with placeholder: ${String(placeholder)} `;
|
|
33
|
+
|
|
34
|
+
const getMissingError = placeholder => `Unable to find an element with placeholder: ${String(placeholder)}`;
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
getBy: getByPlaceholderText,
|
|
38
|
+
getAllBy: getAllByPlaceholderText,
|
|
39
|
+
queryBy: queryByPlaceholderText,
|
|
40
|
+
findBy: findByPlaceholderText,
|
|
41
|
+
findAllBy: findAllByPlaceholderText
|
|
42
|
+
} = (0, _makeQueries.makeQueries)(queryAllByPlaceholderText, getMissingError, getMultipleError);
|
|
43
|
+
exports.findAllByPlaceholderText = findAllByPlaceholderText;
|
|
44
|
+
exports.findByPlaceholderText = findByPlaceholderText;
|
|
45
|
+
exports.queryByPlaceholderText = queryByPlaceholderText;
|
|
46
|
+
exports.getAllByPlaceholderText = getAllByPlaceholderText;
|
|
47
|
+
exports.getByPlaceholderText = getByPlaceholderText;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { makeQueries } from './makeQueries';
|
|
3
|
+
import type { Queries } from './makeQueries';
|
|
4
|
+
import { filterNodeByType } from './filterNodeByType';
|
|
5
|
+
import { createLibraryNotSupportedError } from './errors';
|
|
6
|
+
|
|
7
|
+
const getTextInputNodeByPlaceholderText = (node, placeholder) => {
|
|
8
|
+
try {
|
|
9
|
+
const { TextInput } = require('react-native');
|
|
10
|
+
return (
|
|
11
|
+
filterNodeByType(node, TextInput) &&
|
|
12
|
+
(typeof placeholder === 'string'
|
|
13
|
+
? placeholder === node.props.placeholder
|
|
14
|
+
: placeholder.test(node.props.placeholder))
|
|
15
|
+
);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
throw createLibraryNotSupportedError(error);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const queryAllByPlaceholderText = (
|
|
22
|
+
instance: ReactTestInstance
|
|
23
|
+
): ((placeholder: string | RegExp) => Array<ReactTestInstance>) =>
|
|
24
|
+
function queryAllByPlaceholderFn(placeholder) {
|
|
25
|
+
return instance.findAll((node) =>
|
|
26
|
+
getTextInputNodeByPlaceholderText(node, placeholder)
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getMultipleError = (placeholder) =>
|
|
31
|
+
`Found multiple elements with placeholder: ${String(placeholder)} `;
|
|
32
|
+
const getMissingError = (placeholder) =>
|
|
33
|
+
`Unable to find an element with placeholder: ${String(placeholder)}`;
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
getBy: getByPlaceholderText,
|
|
37
|
+
getAllBy: getAllByPlaceholderText,
|
|
38
|
+
queryBy: queryByPlaceholderText,
|
|
39
|
+
findBy: findByPlaceholderText,
|
|
40
|
+
findAllBy: findAllByPlaceholderText,
|
|
41
|
+
}: Queries<string | RegExp> = makeQueries(
|
|
42
|
+
queryAllByPlaceholderText,
|
|
43
|
+
getMissingError,
|
|
44
|
+
getMultipleError
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
findAllByPlaceholderText,
|
|
49
|
+
findByPlaceholderText,
|
|
50
|
+
getAllByPlaceholderText,
|
|
51
|
+
getByPlaceholderText,
|
|
52
|
+
queryAllByPlaceholderText,
|
|
53
|
+
queryByPlaceholderText,
|
|
54
|
+
};
|