@testing-library/react-native 12.1.2 → 12.1.3

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 (363) hide show
  1. package/.DS_Store +0 -0
  2. package/.codecov.yml +9 -0
  3. package/.eslintcache +1 -0
  4. package/.eslintignore +2 -0
  5. package/.eslintrc +19 -0
  6. package/.flowconfig +63 -0
  7. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  8. package/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
  9. package/.github/ISSUE_TEMPLATE/question.md +9 -0
  10. package/.github/PULL_REQUEST_TEMPLATE.md +10 -0
  11. package/.github/actions/setup-deps/action.yml +22 -0
  12. package/.github/actions/setup-website-deps/action.yml +22 -0
  13. package/.github/dependabot.yml +10 -0
  14. package/.github/workflows/deploy-website.yml +36 -0
  15. package/.github/workflows/example-apps.yml +25 -0
  16. package/.github/workflows/main.yml +103 -0
  17. package/.gitignore +11 -0
  18. package/.prettierrc.js +5 -0
  19. package/CODE_OF_CONDUCT.md +73 -0
  20. package/CONTRIBUTING.md +64 -0
  21. package/README.md +8 -7
  22. package/babel.config.js +22 -0
  23. package/build/act.js.map +1 -1
  24. package/build/cleanup.js.map +1 -1
  25. package/build/fireEvent.d.ts +9 -1
  26. package/build/fireEvent.js +9 -15
  27. package/build/fireEvent.js.map +1 -1
  28. package/build/flush-micro-tasks.d.ts +19 -0
  29. package/build/flush-micro-tasks.js +36 -0
  30. package/build/flush-micro-tasks.js.map +1 -0
  31. package/build/helpers/accessiblity.js +2 -2
  32. package/build/helpers/accessiblity.js.map +1 -1
  33. package/build/helpers/component-tree.js.map +1 -1
  34. package/build/helpers/deprecation.js.map +1 -1
  35. package/build/helpers/errors.js.map +1 -1
  36. package/build/helpers/findAll.js.map +1 -1
  37. package/build/helpers/format-default.js.map +1 -1
  38. package/build/helpers/format.js.map +1 -1
  39. package/build/helpers/host-component-names.js.map +1 -1
  40. package/build/helpers/matchers/matchLabelText.js.map +1 -1
  41. package/build/helpers/pointer-events.d.ts +9 -0
  42. package/build/helpers/pointer-events.js +25 -0
  43. package/build/helpers/pointer-events.js.map +1 -0
  44. package/build/helpers/stringValidation.js.map +1 -1
  45. package/build/helpers/timers.js.map +1 -1
  46. package/build/index.js +2 -2
  47. package/build/index.js.map +1 -1
  48. package/build/matches.js.map +1 -1
  49. package/build/pure.d.ts +1 -1
  50. package/build/pure.js.map +1 -1
  51. package/build/queries/a11yState.js.map +1 -1
  52. package/build/queries/a11yValue.js.map +1 -1
  53. package/build/queries/displayValue.js.map +1 -1
  54. package/build/queries/hintText.js.map +1 -1
  55. package/build/queries/labelText.js.map +1 -1
  56. package/build/queries/makeQueries.js.map +1 -1
  57. package/build/queries/placeholderText.js.map +1 -1
  58. package/build/queries/role.js.map +1 -1
  59. package/build/queries/testId.js.map +1 -1
  60. package/build/queries/text.js.map +1 -1
  61. package/build/queries/unsafeProps.js.map +1 -1
  62. package/build/render.d.ts +171 -12
  63. package/build/render.js +11 -4
  64. package/build/render.js.map +1 -1
  65. package/build/renderHook.d.ts +3 -6
  66. package/build/renderHook.js +4 -3
  67. package/build/renderHook.js.map +1 -1
  68. package/build/shallow.js.map +1 -1
  69. package/build/test-utils/events.d.ts +10 -0
  70. package/build/test-utils/events.js +27 -0
  71. package/build/test-utils/events.js.map +1 -0
  72. package/build/test-utils/index.d.ts +1 -0
  73. package/build/test-utils/index.js +17 -0
  74. package/build/test-utils/index.js.map +1 -0
  75. package/build/user-event/event-builder/common.d.ts +45 -0
  76. package/build/user-event/event-builder/common.js +58 -0
  77. package/build/user-event/event-builder/common.js.map +1 -0
  78. package/build/user-event/event-builder/index.d.ts +32 -0
  79. package/build/user-event/event-builder/index.js +12 -0
  80. package/build/user-event/event-builder/index.js.map +1 -0
  81. package/build/user-event/index.d.ts +9 -0
  82. package/build/user-event/index.js +16 -0
  83. package/build/user-event/index.js.map +1 -0
  84. package/build/user-event/press/constants.d.ts +2 -0
  85. package/build/user-event/press/constants.js +16 -0
  86. package/build/user-event/press/constants.js.map +1 -0
  87. package/build/user-event/press/index.d.ts +1 -0
  88. package/build/user-event/press/index.js +19 -0
  89. package/build/user-event/press/index.js.map +1 -0
  90. package/build/user-event/press/press.d.ts +7 -0
  91. package/build/user-event/press/press.js +106 -0
  92. package/build/user-event/press/press.js.map +1 -0
  93. package/build/user-event/press/utils/warnAboutRealTimers.d.ts +1 -0
  94. package/build/user-event/press/utils/warnAboutRealTimers.js +14 -0
  95. package/build/user-event/press/utils/warnAboutRealTimers.js.map +1 -0
  96. package/build/user-event/setup/index.d.ts +2 -0
  97. package/build/user-event/setup/index.js +13 -0
  98. package/build/user-event/setup/index.js.map +1 -0
  99. package/build/user-event/setup/setup.d.ts +39 -0
  100. package/build/user-event/setup/setup.js +56 -0
  101. package/build/user-event/setup/setup.js.map +1 -0
  102. package/build/user-event/type/index.d.ts +1 -0
  103. package/build/user-event/type/index.js +13 -0
  104. package/build/user-event/type/index.js.map +1 -0
  105. package/build/user-event/type/type.d.ts +3 -0
  106. package/build/user-event/type/type.js +18 -0
  107. package/build/user-event/type/type.js.map +1 -0
  108. package/build/user-event/utils/events.d.ts +9 -0
  109. package/build/user-event/utils/events.js +44 -0
  110. package/build/user-event/utils/events.js.map +1 -0
  111. package/build/user-event/utils/index.d.ts +2 -0
  112. package/build/user-event/utils/index.js +28 -0
  113. package/build/user-event/utils/index.js.map +1 -0
  114. package/build/user-event/utils/wait.d.ts +2 -0
  115. package/build/user-event/utils/wait.js +14 -0
  116. package/build/user-event/utils/wait.js.map +1 -0
  117. package/build/waitFor.js +3 -3
  118. package/build/waitFor.js.map +1 -1
  119. package/build/waitForElementToBeRemoved.js.map +1 -1
  120. package/examples/basic/.expo-shared/assets.json +4 -0
  121. package/examples/basic/.gitignore +14 -0
  122. package/examples/basic/App.tsx +20 -0
  123. package/examples/basic/README.md +11 -0
  124. package/examples/basic/__tests__/App.test.tsx +119 -0
  125. package/examples/basic/app.json +31 -0
  126. package/examples/basic/assets/adaptive-icon.png +0 -0
  127. package/examples/basic/assets/favicon.png +0 -0
  128. package/examples/basic/assets/icon.png +0 -0
  129. package/examples/basic/assets/splash.png +0 -0
  130. package/examples/basic/babel.config.js +6 -0
  131. package/examples/basic/components/Home.tsx +28 -0
  132. package/examples/basic/components/LoginForm.tsx +138 -0
  133. package/examples/basic/jest-setup.ts +7 -0
  134. package/examples/basic/jest.config.js +5 -0
  135. package/examples/basic/package.json +30 -0
  136. package/examples/basic/tsconfig.json +7 -0
  137. package/examples/react-navigation/README.md +14 -0
  138. package/examples/react-navigation/babel.config.js +4 -0
  139. package/examples/react-navigation/jest-setup.js +11 -0
  140. package/examples/react-navigation/jest.config.js +10 -0
  141. package/examples/react-navigation/package.json +31 -0
  142. package/examples/react-navigation/src/App.js +21 -0
  143. package/examples/react-navigation/src/DrawerNavigator.js +15 -0
  144. package/examples/react-navigation/src/DrawerNavigator.test.js +42 -0
  145. package/examples/react-navigation/src/NativeStackNavigator.js +15 -0
  146. package/examples/react-navigation/src/NativeStackNavigator.test.js +34 -0
  147. package/examples/react-navigation/src/StackNavigator.js +15 -0
  148. package/examples/react-navigation/src/StackNavigator.test.js +34 -0
  149. package/examples/react-navigation/src/TabNavigator.js +15 -0
  150. package/examples/react-navigation/src/TabNavigator.test.js +21 -0
  151. package/examples/react-navigation/src/screens/DetailsScreen.js +43 -0
  152. package/examples/react-navigation/src/screens/DetailsScreen.test.js +27 -0
  153. package/examples/react-navigation/src/screens/DrawerHomeScreen.js +26 -0
  154. package/examples/react-navigation/src/screens/HomeScreen.js +48 -0
  155. package/examples/react-navigation/src/screens/SettingsScreen.js +20 -0
  156. package/examples/react-navigation/src/test-utils.js +12 -0
  157. package/examples/redux/App.js +27 -0
  158. package/examples/redux/actions/todoActions.js +25 -0
  159. package/examples/redux/babel.config.js +6 -0
  160. package/examples/redux/components/AddTodo.js +73 -0
  161. package/examples/redux/components/AddTodo.test.js +27 -0
  162. package/examples/redux/components/TodoElem.js +25 -0
  163. package/examples/redux/components/TodoList.js +29 -0
  164. package/examples/redux/components/TodoList.test.js +34 -0
  165. package/examples/redux/index.js +8 -0
  166. package/examples/redux/jest-setup.js +2 -0
  167. package/examples/redux/jest.config.js +4 -0
  168. package/examples/redux/package.json +23 -0
  169. package/examples/redux/reducers/index.js +6 -0
  170. package/examples/redux/reducers/todoReducer.js +27 -0
  171. package/examples/redux/store.js +10 -0
  172. package/examples/redux/test-utils.js +11 -0
  173. package/experiments-app/.expo/README.md +15 -0
  174. package/experiments-app/.expo/devices.json +3 -0
  175. package/experiments-app/.expo/packager-info.json +9 -0
  176. package/experiments-app/.expo/settings.json +9 -0
  177. package/experiments-app/.gitignore +17 -0
  178. package/experiments-app/.prettierrc.js +5 -0
  179. package/experiments-app/app.json +30 -0
  180. package/experiments-app/assets/adaptive-icon.png +0 -0
  181. package/experiments-app/assets/favicon.png +0 -0
  182. package/experiments-app/assets/icon.png +0 -0
  183. package/experiments-app/assets/splash.png +0 -0
  184. package/experiments-app/babel.config.js +6 -0
  185. package/experiments-app/index.js +4 -0
  186. package/experiments-app/package.json +31 -0
  187. package/experiments-app/src/App.tsx +31 -0
  188. package/experiments-app/src/MainScreen.tsx +51 -0
  189. package/experiments-app/src/experiments.ts +17 -0
  190. package/experiments-app/src/screens/TextInputEventPropagation.tsx +54 -0
  191. package/experiments-app/src/screens/TextInputEvents.tsx +50 -0
  192. package/experiments-app/src/utils/helpers.ts +8 -0
  193. package/experiments-app/tsconfig.json +6 -0
  194. package/experiments-app/yarn.lock +6913 -0
  195. package/flow-typed/npm/jest_v26.x.x.js +1218 -0
  196. package/flow-typed/npm/react-test-renderer_v16.x.x.js +81 -0
  197. package/jest-setup.ts +10 -0
  198. package/package.json +6 -6
  199. package/renovate.json +19 -0
  200. package/scripts/test_react_17 +12 -0
  201. package/src/__tests__/__snapshots__/render-debug.test.tsx.snap +548 -0
  202. package/src/__tests__/__snapshots__/render.test.tsx.snap +39 -0
  203. package/src/__tests__/act.test.tsx +52 -0
  204. package/src/__tests__/auto-cleanup-skip.test.tsx +39 -0
  205. package/src/__tests__/auto-cleanup.test.tsx +50 -0
  206. package/src/__tests__/cleanup.test.tsx +26 -0
  207. package/src/__tests__/config.test.ts +55 -0
  208. package/src/__tests__/fireEvent-textInput.test.tsx +154 -0
  209. package/src/__tests__/fireEvent.test.tsx +485 -0
  210. package/src/__tests__/host-component-names.test.tsx +109 -0
  211. package/src/__tests__/host-text-nesting.test.tsx +90 -0
  212. package/src/__tests__/jest-native.test.tsx +84 -0
  213. package/src/__tests__/questionsBoard.test.tsx +62 -0
  214. package/src/__tests__/react-native-api.test.tsx +126 -0
  215. package/src/__tests__/render-debug.test.tsx +207 -0
  216. package/src/__tests__/render-stringValidation.test.tsx +157 -0
  217. package/src/__tests__/render.test.tsx +256 -0
  218. package/src/__tests__/renderHook.test.tsx +114 -0
  219. package/src/__tests__/screen.test.tsx +66 -0
  220. package/src/__tests__/timerUtils.ts +7 -0
  221. package/src/__tests__/timers.test.ts +27 -0
  222. package/src/__tests__/waitFor.test.tsx +327 -0
  223. package/src/__tests__/waitForElementToBeRemoved.test.tsx +151 -0
  224. package/src/__tests__/within.test.tsx +96 -0
  225. package/src/act.ts +86 -0
  226. package/src/cleanup.ts +15 -0
  227. package/src/config.ts +72 -0
  228. package/src/fireEvent.ts +163 -0
  229. package/src/flush-micro-tasks.ts +30 -0
  230. package/src/helpers/__tests__/accessiblity.test.tsx +373 -0
  231. package/src/helpers/__tests__/component-tree.test.tsx +226 -0
  232. package/src/helpers/__tests__/format-default.tsx +114 -0
  233. package/src/helpers/__tests__/getTextContent.test.tsx +49 -0
  234. package/src/helpers/__tests__/includeHiddenElements.test.tsx +39 -0
  235. package/src/helpers/__tests__/query-name.test.ts +10 -0
  236. package/src/helpers/__tests__/timers.test.ts +8 -0
  237. package/src/helpers/accessiblity.ts +108 -0
  238. package/src/helpers/component-tree.ts +89 -0
  239. package/src/helpers/debugDeep.ts +27 -0
  240. package/src/helpers/debugShallow.ts +22 -0
  241. package/src/helpers/deprecation.ts +53 -0
  242. package/src/helpers/errors.ts +66 -0
  243. package/src/helpers/filterNodeByType.ts +7 -0
  244. package/src/helpers/findAll.ts +68 -0
  245. package/src/helpers/format-default.ts +72 -0
  246. package/src/helpers/format.ts +47 -0
  247. package/src/helpers/getTextContent.ts +20 -0
  248. package/src/helpers/host-component-names.tsx +67 -0
  249. package/src/helpers/matchers/__tests__/matchArrayValue.test.ts +34 -0
  250. package/src/helpers/matchers/__tests__/matchObject.test.ts +37 -0
  251. package/src/helpers/matchers/__tests__/matchStringValue.test.ts +15 -0
  252. package/src/helpers/matchers/accessibilityState.ts +48 -0
  253. package/src/helpers/matchers/accessibilityValue.ts +24 -0
  254. package/src/helpers/matchers/matchArrayProp.ts +21 -0
  255. package/src/helpers/matchers/matchLabelText.ts +51 -0
  256. package/src/helpers/matchers/matchObjectProp.ts +25 -0
  257. package/src/helpers/matchers/matchStringProp.ts +23 -0
  258. package/src/helpers/matchers/matchTextContent.ts +20 -0
  259. package/src/helpers/pointer-events.ts +27 -0
  260. package/src/helpers/query-name.ts +4 -0
  261. package/src/helpers/stringValidation.ts +36 -0
  262. package/src/helpers/timers.ts +98 -0
  263. package/src/index.ts +33 -0
  264. package/src/matches.ts +49 -0
  265. package/src/pure.ts +25 -0
  266. package/src/queries/__tests__/a11yState.test.tsx +439 -0
  267. package/src/queries/__tests__/a11yValue.test.tsx +309 -0
  268. package/src/queries/__tests__/displayValue.test.tsx +221 -0
  269. package/src/queries/__tests__/hintText.test.tsx +177 -0
  270. package/src/queries/__tests__/labelText.test.tsx +242 -0
  271. package/src/queries/__tests__/makeQueries.test.tsx +235 -0
  272. package/src/queries/__tests__/placeholderText.test.tsx +136 -0
  273. package/src/queries/__tests__/role-value.test.tsx +176 -0
  274. package/src/queries/__tests__/role.test.tsx +824 -0
  275. package/src/queries/__tests__/testId.test.tsx +200 -0
  276. package/src/queries/__tests__/text.test.tsx +556 -0
  277. package/src/queries/a11yState.ts +131 -0
  278. package/src/queries/a11yValue.ts +131 -0
  279. package/src/queries/displayValue.ts +78 -0
  280. package/src/queries/hintText.ts +112 -0
  281. package/src/queries/labelText.ts +59 -0
  282. package/src/queries/makeQueries.ts +255 -0
  283. package/src/queries/options.ts +14 -0
  284. package/src/queries/placeholderText.ts +79 -0
  285. package/src/queries/role.ts +132 -0
  286. package/src/queries/testId.ts +71 -0
  287. package/src/queries/text.ts +66 -0
  288. package/src/queries/unsafeProps.ts +76 -0
  289. package/src/queries/unsafeType.ts +73 -0
  290. package/src/react-versions.ts +11 -0
  291. package/src/render-act.ts +19 -0
  292. package/src/render.tsx +183 -0
  293. package/src/renderHook.tsx +56 -0
  294. package/src/screen.ts +123 -0
  295. package/src/shallow.ts +18 -0
  296. package/src/test-utils/events.ts +24 -0
  297. package/src/test-utils/index.ts +1 -0
  298. package/src/user-event/event-builder/common.ts +50 -0
  299. package/src/user-event/event-builder/index.ts +5 -0
  300. package/src/user-event/index.ts +14 -0
  301. package/src/user-event/press/__tests__/longPress.real-timers.test.tsx +115 -0
  302. package/src/user-event/press/__tests__/longPress.test.tsx +157 -0
  303. package/src/user-event/press/__tests__/press.real-timers.test.tsx +318 -0
  304. package/src/user-event/press/__tests__/press.test.tsx +422 -0
  305. package/src/user-event/press/constants.ts +7 -0
  306. package/src/user-event/press/index.ts +1 -0
  307. package/src/user-event/press/press.ts +134 -0
  308. package/src/user-event/press/utils/warnAboutRealTimers.ts +6 -0
  309. package/src/user-event/setup/index.ts +2 -0
  310. package/src/user-event/setup/setup.ts +93 -0
  311. package/src/user-event/type/__tests__/__snapshots__/type.test.tsx.snap +26 -0
  312. package/src/user-event/type/__tests__/type.test.tsx +63 -0
  313. package/src/user-event/type/index.ts +1 -0
  314. package/src/user-event/type/type.ts +20 -0
  315. package/src/user-event/utils/__tests__/wait.test.ts +63 -0
  316. package/src/user-event/utils/events.ts +54 -0
  317. package/src/user-event/utils/index.ts +2 -0
  318. package/src/user-event/utils/wait.ts +15 -0
  319. package/src/waitFor.ts +228 -0
  320. package/src/waitForElementToBeRemoved.ts +42 -0
  321. package/src/within.ts +30 -0
  322. package/tsconfig.json +17 -0
  323. package/tsconfig.release.json +8 -0
  324. package/website/.gitignore +20 -0
  325. package/website/README.md +33 -0
  326. package/website/docker/.dockerignore +3 -0
  327. package/website/docker/Dockerfile +9 -0
  328. package/website/docker/docker-compose.yml +11 -0
  329. package/website/docs/API.md +946 -0
  330. package/website/docs/EslintPLluginTestingLibrary.md +28 -0
  331. package/website/docs/FAQ.md +44 -0
  332. package/website/docs/GettingStarted.md +100 -0
  333. package/website/docs/HowShouldIQuery.md +21 -0
  334. package/website/docs/MigrationV11.md +64 -0
  335. package/website/docs/MigrationV12.md +67 -0
  336. package/website/docs/MigrationV2.md +126 -0
  337. package/website/docs/MigrationV7.md +119 -0
  338. package/website/docs/MigrationV9.md +67 -0
  339. package/website/docs/Queries.md +567 -0
  340. package/website/docs/ReactNavigation.md +371 -0
  341. package/website/docs/ReduxIntegration.md +137 -0
  342. package/website/docs/TestingEnvironment.md +154 -0
  343. package/website/docs/Troubleshooting.md +44 -0
  344. package/website/docs/UnderstandingAct.md +227 -0
  345. package/website/docs/UserEvent.md +66 -0
  346. package/website/docusaurus.config.js +114 -0
  347. package/website/package.json +31 -0
  348. package/website/sidebars.js +20 -0
  349. package/website/src/components/Feature.js +31 -0
  350. package/website/src/css/custom.css +13 -0
  351. package/website/src/css/index.module.css +77 -0
  352. package/website/src/pages/index.js +82 -0
  353. package/website/static/.nojekyll +0 -0
  354. package/website/static/css/custom.css +28 -0
  355. package/website/static/img/hit.png +0 -0
  356. package/website/static/img/locomotive.png +0 -0
  357. package/website/static/img/owl.png +0 -0
  358. package/website/static/img/tools.png +0 -0
  359. package/website/yarn.lock +7669 -0
  360. package/yarn.lock +7765 -0
  361. package/build/flushMicroTasks.d.ts +0 -5
  362. package/build/flushMicroTasks.js +0 -17
  363. package/build/flushMicroTasks.js.map +0 -1
