@testing-library/react-native 12.2.1 → 12.2.2

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 (302) hide show
  1. package/package.json +2 -3
  2. package/.DS_Store +0 -0
  3. package/.codecov.yml +0 -9
  4. package/.eslintcache +0 -1
  5. package/.eslintignore +0 -3
  6. package/.eslintrc +0 -19
  7. package/.flowconfig +0 -63
  8. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  9. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
  10. package/.github/ISSUE_TEMPLATE/question.md +0 -9
  11. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  12. package/.github/actions/setup-deps/action.yml +0 -22
  13. package/.github/actions/setup-website-deps/action.yml +0 -22
  14. package/.github/dependabot.yml +0 -10
  15. package/.github/workflows/deploy-website.yml +0 -36
  16. package/.github/workflows/example-apps.yml +0 -25
  17. package/.github/workflows/main.yml +0 -103
  18. package/.gitignore +0 -11
  19. package/.prettierrc.js +0 -5
  20. package/CODE_OF_CONDUCT.md +0 -73
  21. package/CONTRIBUTING.md +0 -64
  22. package/babel.config.js +0 -22
  23. package/examples/basic/.expo/README.md +0 -15
  24. package/examples/basic/.expo/packager-info.json +0 -4
  25. package/examples/basic/.expo/settings.json +0 -10
  26. package/examples/basic/.expo-shared/assets.json +0 -4
  27. package/examples/basic/.gitignore +0 -14
  28. package/examples/basic/App.tsx +0 -20
  29. package/examples/basic/README.md +0 -11
  30. package/examples/basic/__tests__/App.test.tsx +0 -137
  31. package/examples/basic/app.json +0 -31
  32. package/examples/basic/assets/adaptive-icon.png +0 -0
  33. package/examples/basic/assets/favicon.png +0 -0
  34. package/examples/basic/assets/icon.png +0 -0
  35. package/examples/basic/assets/splash.png +0 -0
  36. package/examples/basic/babel.config.js +0 -6
  37. package/examples/basic/components/Home.tsx +0 -28
  38. package/examples/basic/components/LoginForm.tsx +0 -138
  39. package/examples/basic/jest-setup.ts +0 -7
  40. package/examples/basic/jest.config.js +0 -5
  41. package/examples/basic/package.json +0 -30
  42. package/examples/basic/tsconfig.json +0 -7
  43. package/examples/basic/yarn.lock +0 -7499
  44. package/examples/react-navigation/README.md +0 -16
  45. package/examples/react-navigation/babel.config.js +0 -4
  46. package/examples/react-navigation/jest-setup.js +0 -11
  47. package/examples/react-navigation/jest.config.js +0 -10
  48. package/examples/react-navigation/package.json +0 -31
  49. package/examples/react-navigation/src/App.js +0 -21
  50. package/examples/react-navigation/src/DrawerNavigator.js +0 -15
  51. package/examples/react-navigation/src/DrawerNavigator.test.js +0 -42
  52. package/examples/react-navigation/src/NativeStackNavigator.js +0 -15
  53. package/examples/react-navigation/src/NativeStackNavigator.test.js +0 -34
  54. package/examples/react-navigation/src/StackNavigator.js +0 -15
  55. package/examples/react-navigation/src/StackNavigator.test.js +0 -34
  56. package/examples/react-navigation/src/TabNavigator.js +0 -15
  57. package/examples/react-navigation/src/TabNavigator.test.js +0 -21
  58. package/examples/react-navigation/src/screens/DetailsScreen.js +0 -43
  59. package/examples/react-navigation/src/screens/DetailsScreen.test.js +0 -27
  60. package/examples/react-navigation/src/screens/DrawerHomeScreen.js +0 -26
  61. package/examples/react-navigation/src/screens/HomeScreen.js +0 -48
  62. package/examples/react-navigation/src/screens/SettingsScreen.js +0 -20
  63. package/examples/react-navigation/src/test-utils.js +0 -12
  64. package/examples/react-navigation/yarn.lock +0 -5018
  65. package/examples/redux/App.js +0 -27
  66. package/examples/redux/README.md +0 -5
  67. package/examples/redux/actions/todoActions.js +0 -25
  68. package/examples/redux/babel.config.js +0 -6
  69. package/examples/redux/components/AddTodo.js +0 -73
  70. package/examples/redux/components/AddTodo.test.js +0 -27
  71. package/examples/redux/components/TodoElem.js +0 -25
  72. package/examples/redux/components/TodoList.js +0 -29
  73. package/examples/redux/components/TodoList.test.js +0 -34
  74. package/examples/redux/index.js +0 -8
  75. package/examples/redux/jest-setup.js +0 -2
  76. package/examples/redux/jest.config.js +0 -4
  77. package/examples/redux/package.json +0 -23
  78. package/examples/redux/reducers/index.js +0 -6
  79. package/examples/redux/reducers/todoReducer.js +0 -27
  80. package/examples/redux/store.js +0 -10
  81. package/examples/redux/test-utils.js +0 -11
  82. package/examples/redux/yarn.lock +0 -4819
  83. package/experiments-app/.expo/README.md +0 -15
  84. package/experiments-app/.expo/devices.json +0 -3
  85. package/experiments-app/.expo/packager-info.json +0 -9
  86. package/experiments-app/.expo/settings.json +0 -9
  87. package/experiments-app/.gitignore +0 -17
  88. package/experiments-app/.prettierrc.js +0 -5
  89. package/experiments-app/app.json +0 -30
  90. package/experiments-app/assets/adaptive-icon.png +0 -0
  91. package/experiments-app/assets/favicon.png +0 -0
  92. package/experiments-app/assets/icon.png +0 -0
  93. package/experiments-app/assets/splash.png +0 -0
  94. package/experiments-app/babel.config.js +0 -6
  95. package/experiments-app/index.js +0 -4
  96. package/experiments-app/package.json +0 -29
  97. package/experiments-app/src/App.tsx +0 -31
  98. package/experiments-app/src/MainScreen.tsx +0 -52
  99. package/experiments-app/src/experiments.ts +0 -35
  100. package/experiments-app/src/screens/FlatListEvents.tsx +0 -57
  101. package/experiments-app/src/screens/ScrollViewEvents.tsx +0 -65
  102. package/experiments-app/src/screens/SectionListEvents.tsx +0 -91
  103. package/experiments-app/src/screens/TextInputEventPropagation.tsx +0 -42
  104. package/experiments-app/src/screens/TextInputEvents.tsx +0 -48
  105. package/experiments-app/src/utils/helpers.ts +0 -18
  106. package/experiments-app/tsconfig.json +0 -6
  107. package/experiments-app/yarn.lock +0 -6709
  108. package/experiments-rtl/.babelrc +0 -8
  109. package/experiments-rtl/.eslintrc.json +0 -3
  110. package/experiments-rtl/.gitignore +0 -35
  111. package/experiments-rtl/README.md +0 -34
  112. package/experiments-rtl/jest-setup.js +0 -1
  113. package/experiments-rtl/jest.config.js +0 -4
  114. package/experiments-rtl/next.config.js +0 -4
  115. package/experiments-rtl/package.json +0 -38
  116. package/experiments-rtl/postcss.config.js +0 -6
  117. package/experiments-rtl/public/next.svg +0 -1
  118. package/experiments-rtl/public/vercel.svg +0 -1
  119. package/experiments-rtl/src/app/__tests__/click.test.tsx +0 -31
  120. package/experiments-rtl/src/app/__tests__/managed-text-input.test.tsx +0 -51
  121. package/experiments-rtl/src/app/globals.css +0 -27
  122. package/experiments-rtl/src/app/layout.tsx +0 -22
  123. package/experiments-rtl/src/app/page.tsx +0 -113
  124. package/experiments-rtl/tailwind.config.ts +0 -20
  125. package/experiments-rtl/tsconfig.json +0 -28
  126. package/experiments-rtl/yarn.lock +0 -5418
  127. package/flow-typed/npm/jest_v26.x.x.js +0 -1218
  128. package/flow-typed/npm/react-test-renderer_v16.x.x.js +0 -81
  129. package/jest-setup.ts +0 -10
  130. package/renovate.json +0 -19
  131. package/scripts/test_react_17 +0 -12
  132. package/src/__tests__/__snapshots__/render-debug.test.tsx.snap +0 -548
  133. package/src/__tests__/__snapshots__/render.test.tsx.snap +0 -39
  134. package/src/__tests__/act.test.tsx +0 -56
  135. package/src/__tests__/auto-cleanup-skip.test.tsx +0 -39
  136. package/src/__tests__/auto-cleanup.test.tsx +0 -50
  137. package/src/__tests__/cleanup.test.tsx +0 -26
  138. package/src/__tests__/config.test.ts +0 -55
  139. package/src/__tests__/fireEvent-textInput.test.tsx +0 -154
  140. package/src/__tests__/fireEvent.test.tsx +0 -485
  141. package/src/__tests__/host-component-names.test.tsx +0 -109
  142. package/src/__tests__/host-text-nesting.test.tsx +0 -90
  143. package/src/__tests__/jest-native.test.tsx +0 -84
  144. package/src/__tests__/questionsBoard.test.tsx +0 -62
  145. package/src/__tests__/react-native-api.test.tsx +0 -126
  146. package/src/__tests__/render-debug.test.tsx +0 -207
  147. package/src/__tests__/render-stringValidation.test.tsx +0 -157
  148. package/src/__tests__/render.test.tsx +0 -256
  149. package/src/__tests__/renderHook.test.tsx +0 -114
  150. package/src/__tests__/screen.test.tsx +0 -66
  151. package/src/__tests__/timerUtils.ts +0 -7
  152. package/src/__tests__/timers.test.ts +0 -27
  153. package/src/__tests__/waitFor.test.tsx +0 -327
  154. package/src/__tests__/waitForElementToBeRemoved.test.tsx +0 -151
  155. package/src/__tests__/within.test.tsx +0 -96
  156. package/src/act.ts +0 -86
  157. package/src/cleanup.ts +0 -15
  158. package/src/config.ts +0 -72
  159. package/src/fireEvent.ts +0 -159
  160. package/src/flush-micro-tasks.ts +0 -30
  161. package/src/helpers/__tests__/accessiblity.test.tsx +0 -373
  162. package/src/helpers/__tests__/component-tree.test.tsx +0 -226
  163. package/src/helpers/__tests__/format-default.tsx +0 -114
  164. package/src/helpers/__tests__/getTextContent.test.tsx +0 -49
  165. package/src/helpers/__tests__/includeHiddenElements.test.tsx +0 -39
  166. package/src/helpers/__tests__/query-name.test.ts +0 -10
  167. package/src/helpers/__tests__/timers.test.ts +0 -8
  168. package/src/helpers/accessiblity.ts +0 -108
  169. package/src/helpers/component-tree.ts +0 -94
  170. package/src/helpers/debugDeep.ts +0 -27
  171. package/src/helpers/debugShallow.ts +0 -22
  172. package/src/helpers/deprecation.ts +0 -53
  173. package/src/helpers/errors.ts +0 -66
  174. package/src/helpers/findAll.ts +0 -70
  175. package/src/helpers/format-default.ts +0 -72
  176. package/src/helpers/format.ts +0 -47
  177. package/src/helpers/getTextContent.ts +0 -20
  178. package/src/helpers/host-component-names.tsx +0 -88
  179. package/src/helpers/matchers/__tests__/matchArrayValue.test.ts +0 -34
  180. package/src/helpers/matchers/__tests__/matchObject.test.ts +0 -37
  181. package/src/helpers/matchers/__tests__/matchStringValue.test.ts +0 -15
  182. package/src/helpers/matchers/accessibilityState.ts +0 -48
  183. package/src/helpers/matchers/accessibilityValue.ts +0 -24
  184. package/src/helpers/matchers/matchArrayProp.ts +0 -21
  185. package/src/helpers/matchers/matchLabelText.ts +0 -50
  186. package/src/helpers/matchers/matchObjectProp.ts +0 -25
  187. package/src/helpers/matchers/matchStringProp.ts +0 -23
  188. package/src/helpers/matchers/matchTextContent.ts +0 -20
  189. package/src/helpers/pointer-events.ts +0 -27
  190. package/src/helpers/query-name.ts +0 -4
  191. package/src/helpers/stringValidation.ts +0 -36
  192. package/src/helpers/timers.ts +0 -98
  193. package/src/index.ts +0 -33
  194. package/src/matches.ts +0 -49
  195. package/src/pure.ts +0 -27
  196. package/src/queries/__tests__/a11yState.test.tsx +0 -439
  197. package/src/queries/__tests__/a11yValue.test.tsx +0 -309
  198. package/src/queries/__tests__/displayValue.test.tsx +0 -221
  199. package/src/queries/__tests__/hintText.test.tsx +0 -177
  200. package/src/queries/__tests__/labelText.test.tsx +0 -242
  201. package/src/queries/__tests__/makeQueries.test.tsx +0 -235
  202. package/src/queries/__tests__/placeholderText.test.tsx +0 -136
  203. package/src/queries/__tests__/role-value.test.tsx +0 -176
  204. package/src/queries/__tests__/role.test.tsx +0 -824
  205. package/src/queries/__tests__/testId.test.tsx +0 -200
  206. package/src/queries/__tests__/text.test.tsx +0 -556
  207. package/src/queries/a11yState.ts +0 -127
  208. package/src/queries/a11yValue.ts +0 -127
  209. package/src/queries/displayValue.ts +0 -71
  210. package/src/queries/hintText.ts +0 -107
  211. package/src/queries/labelText.ts +0 -57
  212. package/src/queries/makeQueries.ts +0 -255
  213. package/src/queries/options.ts +0 -14
  214. package/src/queries/placeholderText.ts +0 -72
  215. package/src/queries/role.ts +0 -131
  216. package/src/queries/testId.ts +0 -66
  217. package/src/queries/text.ts +0 -63
  218. package/src/queries/unsafeProps.ts +0 -76
  219. package/src/queries/unsafeType.ts +0 -73
  220. package/src/react-versions.ts +0 -11
  221. package/src/render-act.ts +0 -19
  222. package/src/render.tsx +0 -183
  223. package/src/renderHook.tsx +0 -56
  224. package/src/screen.ts +0 -123
  225. package/src/shallow.ts +0 -18
  226. package/src/test-utils/events.ts +0 -24
  227. package/src/test-utils/index.ts +0 -1
  228. package/src/user-event/__tests__/__snapshots__/clear.test.tsx.snap +0 -269
  229. package/src/user-event/__tests__/clear.test.tsx +0 -217
  230. package/src/user-event/clear.ts +0 -59
  231. package/src/user-event/event-builder/common.ts +0 -66
  232. package/src/user-event/event-builder/index.ts +0 -7
  233. package/src/user-event/event-builder/text-input.ts +0 -86
  234. package/src/user-event/index.ts +0 -18
  235. package/src/user-event/press/__tests__/longPress.real-timers.test.tsx +0 -117
  236. package/src/user-event/press/__tests__/longPress.test.tsx +0 -157
  237. package/src/user-event/press/__tests__/press.real-timers.test.tsx +0 -320
  238. package/src/user-event/press/__tests__/press.test.tsx +0 -457
  239. package/src/user-event/press/constants.ts +0 -7
  240. package/src/user-event/press/index.ts +0 -1
  241. package/src/user-event/press/press.ts +0 -163
  242. package/src/user-event/setup/index.ts +0 -2
  243. package/src/user-event/setup/setup.ts +0 -142
  244. package/src/user-event/type/__tests__/__snapshots__/type-managed.test.tsx.snap +0 -339
  245. package/src/user-event/type/__tests__/__snapshots__/type.test.tsx.snap +0 -668
  246. package/src/user-event/type/__tests__/parseKeys.test.ts +0 -23
  247. package/src/user-event/type/__tests__/type-managed.test.tsx +0 -120
  248. package/src/user-event/type/__tests__/type.test.tsx +0 -335
  249. package/src/user-event/type/index.ts +0 -1
  250. package/src/user-event/type/parseKeys.ts +0 -41
  251. package/src/user-event/type/type.ts +0 -138
  252. package/src/user-event/utils/__tests__/dispatch-event.test.tsx +0 -41
  253. package/src/user-event/utils/__tests__/wait.test.ts +0 -62
  254. package/src/user-event/utils/content-size.ts +0 -25
  255. package/src/user-event/utils/dispatch-event.ts +0 -38
  256. package/src/user-event/utils/host-components.ts +0 -6
  257. package/src/user-event/utils/index.ts +0 -6
  258. package/src/user-event/utils/text-range.ts +0 -4
  259. package/src/user-event/utils/wait.ts +0 -15
  260. package/src/user-event/utils/warn-about-real-timers.ts +0 -13
  261. package/src/waitFor.ts +0 -228
  262. package/src/waitForElementToBeRemoved.ts +0 -42
  263. package/src/within.ts +0 -30
  264. package/tsconfig.json +0 -17
  265. package/tsconfig.release.json +0 -8
  266. package/website/.gitignore +0 -20
  267. package/website/README.md +0 -33
  268. package/website/docker/.dockerignore +0 -3
  269. package/website/docker/Dockerfile +0 -9
  270. package/website/docker/docker-compose.yml +0 -11
  271. package/website/docs/API.md +0 -940
  272. package/website/docs/EslintPLluginTestingLibrary.md +0 -28
  273. package/website/docs/FAQ.md +0 -44
  274. package/website/docs/GettingStarted.md +0 -100
  275. package/website/docs/HowShouldIQuery.md +0 -21
  276. package/website/docs/MigrationV11.md +0 -64
  277. package/website/docs/MigrationV12.md +0 -67
  278. package/website/docs/MigrationV2.md +0 -126
  279. package/website/docs/MigrationV7.md +0 -119
  280. package/website/docs/MigrationV9.md +0 -67
  281. package/website/docs/Queries.md +0 -572
  282. package/website/docs/ReactNavigation.md +0 -371
  283. package/website/docs/ReduxIntegration.md +0 -137
  284. package/website/docs/TestingEnvironment.md +0 -154
  285. package/website/docs/Troubleshooting.md +0 -44
  286. package/website/docs/UnderstandingAct.md +0 -227
  287. package/website/docs/UserEvent.md +0 -191
  288. package/website/docusaurus.config.js +0 -114
  289. package/website/package.json +0 -31
  290. package/website/sidebars.js +0 -20
  291. package/website/src/components/Feature.js +0 -31
  292. package/website/src/css/custom.css +0 -13
  293. package/website/src/css/index.module.css +0 -77
  294. package/website/src/pages/index.js +0 -82
  295. package/website/static/.nojekyll +0 -0
  296. package/website/static/css/custom.css +0 -28
  297. package/website/static/img/hit.png +0 -0
  298. package/website/static/img/locomotive.png +0 -0
  299. package/website/static/img/owl.png +0 -0
  300. package/website/static/img/tools.png +0 -0
  301. package/website/yarn.lock +0 -7669
  302. package/yarn.lock +0 -7765