@@ -0,0 +1,242 @@
1
+ import * as React from 'react';
2
+ import { View, Text, TextInput, TouchableOpacity } from 'react-native';
3
+ import { render } from '../..';
4
+
5
+ const BUTTON_LABEL = 'cool button';
6
+ const BUTTON_HINT = 'click this button';
7
+ const TEXT_LABEL = 'cool text';
8
+ const TEXT_HINT = 'static text';
9
+ // Little hack to make all the methods happy with type
10
+ const NO_MATCHES_TEXT: any = 'not-existent-element';
11
+
12
+ const getMultipleInstancesFoundMessage = (value: string) => {
13
+ return `Found multiple elements with accessibilityLabel: ${value}`;
14
+ };
15
+
16
+ const getNoInstancesFoundMessage = (value: string) => {
17
+ return `Unable to find an element with accessibilityLabel: ${value}`;
18
+ };
19
+
20
+ const Typography = ({ children, ...rest }: any) => {
21
+ return <Text {...rest}>{children}</Text>;
22
+ };
23
+
24
+ const Button = ({ children }: { children: React.ReactNode }) => (
25
+ <TouchableOpacity
26
+ accessibilityHint={BUTTON_HINT}
27
+ accessibilityLabel={BUTTON_LABEL}
28
+ >
29
+ <Typography accessibilityHint={TEXT_HINT} accessibilityLabel={TEXT_LABEL}>
30
+ {children}
31
+ </Typography>
32
+ </TouchableOpacity>
33
+ );
34
+
35
+ const Section = () => (
36
+ <>
37
+ <Typography accessibilityHint={TEXT_HINT} accessibilityLabel={TEXT_LABEL}>
38
+ Title
39
+ </Typography>
40
+ <Button>{TEXT_LABEL}</Button>
41
+ </>
42
+ );
43
+
44
+ test('getByLabelText, queryByLabelText, findByLabelText', async () => {
45
+ const { getByLabelText, queryByLabelText, findByLabelText } = render(
46
+ <Section />
47
+ );
48
+
49
+ expect(getByLabelText(BUTTON_LABEL).props.accessibilityLabel).toEqual(
50
+ BUTTON_LABEL
51
+ );
52
+ const button = queryByLabelText(/button/g);
53
+ expect(button?.props.accessibilityLabel).toEqual(BUTTON_LABEL);
54
+
55
+ expect(() => getByLabelText(NO_MATCHES_TEXT)).toThrow(
56
+ getNoInstancesFoundMessage(NO_MATCHES_TEXT)
57
+ );
58
+ expect(queryByLabelText(NO_MATCHES_TEXT)).toBeNull();
59
+
60
+ expect(() => getByLabelText(TEXT_LABEL)).toThrow(
61
+ getMultipleInstancesFoundMessage(TEXT_LABEL)
62
+ );
63
+ expect(() => queryByLabelText(TEXT_LABEL)).toThrow(
64
+ getMultipleInstancesFoundMessage(TEXT_LABEL)
65
+ );
66
+
67
+ const asyncButton = await findByLabelText(BUTTON_LABEL);
68
+ expect(asyncButton.props.accessibilityLabel).toEqual(BUTTON_LABEL);
69
+ await expect(findByLabelText(NO_MATCHES_TEXT)).rejects.toThrow(
70
+ getNoInstancesFoundMessage(NO_MATCHES_TEXT)
71
+ );
72
+
73
+ await expect(findByLabelText(TEXT_LABEL)).rejects.toThrow(
74
+ getMultipleInstancesFoundMessage(TEXT_LABEL)
75
+ );
76
+ });
77
+
78
+ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText', async () => {
79
+ const { getAllByLabelText, queryAllByLabelText, findAllByLabelText } = render(
80
+ <Section />
81
+ );
82
+
83
+ expect(getAllByLabelText(TEXT_LABEL)).toHaveLength(2);
84
+ expect(queryAllByLabelText(/cool/g)).toHaveLength(3);
85
+
86
+ expect(() => getAllByLabelText(NO_MATCHES_TEXT)).toThrow(
87
+ getNoInstancesFoundMessage(NO_MATCHES_TEXT)
88
+ );
89
+ expect(queryAllByLabelText(NO_MATCHES_TEXT)).toEqual([]);
90
+
91
+ await expect(findAllByLabelText(TEXT_LABEL)).resolves.toHaveLength(2);
92
+ await expect(findAllByLabelText(NO_MATCHES_TEXT)).rejects.toThrow(
93
+ getNoInstancesFoundMessage(NO_MATCHES_TEXT)
94
+ );
95
+ });
96
+
97
+ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText with exact as false', async () => {
98
+ const { getAllByLabelText, queryAllByLabelText, findAllByLabelText } = render(
99
+ <Section />
100
+ );
101
+
102
+ expect(getAllByLabelText(TEXT_LABEL, { exact: false })).toHaveLength(2);
103
+ expect(queryAllByLabelText(/cool/g, { exact: false })).toHaveLength(3);
104
+
105
+ expect(() => getAllByLabelText(NO_MATCHES_TEXT, { exact: false })).toThrow(
106
+ getNoInstancesFoundMessage(NO_MATCHES_TEXT)
107
+ );
108
+ expect(queryAllByLabelText(NO_MATCHES_TEXT, { exact: false })).toEqual([]);
109
+
110
+ await expect(
111
+ findAllByLabelText(TEXT_LABEL, { exact: false })
112
+ ).resolves.toHaveLength(2);
113
+ await expect(
114
+ findAllByLabelText(NO_MATCHES_TEXT, { exact: false })
115
+ ).rejects.toThrow(getNoInstancesFoundMessage(NO_MATCHES_TEXT));
116
+ });
117
+
118
+ describe('findBy options deprecations', () => {
119
+ let warnSpy: jest.SpyInstance;
120
+ beforeEach(() => {
121
+ warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
122
+ });
123
+ afterEach(() => {
124
+ warnSpy.mockRestore();
125
+ });
126
+
127
+ test('findByText queries warn on deprecated use of WaitForOptions', async () => {
128
+ const options = { timeout: 10 };
129
+ // mock implementation to avoid warning in the test suite
130
+ const view = render(<View />);
131
+ await expect(
132
+ view.findByLabelText('Some Text', options)
133
+ ).rejects.toBeTruthy();
134
+
135
+ setTimeout(
136
+ () => view.rerender(<View accessibilityLabel="Some Text" />),
137
+ 20
138
+ );
139
+ await expect(view.findByLabelText('Some Text')).resolves.toBeTruthy();
140
+
141
+ expect(warnSpy).toHaveBeenCalledWith(
142
+ expect.stringContaining('Use of option "timeout"')
143
+ );
144
+ }, 20000);
145
+ });
146
+
147
+ test('byLabelText queries support hidden option', () => {
148
+ const { getByLabelText, queryByLabelText } = render(
149
+ <Text accessibilityLabel="hidden" style={{ display: 'none' }}>
150
+ Hidden from accessibility
151
+ </Text>
152
+ );
153
+
154
+ expect(
155
+ getByLabelText('hidden', { includeHiddenElements: true })
156
+ ).toBeTruthy();
157
+
158
+ expect(queryByLabelText('hidden')).toBeFalsy();
159
+ expect(
160
+ queryByLabelText('hidden', { includeHiddenElements: false })
161
+ ).toBeFalsy();
162
+ expect(() => getByLabelText('hidden', { includeHiddenElements: false }))
163
+ .toThrowErrorMatchingInlineSnapshot(`
164
+ "Unable to find an element with accessibilityLabel: hidden
165
+
166
+ <Text
167
+ accessibilityLabel="hidden"
168
+ style={
169
+ {
170
+ "display": "none",
171
+ }
172
+ }
173
+ >
174
+ Hidden from accessibility
175
+ </Text>"
176
+ `);
177
+ });
178
+
179
+ test('getByLabelText supports accessibilityLabelledBy', async () => {
180
+ const { getByLabelText, getByTestId } = render(
181
+ <>
182
+ <Text nativeID="label">Label for input</Text>
183
+ <TextInput testID="textInput" accessibilityLabelledBy="label" />
184
+ </>
185
+ );
186
+
187
+ expect(getByLabelText('Label for input')).toBe(getByTestId('textInput'));
188
+ expect(getByLabelText(/input/)).toBe(getByTestId('textInput'));
189
+ });
190
+
191
+ test('getByLabelText supports nested accessibilityLabelledBy', async () => {
192
+ const { getByLabelText, getByTestId } = render(
193
+ <>
194
+ <View nativeID="label">
195
+ <Text>Label for input</Text>
196
+ </View>
197
+ <TextInput testID="textInput" accessibilityLabelledBy="label" />
198
+ </>
199
+ );
200
+
201
+ expect(getByLabelText('Label for input')).toBe(getByTestId('textInput'));
202
+ expect(getByLabelText(/input/)).toBe(getByTestId('textInput'));
203
+ });
204
+
205
+ test('error message renders the element tree, preserving only helpful props', async () => {
206
+ const view = render(<TouchableOpacity accessibilityLabel="LABEL" key="3" />);
207
+
208
+ expect(() => view.getByLabelText('FOO')).toThrowErrorMatchingInlineSnapshot(`
209
+ "Unable to find an element with accessibilityLabel: FOO
210
+
211
+ <View
212
+ accessibilityLabel="LABEL"
213
+ />"
214
+ `);
215
+
216
+ expect(() => view.getAllByLabelText('FOO'))
217
+ .toThrowErrorMatchingInlineSnapshot(`
218
+ "Unable to find an element with accessibilityLabel: FOO
219
+
220
+ <View
221
+ accessibilityLabel="LABEL"
222
+ />"
223
+ `);
224
+
225
+ await expect(view.findByLabelText('FOO')).rejects
226
+ .toThrowErrorMatchingInlineSnapshot(`
227
+ "Unable to find an element with accessibilityLabel: FOO
228
+
229
+ <View
230
+ accessibilityLabel="LABEL"
231
+ />"
232
+ `);
233
+
234
+ await expect(view.findAllByLabelText('FOO')).rejects
235
+ .toThrowErrorMatchingInlineSnapshot(`
236
+ "Unable to find an element with accessibilityLabel: FOO
237
+
238
+ <View
239
+ accessibilityLabel="LABEL"
240
+ />"
241
+ `);
242
+ });
@@ -0,0 +1,235 @@
1
+ import * as React from 'react';
2
+ import { Text, TextInput, View } from 'react-native';
3
+ import { render, screen } from '../..';
4
+
5
+ describe('printing element tree', () => {
6
+ test('includes element tree on error with less-helpful props stripped', async () => {
7
+ const { getByText } = render(<Text onPress={() => null}>Some text</Text>);
8
+
9
+ expect(() => getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
10
+ "Unable to find an element with text: /foo/
11
+
12
+ <Text>
13
+ Some text
14
+ </Text>"
15
+ `);
16
+ });
17
+
18
+ test('prints helpful props but not others', async () => {
19
+ const { getByText } = render(
20
+ <View
21
+ accessibilityElementsHidden
22
+ accessibilityViewIsModal
23
+ importantForAccessibility="yes"
24
+ testID="TEST_ID"
25
+ nativeID="NATIVE_ID"
26
+ accessibilityLabel="LABEL"
27
+ accessibilityLabelledBy="LABELLED_BY"
28
+ accessibilityRole="summary"
29
+ accessibilityHint="HINT"
30
+ key="this is filtered"
31
+ >
32
+ <TextInput
33
+ placeholder="PLACEHOLDER"
34
+ value="VALUE"
35
+ defaultValue="DEFAULT_VALUE"
36
+ />
37
+ <Text>Some Text</Text>
38
+ </View>
39
+ );
40
+
41
+ expect(() => getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
42
+ "Unable to find an element with text: /foo/
43
+
44
+ <View
45
+ accessibilityElementsHidden={true}
46
+ accessibilityHint="HINT"
47
+ accessibilityLabel="LABEL"
48
+ accessibilityLabelledBy="LABELLED_BY"
49
+ accessibilityRole="summary"
50
+ accessibilityViewIsModal={true}
51
+ importantForAccessibility="yes"
52
+ nativeID="NATIVE_ID"
53
+ testID="TEST_ID"
54
+ >
55
+ <TextInput
56
+ defaultValue="DEFAULT_VALUE"
57
+ placeholder="PLACEHOLDER"
58
+ value="VALUE"
59
+ />
60
+ <Text>
61
+ Some Text
62
+ </Text>
63
+ </View>"
64
+ `);
65
+ });
66
+
67
+ test('prints tree and filters props with getBy, getAllBy, findBy, findAllBy', async () => {
68
+ const view = render(
69
+ <View accessibilityViewIsModal key="this is filtered" />
70
+ );
71
+
72
+ expect(() => view.getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
73
+ "Unable to find an element with text: /foo/
74
+
75
+ <View
76
+ accessibilityViewIsModal={true}
77
+ />"
78
+ `);
79
+
80
+ expect(() => view.getAllByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
81
+ "Unable to find an element with text: /foo/
82
+
83
+ <View
84
+ accessibilityViewIsModal={true}
85
+ />"
86
+ `);
87
+
88
+ await expect(view.findByText(/foo/)).rejects
89
+ .toThrowErrorMatchingInlineSnapshot(`
90
+ "Unable to find an element with text: /foo/
91
+
92
+ <View
93
+ accessibilityViewIsModal={true}
94
+ />"
95
+ `);
96
+
97
+ await expect(view.findAllByText(/foo/)).rejects
98
+ .toThrowErrorMatchingInlineSnapshot(`
99
+ "Unable to find an element with text: /foo/
100
+
101
+ <View
102
+ accessibilityViewIsModal={true}
103
+ />"
104
+ `);
105
+ });
106
+
107
+ test('only appends element tree on last failure with findBy', async () => {
108
+ const { findByText } = render(
109
+ <View accessibilityViewIsModal key="this is filtered" />
110
+ );
111
+
112
+ jest.spyOn(screen, 'toJSON');
113
+
114
+ await expect(findByText(/foo/)).rejects.toThrow();
115
+
116
+ expect(screen.toJSON).toHaveBeenCalledTimes(1);
117
+ });
118
+
119
+ test('onTimeout with findBy receives error without element tree', async () => {
120
+ const { findByText } = render(<View />);
121
+
122
+ const onTimeout = jest.fn((_: Error) => new Error('Replacement error'));
123
+
124
+ await expect(() =>
125
+ findByText(/foo/, undefined, { onTimeout })
126
+ ).rejects.toThrowErrorMatchingInlineSnapshot(`"Replacement error"`);
127
+
128
+ expect(onTimeout).toHaveBeenCalledTimes(1);
129
+ expect(onTimeout.mock.calls[0][0].message).not.toMatch(/View/);
130
+ expect(onTimeout.mock.calls[0][0].message).toMatchInlineSnapshot(
131
+ `"Unable to find an element with text: /foo/"`
132
+ );
133
+ });
134
+
135
+ test('onTimeout with findAllBy receives error without element tree', async () => {
136
+ const { findAllByText } = render(<View />);
137
+
138
+ const onTimeout = jest.fn((_: Error) => new Error('Replacement error'));
139
+
140
+ await expect(() =>
141
+ findAllByText(/foo/, undefined, { onTimeout })
142
+ ).rejects.toThrowErrorMatchingInlineSnapshot(`"Replacement error"`);
143
+
144
+ expect(onTimeout).toHaveBeenCalledTimes(1);
145
+ expect(onTimeout.mock.calls[0][0].message).not.toMatch(/View/);
146
+ expect(onTimeout.mock.calls[0][0].message).toMatchInlineSnapshot(
147
+ `"Unable to find an element with text: /foo/"`
148
+ );
149
+ });
150
+
151
+ test('does not strip display: none from "style" prop, but does strip other styles', () => {
152
+ const { getByText } = render(
153
+ <View style={{ display: 'flex', position: 'absolute' }}>
154
+ <Text
155
+ style={[
156
+ { display: 'flex', position: 'relative' },
157
+ { display: 'none', flex: 1 },
158
+ ]}
159
+ >
160
+ Some text
161
+ </Text>
162
+ </View>
163
+ );
164
+
165
+ expect(() => getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
166
+ "Unable to find an element with text: /foo/
167
+
168
+ <View>
169
+ <Text
170
+ style={
171
+ {
172
+ "display": "none",
173
+ }
174
+ }
175
+ >
176
+ Some text
177
+ </Text>
178
+ </View>"
179
+ `);
180
+ });
181
+
182
+ test('strips undefined values from accessibilityState', () => {
183
+ const { getByText } = render(
184
+ <View accessibilityState={{ checked: true, busy: false }}>
185
+ <View accessibilityState={{ checked: undefined }} />
186
+ </View>
187
+ );
188
+
189
+ expect(() => getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
190
+ "Unable to find an element with text: /foo/
191
+
192
+ <View
193
+ accessibilityState={
194
+ {
195
+ "busy": false,
196
+ "checked": true,
197
+ }
198
+ }
199
+ >
200
+ <View />
201
+ </View>"
202
+ `);
203
+ });
204
+
205
+ test('strips undefined values from accessibilityValue', () => {
206
+ const { getByText } = render(
207
+ <View accessibilityValue={{ min: 1 }}>
208
+ <View accessibilityState={{}} />
209
+ </View>
210
+ );
211
+
212
+ expect(() => getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(`
213
+ "Unable to find an element with text: /foo/
214
+
215
+ <View
216
+ accessibilityValue={
217
+ {
218
+ "min": 1,
219
+ }
220
+ }
221
+ >
222
+ <View />
223
+ </View>"
224
+ `);
225
+ });
226
+
227
+ test('does not render element tree when toJSON() returns null', () => {
228
+ const view = render(<View />);
229
+
230
+ jest.spyOn(screen, 'toJSON').mockImplementation(() => null);
231
+ expect(() => view.getByText(/foo/)).toThrowErrorMatchingInlineSnapshot(
232
+ `"Unable to find an element with text: /foo/"`
233
+ );
234
+ });
235
+ });
@@ -0,0 +1,136 @@
1
+ import * as React from 'react';
2
+ import { View, TextInput } from 'react-native';
3
+ import { render } from '../..';
4
+
5
+ const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
6
+ const PLACEHOLDER_CHEF = 'Who inspected freshness?';
7
+ const INPUT_FRESHNESS = 'Custom Freshie';
8
+ const INPUT_CHEF = 'I inspected freshie';
9
+ const DEFAULT_INPUT_CHEF = 'What did you inspect?';
10
+
11
+ const Banana = () => (
12
+ <View>
13
+ <TextInput
14
+ testID="bananaCustomFreshness"
15
+ placeholder={PLACEHOLDER_FRESHNESS}
16
+ value={INPUT_FRESHNESS}
17
+ />
18
+ <TextInput
19
+ testID="bananaChef"
20
+ placeholder={PLACEHOLDER_CHEF}
21
+ value={INPUT_CHEF}
22
+ defaultValue={DEFAULT_INPUT_CHEF}
23
+ />
24
+ </View>
25
+ );
26
+
27
+ test('getByPlaceholderText, queryByPlaceholderText', () => {
28
+ const { getByPlaceholderText, queryByPlaceholderText } = render(<Banana />);
29
+ const input = getByPlaceholderText(/custom/i);
30
+
31
+ expect(input.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
32
+
33
+ const sameInput = getByPlaceholderText(PLACEHOLDER_FRESHNESS);
34
+
35
+ expect(sameInput.props.placeholder).toBe(PLACEHOLDER_FRESHNESS);
36
+ expect(() => getByPlaceholderText('no placeholder')).toThrow(
37
+ 'Unable to find an element with placeholder: no placeholder'
38
+ );
39
+
40
+ expect(queryByPlaceholderText(/add/i)).toBe(input);
41
+ expect(queryByPlaceholderText('no placeholder')).toBeNull();
42
+ expect(() => queryByPlaceholderText(/fresh/)).toThrow(
43
+ 'Found multiple elements with placeholder: /fresh/ '
44
+ );
45
+ });
46
+
47
+ test('getAllByPlaceholderText, queryAllByPlaceholderText', () => {
48
+ const { getAllByPlaceholderText, queryAllByPlaceholderText } = render(
49
+ <Banana />
50
+ );
51
+ const inputs = getAllByPlaceholderText(/fresh/i);
52
+
53
+ expect(inputs).toHaveLength(2);
54
+ expect(() => getAllByPlaceholderText('no placeholder')).toThrow(
55
+ 'Unable to find an element with placeholder: no placeholder'
56
+ );
57
+
58
+ expect(queryAllByPlaceholderText(/fresh/i)).toEqual(inputs);
59
+ expect(queryAllByPlaceholderText('no placeholder')).toHaveLength(0);
60
+ });
61
+
62
+ test('byPlaceholderText queries support hidden option', () => {
63
+ const { getByPlaceholderText, queryByPlaceholderText } = render(
64
+ <TextInput placeholder="hidden" style={{ display: 'none' }} />
65
+ );
66
+
67
+ expect(
68
+ getByPlaceholderText('hidden', { includeHiddenElements: true })
69
+ ).toBeTruthy();
70
+
71
+ expect(queryByPlaceholderText('hidden')).toBeFalsy();
72
+ expect(
73
+ queryByPlaceholderText('hidden', { includeHiddenElements: false })
74
+ ).toBeFalsy();
75
+ expect(() => getByPlaceholderText('hidden', { includeHiddenElements: false }))
76
+ .toThrowErrorMatchingInlineSnapshot(`
77
+ "Unable to find an element with placeholder: hidden
78
+
79
+ <TextInput
80
+ placeholder="hidden"
81
+ style={
82
+ {
83
+ "display": "none",
84
+ }
85
+ }
86
+ />"
87
+ `);
88
+ });
89
+
90
+ test('byPlaceHolderText should return host component', () => {
91
+ const { getByPlaceholderText } = render(
92
+ <TextInput placeholder="placeholder" />
93
+ );
94
+
95
+ expect(getByPlaceholderText('placeholder').type).toBe('TextInput');
96
+ });
97
+
98
+ test('error message renders the element tree, preserving only helpful props', async () => {
99
+ const view = render(<TextInput placeholder="PLACEHOLDER" key="3" />);
100
+
101
+ expect(() => view.getByPlaceholderText('FOO'))
102
+ .toThrowErrorMatchingInlineSnapshot(`
103
+ "Unable to find an element with placeholder: FOO
104
+
105
+ <TextInput
106
+ placeholder="PLACEHOLDER"
107
+ />"
108
+ `);
109
+
110
+ expect(() => view.getAllByPlaceholderText('FOO'))
111
+ .toThrowErrorMatchingInlineSnapshot(`
112
+ "Unable to find an element with placeholder: FOO
113
+
114
+ <TextInput
115
+ placeholder="PLACEHOLDER"
116
+ />"
117
+ `);
118
+
119
+ await expect(view.findByPlaceholderText('FOO')).rejects
120
+ .toThrowErrorMatchingInlineSnapshot(`
121
+ "Unable to find an element with placeholder: FOO
122
+
123
+ <TextInput
124
+ placeholder="PLACEHOLDER"
125
+ />"
126
+ `);
127
+
128
+ await expect(view.findAllByPlaceholderText('FOO')).rejects
129
+ .toThrowErrorMatchingInlineSnapshot(`
130
+ "Unable to find an element with placeholder: FOO
131
+
132
+ <TextInput
133
+ placeholder="PLACEHOLDER"
134
+ />"
135
+ `);
136
+ });