@@ -1,120 +0,0 @@
1
- import * as React from 'react';
2
- import { TextInput } from 'react-native';
3
- import { createEventLogger } from '../../../test-utils/events';
4
- import { render } from '../../..';
5
- import { userEvent } from '../..';
6
-
7
- beforeEach(() => {
8
- jest.useRealTimers();
9
- });
10
-
11
- interface ManagedTextInputProps {
12
- valueTransformer?: (text: string) => string;
13
- logEvent: (name: string) => (event: any) => void;
14
- initialValue?: string;
15
- }
16
-
17
- function ManagedTextInput({
18
- logEvent,
19
- valueTransformer,
20
- initialValue = '',
21
- }: ManagedTextInputProps) {
22
- const [value, setValue] = React.useState(initialValue);
23
-
24
- const handleChangeText = (text: string) => {
25
- logEvent('changeText')(text);
26
- const newValue = valueTransformer?.(text) ?? text;
27
- setValue(newValue);
28
- };
29
-
30
- return (
31
- <TextInput
32
- testID="input"
33
- value={value}
34
- onChangeText={handleChangeText}
35
- onFocus={logEvent('focus')}
36
- onBlur={logEvent('blur')}
37
- onPressIn={logEvent('pressIn')}
38
- onPressOut={logEvent('pressOut')}
39
- onChange={logEvent('change')}
40
- onKeyPress={logEvent('keyPress')}
41
- onTextInput={logEvent('textInput')}
42
- onSelectionChange={logEvent('selectionChange')}
43
- onSubmitEditing={logEvent('submitEditing')}
44
- onEndEditing={logEvent('endEditing')}
45
- onContentSizeChange={logEvent('contentSizeChange')}
46
- />
47
- );
48
- }
49
-
50
- describe('type() for managed TextInput', () => {
51
- it('supports basic case', async () => {
52
- jest.spyOn(Date, 'now').mockImplementation(() => 100100100100);
53
- const { events, logEvent } = createEventLogger();
54
- const screen = render(<ManagedTextInput logEvent={logEvent} />);
55
-
56
- const user = userEvent.setup();
57
- await user.type(screen.getByTestId('input'), 'Wow');
58
-
59
- const eventNames = events.map((e) => e.name);
60
- expect(eventNames).toEqual([
61
- 'pressIn',
62
- 'focus',
63
- 'pressOut',
64
- 'keyPress',
65
- 'change',
66
- 'changeText',
67
- 'selectionChange',
68
- 'keyPress',
69
- 'change',
70
- 'changeText',
71
- 'selectionChange',
72
- 'keyPress',
73
- 'change',
74
- 'changeText',
75
- 'selectionChange',
76
- 'endEditing',
77
- 'blur',
78
- ]);
79
-
80
- expect(events).toMatchSnapshot('input: "Wow"');
81
- });
82
-
83
- test('supports rejecting TextInput', async () => {
84
- jest.spyOn(Date, 'now').mockImplementation(() => 100100100100);
85
- const { events, logEvent } = createEventLogger();
86
- const screen = render(
87
- <ManagedTextInput
88
- initialValue="XXX"
89
- logEvent={logEvent}
90
- valueTransformer={() => 'XXX'}
91
- />
92
- );
93
-
94
- const user = userEvent.setup();
95
- await user.type(screen.getByTestId('input'), 'ABC');
96
-
97
- const eventNames = events.map((e) => e.name);
98
- expect(eventNames).toEqual([
99
- 'pressIn',
100
- 'focus',
101
- 'pressOut',
102
- 'keyPress',
103
- 'change',
104
- 'changeText',
105
- 'selectionChange',
106
- 'keyPress',
107
- 'change',
108
- 'changeText',
109
- 'selectionChange',
110
- 'keyPress',
111
- 'change',
112
- 'changeText',
113
- 'selectionChange',
114
- 'endEditing',
115
- 'blur',
116
- ]);
117
-
118
- expect(events).toMatchSnapshot('input: "ABC", value: "XXX"');
119
- });
120
- });
@@ -1,335 +0,0 @@
1
- import * as React from 'react';
2
- import { View, TextInput, TextInputProps } from 'react-native';
3
- import { createEventLogger } from '../../../test-utils/events';
4
- import { render } from '../../..';
5
- import { userEvent } from '../..';
6
-
7
- beforeEach(() => {
8
- jest.useRealTimers();
9
- });
10
-
11
- function renderTextInputWithToolkit(props: TextInputProps = {}) {
12
- const { events, logEvent } = createEventLogger();
13
-
14
- const screen = render(
15
- <TextInput
16
- testID="input"
17
- onFocus={logEvent('focus')}
18
- onBlur={logEvent('blur')}
19
- onPressIn={logEvent('pressIn')}
20
- onPressOut={logEvent('pressOut')}
21
- onChange={logEvent('change')}
22
- onChangeText={logEvent('changeText')}
23
- onKeyPress={logEvent('keyPress')}
24
- onTextInput={logEvent('textInput')}
25
- onSelectionChange={logEvent('selectionChange')}
26
- onSubmitEditing={logEvent('submitEditing')}
27
- onEndEditing={logEvent('endEditing')}
28
- onContentSizeChange={logEvent('contentSizeChange')}
29
- {...props}
30
- />
31
- );
32
-
33
- return {
34
- ...screen,
35
- events,
36
- };
37
- }
38
-
39
- describe('type()', () => {
40
- it('supports basic case', async () => {
41
- jest.spyOn(Date, 'now').mockImplementation(() => 100100100100);
42
- const { events, ...queries } = renderTextInputWithToolkit();
43
-
44
- const user = userEvent.setup();
45
- await user.type(queries.getByTestId('input'), 'abc');
46
-
47
- const eventNames = events.map((e) => e.name);
48
- expect(eventNames).toEqual([
49
- 'pressIn',
50
- 'focus',
51
- 'pressOut',
52
- 'keyPress',
53
- 'change',
54
- 'changeText',
55
- 'selectionChange',
56
- 'keyPress',
57
- 'change',
58
- 'changeText',
59
- 'selectionChange',
60
- 'keyPress',
61
- 'change',
62
- 'changeText',
63
- 'selectionChange',
64
- 'endEditing',
65
- 'blur',
66
- ]);
67
-
68
- expect(events).toMatchSnapshot('input: "abc"');
69
- });
70
-
71
- it.each(['modern', 'legacy'])('works with %s fake timers', async (type) => {
72
- jest.useFakeTimers({ legacyFakeTimers: type === 'legacy' });
73
- const { events, ...queries } = renderTextInputWithToolkit();
74
-
75
- const user = userEvent.setup();
76
- await user.type(queries.getByTestId('input'), 'abc');
77
-
78
- const eventNames = events.map((e) => e.name);
79
- expect(eventNames).toEqual([
80
- 'pressIn',
81
- 'focus',
82
- 'pressOut',
83
- 'keyPress',
84
- 'change',
85
- 'changeText',
86
- 'selectionChange',
87
- 'keyPress',
88
- 'change',
89
- 'changeText',
90
- 'selectionChange',
91
- 'keyPress',
92
- 'change',
93
- 'changeText',
94
- 'selectionChange',
95
- 'endEditing',
96
- 'blur',
97
- ]);
98
- });
99
-
100
- it('supports defaultValue prop', async () => {
101
- const { events, ...queries } = renderTextInputWithToolkit({
102
- defaultValue: 'xxx',
103
- });
104
-
105
- const user = userEvent.setup();
106
- await user.type(queries.getByTestId('input'), 'ab');
107
-
108
- const eventNames = events.map((e) => e.name);
109
- expect(eventNames).toEqual([
110
- 'pressIn',
111
- 'focus',
112
- 'pressOut',
113
- 'keyPress',
114
- 'change',
115
- 'changeText',
116
- 'selectionChange',
117
- 'keyPress',
118
- 'change',
119
- 'changeText',
120
- 'selectionChange',
121
- 'endEditing',
122
- 'blur',
123
- ]);
124
-
125
- expect(events).toMatchSnapshot('input: "ab", defaultValue: "xxx"');
126
- });
127
-
128
- it('does respect editable prop', async () => {
129
- const { events, ...queries } = renderTextInputWithToolkit({
130
- editable: false,
131
- });
132
-
133
- const user = userEvent.setup();
134
- await user.type(queries.getByTestId('input'), 'ab');
135
-
136
- const eventNames = events.map((e) => e.name);
137
- expect(eventNames).toEqual([]);
138
- });
139
-
140
- it('supports backspace', async () => {
141
- const { events, ...queries } = renderTextInputWithToolkit({
142
- defaultValue: 'xxx',
143
- });
144
-
145
- const user = userEvent.setup();
146
- await user.type(queries.getByTestId('input'), '{Backspace}a');
147
-
148
- const eventNames = events.map((e) => e.name);
149
- expect(eventNames).toEqual([
150
- 'pressIn',
151
- 'focus',
152
- 'pressOut',
153
- 'keyPress',
154
- 'change',
155
- 'changeText',
156
- 'selectionChange',
157
- 'keyPress',
158
- 'change',
159
- 'changeText',
160
- 'selectionChange',
161
- 'endEditing',
162
- 'blur',
163
- ]);
164
-
165
- expect(events).toMatchSnapshot(
166
- 'input: "{Backspace}a", defaultValue: "xxx"'
167
- );
168
- });
169
-
170
- it('supports multiline', async () => {
171
- const { events, ...queries } = renderTextInputWithToolkit({
172
- multiline: true,
173
- });
174
-
175
- const user = userEvent.setup();
176
- await user.type(queries.getByTestId('input'), '{Enter}\n');
177
-
178
- const eventNames = events.map((e) => e.name);
179
- expect(eventNames).toEqual([
180
- 'pressIn',
181
- 'focus',
182
- 'pressOut',
183
- 'keyPress',
184
- 'textInput',
185
- 'change',
186
- 'changeText',
187
- 'selectionChange',
188
- 'contentSizeChange',
189
- 'keyPress',
190
- 'textInput',
191
- 'change',
192
- 'changeText',
193
- 'selectionChange',
194
- 'contentSizeChange',
195
- 'endEditing',
196
- 'blur',
197
- ]);
198
-
199
- expect(events).toMatchSnapshot('input: "{Enter}\\n", multiline: true');
200
- });
201
-
202
- test('skips press events when `skipPress: true`', async () => {
203
- const { events, ...queries } = renderTextInputWithToolkit();
204
-
205
- const user = userEvent.setup();
206
- await user.type(queries.getByTestId('input'), 'a', {
207
- skipPress: true,
208
- });
209
-
210
- const eventNames = events.map((e) => e.name);
211
- expect(eventNames).not.toContainEqual('pressIn');
212
- expect(eventNames).not.toContainEqual('pressOut');
213
- expect(eventNames).toEqual([
214
- 'focus',
215
- 'keyPress',
216
- 'change',
217
- 'changeText',
218
- 'selectionChange',
219
- 'endEditing',
220
- 'blur',
221
- ]);
222
- });
223
-
224
- it('triggers submit event with `submitEditing: true`', async () => {
225
- const { events, ...queries } = renderTextInputWithToolkit();
226
-
227
- const user = userEvent.setup();
228
- await user.type(queries.getByTestId('input'), 'a', {
229
- submitEditing: true,
230
- });
231
-
232
- const eventNames = events.map((e) => e.name);
233
- expect(eventNames).toEqual([
234
- 'pressIn',
235
- 'focus',
236
- 'pressOut',
237
- 'keyPress',
238
- 'change',
239
- 'changeText',
240
- 'selectionChange',
241
- 'submitEditing',
242
- 'endEditing',
243
- 'blur',
244
- ]);
245
-
246
- expect(events[7].name).toBe('submitEditing');
247
- expect(events[7].payload).toEqual({
248
- nativeEvent: { text: 'a', target: 0 },
249
- });
250
- });
251
-
252
- it('works when not all events have handlers', async () => {
253
- const { events, logEvent } = createEventLogger();
254
- const screen = render(
255
- <TextInput
256
- testID="input"
257
- onChangeText={logEvent('changeText')}
258
- onEndEditing={logEvent('endEditing')}
259
- />
260
- );
261
-
262
- const user = userEvent.setup();
263
- await user.type(screen.getByTestId('input'), 'abc');
264
-
265
- const eventNames = events.map((e) => e.name);
266
- expect(eventNames).toEqual([
267
- 'changeText',
268
- 'changeText',
269
- 'changeText',
270
- 'endEditing',
271
- ]);
272
-
273
- expect(events).toMatchSnapshot('input: "abc"');
274
- });
275
-
276
- it('does NOT work on View', async () => {
277
- const screen = render(<View testID="input" />);
278
-
279
- const user = userEvent.setup();
280
- await expect(
281
- user.type(screen.getByTestId('input'), 'abc')
282
- ).rejects.toThrowErrorMatchingInlineSnapshot(
283
- `"type() works only with host "TextInput" elements. Passed element has type "View"."`
284
- );
285
- });
286
-
287
- // View that ignores props type checking
288
- const AnyView = View as React.ComponentType<any>;
289
-
290
- it('does NOT bubble up', async () => {
291
- const parentHandler = jest.fn();
292
- const screen = render(
293
- <AnyView
294
- onChangeText={parentHandler}
295
- onChange={parentHandler}
296
- onKeyPress={parentHandler}
297
- onTextInput={parentHandler}
298
- onFocus={parentHandler}
299
- onBlur={parentHandler}
300
- onEndEditing={parentHandler}
301
- onPressIn={parentHandler}
302
- onPressOut={parentHandler}
303
- >
304
- <TextInput testID="input" />
305
- </AnyView>
306
- );
307
-
308
- const user = userEvent.setup();
309
- await user.type(screen.getByTestId('input'), 'abc');
310
- expect(parentHandler).not.toHaveBeenCalled();
311
- });
312
-
313
- it('supports direct access', async () => {
314
- const { events, logEvent } = createEventLogger();
315
- const screen = render(
316
- <TextInput
317
- testID="input"
318
- onChangeText={logEvent('changeText')}
319
- onFocus={logEvent('focus')}
320
- onBlur={logEvent('blur')}
321
- />
322
- );
323
-
324
- await userEvent.type(screen.getByTestId('input'), 'abc');
325
-
326
- const eventNames = events.map((event) => event.name);
327
- expect(eventNames).toEqual([
328
- 'focus',
329
- 'changeText',
330
- 'changeText',
331
- 'changeText',
332
- 'blur',
333
- ]);
334
- });
335
- });
@@ -1 +0,0 @@
1
- export { type, TypeOptions } from './type';
@@ -1,41 +0,0 @@
1
- const knownKeys = new Set(['Enter', 'Backspace']);
2
-
3
- export function parseKeys(text: string) {
4
- const result = [];
5
-
6
- let remainingText = text;
7
- while (remainingText) {
8
- const [token, rest] = getNextToken(remainingText);
9
- if (token.length > 1 && !knownKeys.has(token)) {
10
- throw new Error(`Unknown key "${token}" in "${text}"`);
11
- }
12
-
13
- result.push(token);
14
- remainingText = rest;
15
- }
16
-
17
- return result;
18
- }
19
-
20
- function getNextToken(text: string): [string, string] {
21
- // Detect `{{` => escaped `{`
22
- if (text[0] === '{' && text[1] === '{') {
23
- return ['{', text.slice(2)];
24
- }
25
-
26
- // Detect `{key}` => special key
27
- if (text[0] === '{') {
28
- const endIndex = text.indexOf('}');
29
- if (endIndex === -1) {
30
- throw new Error(`Invalid key sequence "${text}"`);
31
- }
32
-
33
- return [text.slice(1, endIndex), text.slice(endIndex + 1)];
34
- }
35
-
36
- if (text[0] === '\n') {
37
- return ['Enter', text.slice(1)];
38
- }
39
-
40
- return [text[0], text.slice(1)];
41
- }
@@ -1,138 +0,0 @@
1
- import { ReactTestInstance } from 'react-test-renderer';
2
- import { isHostTextInput } from '../../helpers/host-component-names';
3
- import { EventBuilder } from '../event-builder';
4
- import { ErrorWithStack } from '../../helpers/errors';
5
- import { isPointerEventEnabled } from '../../helpers/pointer-events';
6
- import { UserEventConfig, UserEventInstance } from '../setup';
7
- import { dispatchEvent, wait, getTextContentSize } from '../utils';
8
-
9
- import { parseKeys } from './parseKeys';
10
-
11
- export interface TypeOptions {
12
- skipPress?: boolean;
13
- submitEditing?: boolean;
14
- }
15
-
16
- export async function type(
17
- this: UserEventInstance,
18
- element: ReactTestInstance,
19
- text: string,
20
- options?: TypeOptions
21
- ): Promise<void> {
22
- if (!isHostTextInput(element)) {
23
- throw new ErrorWithStack(
24
- `type() works only with host "TextInput" elements. Passed element has type "${element.type}".`,
25
- type
26
- );
27
- }
28
-
29
- // Skip events if the element is disabled
30
- if (element.props.editable === false || !isPointerEventEnabled(element)) {
31
- return;
32
- }
33
-
34
- const keys = parseKeys(text);
35
-
36
- if (!options?.skipPress) {
37
- dispatchEvent(element, 'pressIn', EventBuilder.Common.touch());
38
- }
39
-
40
- dispatchEvent(element, 'focus', EventBuilder.Common.focus());
41
-
42
- if (!options?.skipPress) {
43
- await wait(this.config);
44
- dispatchEvent(element, 'pressOut', EventBuilder.Common.touch());
45
- }
46
-
47
- let currentText = element.props.value ?? element.props.defaultValue ?? '';
48
- for (const key of keys) {
49
- const previousText = element.props.value ?? currentText;
50
- currentText = applyKey(previousText, key);
51
-
52
- await emitTypingEvents(
53
- this.config,
54
- element,
55
- key,
56
- currentText,
57
- previousText
58
- );
59
- }
60
-
61
- const finalText = element.props.value ?? currentText;
62
- await wait(this.config);
63
-
64
- if (options?.submitEditing) {
65
- dispatchEvent(
66
- element,
67
- 'submitEditing',
68
- EventBuilder.TextInput.submitEditing(finalText)
69
- );
70
- }
71
-
72
- dispatchEvent(
73
- element,
74
- 'endEditing',
75
- EventBuilder.TextInput.endEditing(finalText)
76
- );
77
-
78
- dispatchEvent(element, 'blur', EventBuilder.Common.blur());
79
- }
80
-
81
- export async function emitTypingEvents(
82
- config: UserEventConfig,
83
- element: ReactTestInstance,
84
- key: string,
85
- currentText: string,
86
- previousText: string
87
- ) {
88
- const isMultiline = element.props.multiline === true;
89
-
90
- await wait(config);
91
- dispatchEvent(element, 'keyPress', EventBuilder.TextInput.keyPress(key));
92
-
93
- // According to the docs only multiline TextInput emits textInput event
94
- // @see: https://github.com/facebook/react-native/blob/42a2898617da1d7a98ef574a5b9e500681c8f738/packages/react-native/Libraries/Components/TextInput/TextInput.d.ts#L754
95
- if (isMultiline) {
96
- dispatchEvent(
97
- element,
98
- 'textInput',
99
- EventBuilder.TextInput.textInput(currentText, previousText)
100
- );
101
- }
102
-
103
- dispatchEvent(element, 'change', EventBuilder.TextInput.change(currentText));
104
- dispatchEvent(element, 'changeText', currentText);
105
-
106
- const selectionRange = {
107
- start: currentText.length,
108
- end: currentText.length,
109
- };
110
- dispatchEvent(
111
- element,
112
- 'selectionChange',
113
- EventBuilder.TextInput.selectionChange(selectionRange)
114
- );
115
-
116
- // According to the docs only multiline TextInput emits contentSizeChange event
117
- // @see: https://reactnative.dev/docs/textinput#oncontentsizechange
118
- if (isMultiline) {
119
- const contentSize = getTextContentSize(currentText);
120
- dispatchEvent(
121
- element,
122
- 'contentSizeChange',
123
- EventBuilder.TextInput.contentSizeChange(contentSize)
124
- );
125
- }
126
- }
127
-
128
- function applyKey(text: string, key: string) {
129
- if (key === 'Enter') {
130
- return `${text}\n`;
131
- }
132
-
133
- if (key === 'Backspace') {
134
- return text.slice(0, -1);
135
- }
136
-
137
- return text + key;
138
- }
@@ -1,41 +0,0 @@
1
- import * as React from 'react';
2
- import { Text } from 'react-native';
3
- import render from '../../../render';
4
- import { dispatchEvent } from '../dispatch-event';
5
- import { EventBuilder } from '../../event-builder';
6
-
7
- const TOUCH_EVENT = EventBuilder.Common.touch();
8
-
9
- describe('dispatchEvent', () => {
10
- it('does dispatch event', () => {
11
- const onPress = jest.fn();
12
- const screen = render(<Text testID="text" onPress={onPress} />);
13
-
14
- dispatchEvent(screen.getByTestId('text'), 'press', TOUCH_EVENT);
15
- expect(onPress).toHaveBeenCalledTimes(1);
16
- });
17
-
18
- it('does not dispatch event to parent host component', () => {
19
- const onPressParent = jest.fn();
20
- const screen = render(
21
- <Text onPress={onPressParent}>
22
- <Text testID="text" />
23
- </Text>
24
- );
25
-
26
- dispatchEvent(screen.getByTestId('text'), 'press', TOUCH_EVENT);
27
- expect(onPressParent).not.toHaveBeenCalled();
28
- });
29
-
30
- it('does NOT throw if no handler found', () => {
31
- const screen = render(
32
- <Text>
33
- <Text testID="text" />
34
- </Text>
35
- );
36
-
37
- expect(() =>
38
- dispatchEvent(screen.getByTestId('text'), 'press', TOUCH_EVENT)
39
- ).not.toThrow();
40
- });
41
- });