@hanzogui/kitchen-sink 3.0.5

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 (431) hide show
  1. package/.detoxrc.js +130 -0
  2. package/.env.production +2 -0
  3. package/.maestro/config.yaml +4 -0
  4. package/.maestro/flows/shorthand-variables.yaml +23 -0
  5. package/.watchmanconfig +1 -0
  6. package/LICENSE +21 -0
  7. package/README.md +11 -0
  8. package/app.json +43 -0
  9. package/assets/adaptive-icon.png +0 -0
  10. package/assets/favicon.png +0 -0
  11. package/assets/icon.png +0 -0
  12. package/assets/splash.png +0 -0
  13. package/babel.config.js +25 -0
  14. package/e2e/CompilerExtraction.test.ts +147 -0
  15. package/e2e/GroupPressNative.test.ts +167 -0
  16. package/e2e/MediaQueryGtMd.test.ts +71 -0
  17. package/e2e/NativePortal.test.ts +113 -0
  18. package/e2e/PointerEvents.test.ts +116 -0
  19. package/e2e/PressStyleNative.noRngh.test.ts +191 -0
  20. package/e2e/PressStyleNative.test.ts +231 -0
  21. package/e2e/SafeArea.test.ts +57 -0
  22. package/e2e/SelectAndroidOnPress.test.ts +181 -0
  23. package/e2e/SelectRemount.test.ts +137 -0
  24. package/e2e/SheetDragResist.test.ts +370 -0
  25. package/e2e/SheetKeyboardDrag.test.ts +249 -0
  26. package/e2e/SheetScrollableDrag.test.ts +560 -0
  27. package/e2e/ShorthandVariables.test.ts +53 -0
  28. package/e2e/ThemeChangeBasic.test.ts +123 -0
  29. package/e2e/ThemeMutation.test.ts +80 -0
  30. package/e2e/check-rngh-status.test.ts +31 -0
  31. package/e2e/jest.config.js +19 -0
  32. package/e2e/utils/colors.ts +75 -0
  33. package/e2e/utils/navigation.ts +53 -0
  34. package/eas.json +22 -0
  35. package/flows/AlertDialog.yaml +17 -0
  36. package/flows/OpenApp.yaml +25 -0
  37. package/flows/Select.yaml +13 -0
  38. package/flows/Sheet.yaml +12 -0
  39. package/flows/Tabs.yaml +13 -0
  40. package/flows/Toast.yaml +14 -0
  41. package/flows/WarmUp.yaml +24 -0
  42. package/index.html +21 -0
  43. package/index.js +17 -0
  44. package/metro.config.js +64 -0
  45. package/next-router-shim.ts +9 -0
  46. package/package.json +118 -0
  47. package/plans/toast-2.md +471 -0
  48. package/playwright.config.ts +71 -0
  49. package/plugins/expo-modules-core-swift6.js +76 -0
  50. package/pod-install.sh +7 -0
  51. package/public/favicon.svg +70 -0
  52. package/public/fonts/inter.css +15 -0
  53. package/public/fonts/noto-cn.otf +0 -0
  54. package/public/gui-icon.svg +68 -0
  55. package/run-detox.sh +230 -0
  56. package/run-native-tests.sh +4 -0
  57. package/run-tests-parallel.ts +195 -0
  58. package/screenshots/Screenshotter.test.tsx +48 -0
  59. package/src/AnimationDemos.tsx +131 -0
  60. package/src/App.native.tsx +121 -0
  61. package/src/App.tsx +121 -0
  62. package/src/Navigation.tsx +98 -0
  63. package/src/Sandbox.tsx +87 -0
  64. package/src/TestDynamicEval.tsx +33 -0
  65. package/src/TestNativeSheet.tsx +100 -0
  66. package/src/components/TimedRender.tsx +18 -0
  67. package/src/constants/test-ids.ts +52 -0
  68. package/src/features/demos/demo-screen.tsx +72 -0
  69. package/src/features/home/ColorSchemeListItem.tsx +41 -0
  70. package/src/features/home/TestBuildAButton.tsx +102 -0
  71. package/src/features/home/TestSeparator.tsx +0 -0
  72. package/src/features/home/screen.tsx +285 -0
  73. package/src/features/testcases/screen.tsx +59 -0
  74. package/src/features/testcases/test-screen.tsx +50 -0
  75. package/src/generatedV5Theme.ts +112 -0
  76. package/src/gui.config.ts +411 -0
  77. package/src/guy.png +0 -0
  78. package/src/index.tsx +6 -0
  79. package/src/provider/index.tsx +18 -0
  80. package/src/test-gui-stack.tsx +11 -0
  81. package/src/test.tsx +3 -0
  82. package/src/useKitchenSinkTheme.tsx +15 -0
  83. package/src/usecases/ActionsSheetComparison.tsx +194 -0
  84. package/src/usecases/AnimatePresenceEnterExitCase.tsx +255 -0
  85. package/src/usecases/AnimatePresenceExitTest.tsx +69 -0
  86. package/src/usecases/AnimatedByProp.tsx +39 -0
  87. package/src/usecases/AnimationComprehensiveCase.tsx +2515 -0
  88. package/src/usecases/AnimationValueLoggingCase.tsx +526 -0
  89. package/src/usecases/AnimationsWithMediaQueriesCase.tsx +110 -0
  90. package/src/usecases/Benchmark.tsx +148 -0
  91. package/src/usecases/BenchmarkSelect.tsx +34 -0
  92. package/src/usecases/ButtonCircular.tsx +3 -0
  93. package/src/usecases/ButtonCustom.tsx +33 -0
  94. package/src/usecases/ButtonIconColor.tsx +18 -0
  95. package/src/usecases/ButtonInverse.tsx +30 -0
  96. package/src/usecases/ButtonUnstyled.tsx +31 -0
  97. package/src/usecases/CheckboxDisabledOnPress.tsx +62 -0
  98. package/src/usecases/ClickDuringEnterCase.tsx +59 -0
  99. package/src/usecases/CodeExamplesInput.tsx +9 -0
  100. package/src/usecases/ColorTokenFallback.tsx +52 -0
  101. package/src/usecases/CompilerExtraction.tsx +380 -0
  102. package/src/usecases/ComplexVariants.tsx +164 -0
  103. package/src/usecases/CrashAdaptSheet.tsx +98 -0
  104. package/src/usecases/CustomStyledAnimatedPopover.tsx +42 -0
  105. package/src/usecases/CustomStyledAnimatedTooltip.tsx +72 -0
  106. package/src/usecases/DOMNodeAPIs.tsx +154 -0
  107. package/src/usecases/DialogFocusScopeCase.tsx +277 -0
  108. package/src/usecases/DialogFocusScopeDebug.tsx +85 -0
  109. package/src/usecases/DialogNestedCase.tsx +121 -0
  110. package/src/usecases/DialogOpenControlled.tsx +49 -0
  111. package/src/usecases/DialogPointerEventsCase.tsx +58 -0
  112. package/src/usecases/DialogScopedCase.tsx +106 -0
  113. package/src/usecases/DialogSheetAdaptCase.tsx +178 -0
  114. package/src/usecases/DialogSheetAdaptResizeCase.tsx +98 -0
  115. package/src/usecases/DismissLayerStackingCase.tsx +223 -0
  116. package/src/usecases/DriverDisableAnimationPropsCase.tsx +44 -0
  117. package/src/usecases/Example.tsx +10 -0
  118. package/src/usecases/ExitCompletionCase.tsx +713 -0
  119. package/src/usecases/FocusVisibleButton.tsx +14 -0
  120. package/src/usecases/FocusVisibleButtonPointer.tsx +13 -0
  121. package/src/usecases/FocusVisibleButtonWithFocusStyle.tsx +16 -0
  122. package/src/usecases/FocusWithinCase.tsx +55 -0
  123. package/src/usecases/FontTokensInVariants.tsx +14 -0
  124. package/src/usecases/FormButtonTypeCase.tsx +34 -0
  125. package/src/usecases/GlobalScopedTriggerIsolationCase.tsx +178 -0
  126. package/src/usecases/GroupHoverMobile.tsx +39 -0
  127. package/src/usecases/GroupPressInVariant.tsx +92 -0
  128. package/src/usecases/GroupPressNative.tsx +200 -0
  129. package/src/usecases/GroupProp.tsx +96 -0
  130. package/src/usecases/GroupPseudoVariantOverride.tsx +56 -0
  131. package/src/usecases/GroupUseCases.tsx +94 -0
  132. package/src/usecases/HeightMediaQueryOverrideCase.tsx +183 -0
  133. package/src/usecases/InputAutoFocusAfterMenuCase.tsx +105 -0
  134. package/src/usecases/InputAutoFocusStyledCase.tsx +39 -0
  135. package/src/usecases/KeyboardControllerTest.tsx +146 -0
  136. package/src/usecases/ListItem.tsx +123 -0
  137. package/src/usecases/MediaQueriesV5.tsx +137 -0
  138. package/src/usecases/MediaQueryGtMd.tsx +73 -0
  139. package/src/usecases/MenuAboveDialogCase.tsx +75 -0
  140. package/src/usecases/MenuAccessibilityCase.tsx +133 -0
  141. package/src/usecases/MenuAnimatePositionCase.tsx +41 -0
  142. package/src/usecases/MenuArrowAnimatePresenceCase.tsx +98 -0
  143. package/src/usecases/MenuAsChildPositionCase.tsx +24 -0
  144. package/src/usecases/MenuAutoResizeCase.tsx +57 -0
  145. package/src/usecases/MenuBottomCase.tsx +55 -0
  146. package/src/usecases/MenuFocusLeaveCase.tsx +135 -0
  147. package/src/usecases/MenuHighlightCase.tsx +44 -0
  148. package/src/usecases/MenuItemFocusCase.tsx +79 -0
  149. package/src/usecases/MenuItemPseudoOverrideCase.tsx +270 -0
  150. package/src/usecases/MenuMultiTriggerCase.tsx +47 -0
  151. package/src/usecases/MenuOverflowCase.tsx +60 -0
  152. package/src/usecases/MenuSubCase.tsx +223 -0
  153. package/src/usecases/MenuSubLeftCase.tsx +178 -0
  154. package/src/usecases/MenuSubNestedPositionCase.tsx +171 -0
  155. package/src/usecases/MenuSubStyledCase.tsx +145 -0
  156. package/src/usecases/MenuThemeCase.tsx +50 -0
  157. package/src/usecases/MenuUnstyledCase.tsx +52 -0
  158. package/src/usecases/MultiDriverAnimation.tsx +118 -0
  159. package/src/usecases/NativePortalTest.tsx +179 -0
  160. package/src/usecases/NewInputBasic.tsx +16 -0
  161. package/src/usecases/NewInputEvents.tsx +29 -0
  162. package/src/usecases/NonGuiTextStyledType.tsx +23 -0
  163. package/src/usecases/OnLayoutCase.tsx +134 -0
  164. package/src/usecases/OnLayoutScaleCase.tsx +88 -0
  165. package/src/usecases/OnLayoutStressCase.tsx +353 -0
  166. package/src/usecases/OpacityModifierCase.tsx +113 -0
  167. package/src/usecases/OverlayStyled.tsx +66 -0
  168. package/src/usecases/ParagraphSpanFontInheritance.tsx +53 -0
  169. package/src/usecases/PlaceholderTextColor.tsx +20 -0
  170. package/src/usecases/PointerEventsCase.tsx +100 -0
  171. package/src/usecases/PopoverAndMenuMultiTriggerCase.tsx +138 -0
  172. package/src/usecases/PopoverCase.tsx +222 -0
  173. package/src/usecases/PopoverContentStyledPlusAnimations.tsx +44 -0
  174. package/src/usecases/PopoverFocusScopeCase.tsx +171 -0
  175. package/src/usecases/PopoverHoverableCase.tsx +167 -0
  176. package/src/usecases/PopoverHoverableDisableClickCase.tsx +118 -0
  177. package/src/usecases/PopoverHoverableRapidCase.tsx +103 -0
  178. package/src/usecases/PopoverHoverableScopedCase.tsx +135 -0
  179. package/src/usecases/PopoverScopedCase.tsx +76 -0
  180. package/src/usecases/PopoverTriggerIsolationCase.tsx +80 -0
  181. package/src/usecases/PressStyleNative.tsx +143 -0
  182. package/src/usecases/PseudoStyleMerge.tsx +25 -0
  183. package/src/usecases/PseudoTransitionCase.tsx +174 -0
  184. package/src/usecases/RawAnimatedValueCase.tsx +231 -0
  185. package/src/usecases/RemoveScrollCase.tsx +66 -0
  186. package/src/usecases/RenderPropCase.tsx +263 -0
  187. package/src/usecases/SafeAreaCase.tsx +236 -0
  188. package/src/usecases/ScrollViewRefCase.tsx +88 -0
  189. package/src/usecases/SecondPage.tsx +5 -0
  190. package/src/usecases/SelectAndroidOnPress.tsx +129 -0
  191. package/src/usecases/SelectFocusScopeCase.tsx +270 -0
  192. package/src/usecases/SelectRemount.tsx +136 -0
  193. package/src/usecases/Shadows.tsx +5 -0
  194. package/src/usecases/SheetAnimationCase.tsx +155 -0
  195. package/src/usecases/SheetDragCase.tsx +183 -0
  196. package/src/usecases/SheetDragResistCase.tsx +433 -0
  197. package/src/usecases/SheetDragResistCase.web.tsx +359 -0
  198. package/src/usecases/SheetKeyboardDragCase.tsx +328 -0
  199. package/src/usecases/SheetKeyboardFitContentCase.tsx +165 -0
  200. package/src/usecases/SheetOnAnimationCompleteCase.tsx +54 -0
  201. package/src/usecases/SheetScrollLockCase.tsx +166 -0
  202. package/src/usecases/SheetScrollableDrag.tsx +249 -0
  203. package/src/usecases/SheetSnapPointsFitCase.tsx +393 -0
  204. package/src/usecases/ShorthandVariables.tsx +49 -0
  205. package/src/usecases/SlowThemeReRender.tsx +48 -0
  206. package/src/usecases/SpinnerCustomColors.tsx +34 -0
  207. package/src/usecases/StackZIndex.tsx +82 -0
  208. package/src/usecases/StressPage.tsx +301 -0
  209. package/src/usecases/StylePlatform.tsx +30 -0
  210. package/src/usecases/StyleProp.tsx +29 -0
  211. package/src/usecases/StyledAnchor.tsx +27 -0
  212. package/src/usecases/StyledButtonAnimationAuto.tsx +99 -0
  213. package/src/usecases/StyledButtonTheme.tsx +63 -0
  214. package/src/usecases/StyledButtonVariantPseudo.tsx +25 -0
  215. package/src/usecases/StyledButtonVariantPseudoMerge.tsx +77 -0
  216. package/src/usecases/StyledCheckboxTheme.tsx +23 -0
  217. package/src/usecases/StyledContextColor.tsx +246 -0
  218. package/src/usecases/StyledContextTokens.tsx +147 -0
  219. package/src/usecases/StyledHOCNamed.tsx +20 -0
  220. package/src/usecases/StyledHtmlCase.tsx +144 -0
  221. package/src/usecases/StyledIconColor.tsx +19 -0
  222. package/src/usecases/StyledInputFocusStyle.tsx +21 -0
  223. package/src/usecases/StyledInputOnFocus.tsx +30 -0
  224. package/src/usecases/StyledMediaQueryMerge.tsx +95 -0
  225. package/src/usecases/StyledOverridePsuedo.tsx +26 -0
  226. package/src/usecases/StyledRNW.tsx +61 -0
  227. package/src/usecases/StyledStyleableInputOnFocus.tsx +34 -0
  228. package/src/usecases/StyledStyleableInputVariant.tsx +48 -0
  229. package/src/usecases/StyledStyledStyleableInputOnFocus.tsx +36 -0
  230. package/src/usecases/StyledVariantTextColor.tsx +25 -0
  231. package/src/usecases/StyledViewOnFocus.tsx +32 -0
  232. package/src/usecases/TabHoverAnimationCase.tsx +212 -0
  233. package/src/usecases/TextNestedInheritance.tsx +80 -0
  234. package/src/usecases/ThemeChange.tsx +100 -0
  235. package/src/usecases/ThemeChangeBasic.tsx +52 -0
  236. package/src/usecases/ThemeComponentResolution.tsx +119 -0
  237. package/src/usecases/ThemeConditionalName.tsx +31 -0
  238. package/src/usecases/ThemeMediaAnimationCase.tsx +39 -0
  239. package/src/usecases/ThemeMutation.tsx +86 -0
  240. package/src/usecases/ThemeNested.tsx +103 -0
  241. package/src/usecases/ThemeReset.tsx +62 -0
  242. package/src/usecases/ThemeShallowCase.tsx +83 -0
  243. package/src/usecases/ToastCase.tsx +46 -0
  244. package/src/usecases/ToggleGroupActiveProps.tsx +40 -0
  245. package/src/usecases/ToggleGroupXGroupCase.tsx +104 -0
  246. package/src/usecases/TooltipAnimationCase.tsx +99 -0
  247. package/src/usecases/TooltipCase.tsx +32 -0
  248. package/src/usecases/TooltipGlobalPatternCase.tsx +83 -0
  249. package/src/usecases/TooltipGroupCase.tsx +102 -0
  250. package/src/usecases/TooltipMultiTriggerCase.tsx +88 -0
  251. package/src/usecases/TooltipPositionJumpCase.tsx +91 -0
  252. package/src/usecases/TooltipTriggerInlineCase.tsx +60 -0
  253. package/src/usecases/TransformMediaQueryMerge.tsx +98 -0
  254. package/src/usecases/UseCases.tsx +409 -0
  255. package/src/usecases/UseTheme.tsx +41 -0
  256. package/src/usecases/V5ThemeBuilderOutput.tsx +231 -0
  257. package/src/usecases/VariantFontFamily.tsx +25 -0
  258. package/src/usecases/VariantsOrder.tsx +117 -0
  259. package/src/usecases/ZIndex.tsx +155 -0
  260. package/src/usecases/helpers.tsx +44 -0
  261. package/src/usecases/index.native.ts +122 -0
  262. package/src/usecases/index.ts +3 -0
  263. package/src/usecases/index.web.ts +177 -0
  264. package/tests/AnimatePresenceEnterExit.animated.test.tsx +176 -0
  265. package/tests/AnimatedByProp.animated.test.tsx +138 -0
  266. package/tests/AnimationBehavior.animated.test.tsx +543 -0
  267. package/tests/AnimationTiming.animated.test.tsx +195 -0
  268. package/tests/AnimationsWithMediaQueries.animated.test.tsx +154 -0
  269. package/tests/BuildAButton.test.tsx +87 -0
  270. package/tests/ButtonCircular.test.tsx +17 -0
  271. package/tests/ButtonCustom.test.tsx +17 -0
  272. package/tests/ButtonIconColor.test.tsx +23 -0
  273. package/tests/ButtonUnstyled.test.tsx +56 -0
  274. package/tests/ClickDuringEnter.animated.test.tsx +174 -0
  275. package/tests/ColorTokenFallback.test.tsx +45 -0
  276. package/tests/DOMNodeAPIs.test.tsx +161 -0
  277. package/tests/DialogFocusScope.animated.test.tsx +309 -0
  278. package/tests/DialogNested.test.tsx +128 -0
  279. package/tests/DialogOpenControlled.test.tsx +42 -0
  280. package/tests/DialogPointerEvents.animated.test.tsx +108 -0
  281. package/tests/DialogScoped.test.tsx +137 -0
  282. package/tests/DialogSheetAdapt.test.tsx +68 -0
  283. package/tests/DialogSheetAdaptResize.test.tsx +161 -0
  284. package/tests/DismissLayerStacking.test.tsx +292 -0
  285. package/tests/DriverDisableAnimationProps.animated.test.tsx +157 -0
  286. package/tests/ExitCompletion.animated.test.tsx +425 -0
  287. package/tests/ExitTimingCheck.animated.test.ts +34 -0
  288. package/tests/FocusVisibleButton.test.tsx +41 -0
  289. package/tests/FocusVisibleButtonPointerFocus.test.tsx +23 -0
  290. package/tests/FocusVisibleButtonPointerFocusWithFocusStyle.test.tsx +40 -0
  291. package/tests/FocusWithinStyle.animated.test.tsx +66 -0
  292. package/tests/FocusWithinStyle.test.tsx +60 -0
  293. package/tests/FormButtonType.test.tsx +42 -0
  294. package/tests/GlobalScopedTriggerIsolation.test.tsx +89 -0
  295. package/tests/GroupHoverMobile.test.tsx +52 -0
  296. package/tests/GroupPressInVariant.test.tsx +82 -0
  297. package/tests/GroupProp.test.tsx +30 -0
  298. package/tests/GroupPseudoVariantOverride.test.tsx +57 -0
  299. package/tests/GroupUseCases.test.tsx +111 -0
  300. package/tests/GuiSiteMotion.test.ts +481 -0
  301. package/tests/HeightMediaQueryOverride.test.tsx +112 -0
  302. package/tests/InputAutoFocusAfterMenu.test.tsx +55 -0
  303. package/tests/InputAutoFocusStyled.test.tsx +22 -0
  304. package/tests/ListItem.test.tsx +129 -0
  305. package/tests/MediaQueriesV5.test.tsx +113 -0
  306. package/tests/MediaQueryGtMd.test.tsx +84 -0
  307. package/tests/MenuAboveDialog.test.tsx +108 -0
  308. package/tests/MenuAccessibility.test.tsx +346 -0
  309. package/tests/MenuAnimatePosition.animated.test.tsx +57 -0
  310. package/tests/MenuArrowAnimatePresence.animated.test.tsx +71 -0
  311. package/tests/MenuAsChildPosition.test.tsx +16 -0
  312. package/tests/MenuAutoResize.test.tsx +54 -0
  313. package/tests/MenuFocusLeave.test.tsx +181 -0
  314. package/tests/MenuHighlight.test.tsx +165 -0
  315. package/tests/MenuHoverKeyboardBugs.test.tsx +252 -0
  316. package/tests/MenuItemFocus.test.tsx +59 -0
  317. package/tests/MenuItemPseudoOverride.test.tsx +231 -0
  318. package/tests/MenuMultiTrigger.test.tsx +101 -0
  319. package/tests/MenuOverflow.test.tsx +93 -0
  320. package/tests/MenuStayInFrame.test.tsx +102 -0
  321. package/tests/MenuSubKeyboardFocus.test.tsx +220 -0
  322. package/tests/MenuSubLeftSafePolygon.test.tsx +88 -0
  323. package/tests/MenuSubNestedPosition.test.tsx +48 -0
  324. package/tests/MenuSubSafePolygon.test.tsx +97 -0
  325. package/tests/MenuSubStyled.test.tsx +40 -0
  326. package/tests/MenuTheme.test.tsx +34 -0
  327. package/tests/MenuUnstyled.test.tsx +56 -0
  328. package/tests/MultiDriverAnimation.test.tsx +207 -0
  329. package/tests/NewInputBasic.test.tsx +50 -0
  330. package/tests/NewInputEvents.test.tsx +55 -0
  331. package/tests/OnLayout.test.tsx +163 -0
  332. package/tests/OnLayoutScale.test.tsx +100 -0
  333. package/tests/OnLayoutStress.test.tsx +304 -0
  334. package/tests/ParagraphSpanFontInheritance.test.tsx +73 -0
  335. package/tests/PointerEvents.test.tsx +123 -0
  336. package/tests/Popover.animated.test.tsx +234 -0
  337. package/tests/PopoverAndMenuMultiTrigger.test.tsx +184 -0
  338. package/tests/PopoverAnimatePosition.animated.test.tsx +51 -0
  339. package/tests/PopoverClickDuringEnter.animated.test.tsx +197 -0
  340. package/tests/PopoverFocusScope.test.tsx +242 -0
  341. package/tests/PopoverHoverable.test.tsx +383 -0
  342. package/tests/PopoverHoverableDisableClick.test.tsx +106 -0
  343. package/tests/PopoverHoverableRapid.test.tsx +129 -0
  344. package/tests/PopoverHoverableReposition.test.tsx +111 -0
  345. package/tests/PopoverHoverableScoped.animated.test.tsx +103 -0
  346. package/tests/PopoverHoverableStress.test.tsx +169 -0
  347. package/tests/PopoverInitialPosition.animated.test.tsx +82 -0
  348. package/tests/PopoverMiddlewareSkipRegression.animated.test.tsx +221 -0
  349. package/tests/PopoverScoped.test.tsx +128 -0
  350. package/tests/PopoverScopedPositionGlitch.animated.test.tsx +184 -0
  351. package/tests/PopoverTriggerIsolation.test.tsx +62 -0
  352. package/tests/PseudoTransition.animated.test.tsx +319 -0
  353. package/tests/RawAnimatedValue.test.tsx +147 -0
  354. package/tests/RemoveScroll.test.tsx +223 -0
  355. package/tests/RenderProp.test.tsx +293 -0
  356. package/tests/ScrollViewRef.test.tsx +39 -0
  357. package/tests/SelectClickHold.test.tsx +147 -0
  358. package/tests/SelectFocusScope.test.tsx +176 -0
  359. package/tests/SelectInnerPositioning.test.tsx +82 -0
  360. package/tests/SelectKeyboardNav.test.tsx +173 -0
  361. package/tests/SelectPositioning.test.tsx +56 -0
  362. package/tests/SelectTypeahead.test.tsx +63 -0
  363. package/tests/Shadows.test.tsx +14 -0
  364. package/tests/SheetAnimation.animated.test.tsx +413 -0
  365. package/tests/SheetDrag.animated.test.tsx +223 -0
  366. package/tests/SheetDragResist.animated.test.tsx +393 -0
  367. package/tests/SheetOnAnimationComplete.animated.test.tsx +62 -0
  368. package/tests/SheetScrollLock.animated.test.tsx +287 -0
  369. package/tests/SheetScrollableDrag.animated.test.tsx +1264 -0
  370. package/tests/SheetSnapPointsFit.animated.test.tsx +259 -0
  371. package/tests/ShorthandVariables.test.tsx +44 -0
  372. package/tests/SpinnerCustomColors.test.tsx +67 -0
  373. package/tests/StackZIndex.test.tsx +51 -0
  374. package/tests/StressPagePerf.test.tsx +76 -0
  375. package/tests/StylePlatform.test.tsx +38 -0
  376. package/tests/StyleProp.test.tsx +20 -0
  377. package/tests/StyledAnchor.test.tsx +17 -0
  378. package/tests/StyledButtonTheme.test.tsx +22 -0
  379. package/tests/StyledButtonVariantPseudo.test.tsx +20 -0
  380. package/tests/StyledButtonVariantPseudoMerge.animated.test.tsx +33 -0
  381. package/tests/StyledCheckboxTheme.test.tsx +16 -0
  382. package/tests/StyledContextColor.test.tsx +119 -0
  383. package/tests/StyledContextTokens.test.tsx +56 -0
  384. package/tests/StyledHOCNamed.test.tsx +16 -0
  385. package/tests/StyledHtml.test.tsx +161 -0
  386. package/tests/StyledIconColor.test.tsx +32 -0
  387. package/tests/StyledInputFocusStyle.test.tsx +19 -0
  388. package/tests/StyledInputOnFocus.test.tsx +27 -0
  389. package/tests/StyledMediaQueryMerge.test.tsx +66 -0
  390. package/tests/StyledRNW.test.tsx +17 -0
  391. package/tests/StyledStyleableInputOnFocus.test.tsx +27 -0
  392. package/tests/StyledStyleableInputVariant.test.tsx +22 -0
  393. package/tests/StyledStyledStyleableInputOnFocus.test.tsx +27 -0
  394. package/tests/StyledVariantTextColor.test.tsx +24 -0
  395. package/tests/StyledViewOnFocus.test.tsx +27 -0
  396. package/tests/TabHoverAnimation.animated.test.tsx +468 -0
  397. package/tests/TabHoverPositionSmooth.animated.test.tsx +129 -0
  398. package/tests/TextNestedInheritance.test.tsx +93 -0
  399. package/tests/ThemeChange.test.tsx +70 -0
  400. package/tests/ThemeComponentResolution.test.tsx +82 -0
  401. package/tests/ThemeConditionalName.test.tsx +34 -0
  402. package/tests/ThemeMediaAnimation.test.tsx +65 -0
  403. package/tests/ThemeNested.test.tsx +141 -0
  404. package/tests/ThemeReset.test.tsx +63 -0
  405. package/tests/ThemeShallow.test.tsx +95 -0
  406. package/tests/Toast.test.tsx +106 -0
  407. package/tests/ToggleGroup.test.tsx +61 -0
  408. package/tests/ToggleGroupActiveProps.test.tsx +38 -0
  409. package/tests/ToggleGroupXGroup.test.tsx +172 -0
  410. package/tests/TooltipAnimation.animated.test.tsx +260 -0
  411. package/tests/TooltipEnterInterrupt.animated.test.tsx +76 -0
  412. package/tests/TooltipGlobalPattern.animated.test.tsx +208 -0
  413. package/tests/TooltipGroup.animated.test.tsx +79 -0
  414. package/tests/TooltipMultiTrigger.test.tsx +116 -0
  415. package/tests/TooltipPositionJump.animated.test.tsx +229 -0
  416. package/tests/TooltipPositionJumpNotes.md +219 -0
  417. package/tests/TooltipRapidSwitch.animated.test.tsx +399 -0
  418. package/tests/TooltipTriggerInline.test.tsx +65 -0
  419. package/tests/TransformMediaQueryMerge.test.tsx +104 -0
  420. package/tests/TransitionEnterExit.animated.test.tsx +311 -0
  421. package/tests/UseTheme.test.tsx +16 -0
  422. package/tests/V5ThemeBuilderOutput.test.tsx +164 -0
  423. package/tests/VariantFontFamily.test.tsx +11 -0
  424. package/tests/VariantsOrder.test.tsx +53 -0
  425. package/tests/_debug_position.mjs +52 -0
  426. package/tests/test-utils.ts +106 -0
  427. package/tests/utils.tsx +54 -0
  428. package/tsconfig.json +45 -0
  429. package/vite-env.d.ts +1 -0
  430. package/vite.config.ts +14 -0
  431. package/webpack.config.js +139 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Test for native portal with react-native-teleport integration
3
+ * Verifies that Portal/Sheet/Popover work correctly when using teleport
4
+ */
5
+
6
+ import { by, device, element, expect, waitFor } from 'detox'
7
+ import { navigateToTestCase } from './utils/navigation'
8
+
9
+ describe('NativePortal', () => {
10
+ beforeAll(async () => {
11
+ await device.launchApp({ newInstance: true })
12
+ })
13
+
14
+ beforeEach(async () => {
15
+ await device.reloadReactNative()
16
+ await navigateToTestCase('NativePortalTest', 'portal-status')
17
+ })
18
+
19
+ it('should navigate to NativePortalTest test case', async () => {
20
+ // verify we're on the right screen by checking for portal status
21
+ await expect(element(by.id('portal-status'))).toBeVisible()
22
+ })
23
+
24
+ it('should show teleport as enabled', async () => {
25
+ // check that teleport is detected and enabled
26
+ const statusText = element(by.id('portal-status'))
27
+ await expect(statusText).toBeVisible()
28
+ // the status should indicate teleport is active (not "Not enabled")
29
+ // we can't easily check text content in detox, but visibility confirms component renders
30
+ })
31
+
32
+ it('should open Select with Sheet', async () => {
33
+ await device.disableSynchronization()
34
+
35
+ try {
36
+ // tap the select trigger
37
+ await element(by.id('native-portal-select-trigger')).tap()
38
+
39
+ // wait for select options to appear
40
+ await waitFor(element(by.id('native-portal-select-option-apple')))
41
+ .toBeVisible()
42
+ .withTimeout(10000)
43
+
44
+ // close by selecting an option
45
+ await element(by.id('native-portal-select-option-apple')).tap()
46
+
47
+ // wait for sheet to close
48
+ await new Promise((resolve) => setTimeout(resolve, 1000))
49
+ } finally {
50
+ await device.enableSynchronization()
51
+ }
52
+ })
53
+
54
+ it('should open and close Popover', async () => {
55
+ await device.disableSynchronization()
56
+
57
+ try {
58
+ // tap popover trigger
59
+ await element(by.id('native-portal-popover-trigger')).tap()
60
+
61
+ // wait for popover content to appear
62
+ await waitFor(element(by.id('native-portal-popover-content')))
63
+ .toBeVisible()
64
+ .withTimeout(5000)
65
+
66
+ // verify text is visible inside popover
67
+ await expect(element(by.id('native-portal-popover-text'))).toBeVisible()
68
+
69
+ // close popover
70
+ await element(by.id('native-portal-popover-close')).tap()
71
+
72
+ // wait for popover to close
73
+ await new Promise((resolve) => setTimeout(resolve, 500))
74
+
75
+ // popover content should no longer be visible
76
+ await waitFor(element(by.id('native-portal-popover-content')))
77
+ .not.toBeVisible()
78
+ .withTimeout(3000)
79
+ } finally {
80
+ await device.enableSynchronization()
81
+ }
82
+ })
83
+
84
+ it('should open and close Sheet', async () => {
85
+ await device.disableSynchronization()
86
+
87
+ try {
88
+ // tap sheet trigger
89
+ await element(by.id('native-portal-sheet-trigger')).tap()
90
+
91
+ // wait for sheet frame to appear
92
+ await waitFor(element(by.id('native-portal-sheet-frame')))
93
+ .toBeVisible()
94
+ .withTimeout(5000)
95
+
96
+ // verify text is visible inside sheet
97
+ await expect(element(by.id('native-portal-sheet-text'))).toBeVisible()
98
+
99
+ // close sheet by swiping down (dismissOnSnapToBottom)
100
+ await element(by.id('native-portal-sheet-frame')).swipe('down', 'fast')
101
+
102
+ // wait for sheet close animation
103
+ await new Promise((resolve) => setTimeout(resolve, 1000))
104
+
105
+ // sheet text should no longer be visible
106
+ await waitFor(element(by.id('native-portal-sheet-text')))
107
+ .not.toBeVisible()
108
+ .withTimeout(5000)
109
+ } finally {
110
+ await device.enableSynchronization()
111
+ }
112
+ })
113
+ })
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Native tests for pointer events
3
+ * Verifies touch events map correctly to pointer events on native
4
+ */
5
+
6
+ import { by, device, element, expect } from 'detox'
7
+ import { navigateToTestCase } from './utils/navigation'
8
+
9
+ async function navigateToPointerEvents() {
10
+ await navigateToTestCase('PointerEventsCase', 'pointer-events-root')
11
+ }
12
+
13
+ describe('PointerEvents', () => {
14
+ beforeAll(async () => {
15
+ await device.launchApp({ newInstance: true })
16
+ })
17
+
18
+ beforeEach(async () => {
19
+ await device.reloadReactNative()
20
+ await navigateToPointerEvents()
21
+ })
22
+
23
+ it('should render the test case', async () => {
24
+ await expect(element(by.id('pointer-target'))).toExist()
25
+ await expect(element(by.id('down-count'))).toHaveText('Down: 0')
26
+ await expect(element(by.id('up-count'))).toHaveText('Up: 0')
27
+ })
28
+
29
+ it('should fire pointerDown and pointerUp on tap', async () => {
30
+ await element(by.id('pointer-target')).tap()
31
+
32
+ await expect(element(by.id('down-count'))).toHaveText('Down: 1')
33
+ await expect(element(by.id('up-count'))).toHaveText('Up: 1')
34
+ })
35
+
36
+ it('should fire pointerEnter on touch start', async () => {
37
+ await element(by.id('pointer-target')).tap()
38
+
39
+ await expect(element(by.id('enter-count'))).toHaveText('Enter: 1')
40
+ })
41
+
42
+ it('should fire pointerLeave on touch end', async () => {
43
+ await element(by.id('pointer-target')).tap()
44
+
45
+ await expect(element(by.id('leave-count'))).toHaveText('Leave: 1')
46
+ })
47
+
48
+ it('should fire pointerMove during drag', async () => {
49
+ await element(by.id('pointer-target')).longPressAndDrag(
50
+ 300, // duration ms
51
+ 0.2, // start x (normalized)
52
+ 0.5, // start y (normalized)
53
+ element(by.id('pointer-target')),
54
+ 0.8, // end x (normalized)
55
+ 0.5, // end y (normalized)
56
+ 'slow',
57
+ 0
58
+ )
59
+
60
+ // should have fired at least one move event (not still 0)
61
+ const moveEl = element(by.id('move-count'))
62
+ // if move fired, text won't be "Move: 0"
63
+ await expect(moveEl).not.toHaveText('Move: 0')
64
+ })
65
+
66
+ // skipping this test because longPressAndDrag from one element to another has
67
+ // visibility threshold issues in Detox when the root container extends beyond viewport
68
+ it.skip('should fire pointerLeave when dragging off element', async () => {
69
+ await element(by.id('pointer-target')).longPressAndDrag(
70
+ 500,
71
+ 0.5,
72
+ 0.5,
73
+ element(by.id('pointer-events-root')),
74
+ 0.5,
75
+ 0.1, // drag to top of root (outside target)
76
+ 'slow',
77
+ 0
78
+ )
79
+
80
+ await new Promise((r) => setTimeout(r, 100))
81
+
82
+ await expect(element(by.id('leave-count'))).toHaveText('Leave: 1')
83
+ })
84
+
85
+ it('should handle multiple tap cycles', async () => {
86
+ await element(by.id('pointer-target')).tap()
87
+ await element(by.id('pointer-target')).tap()
88
+ await element(by.id('pointer-target')).tap()
89
+
90
+ await expect(element(by.id('down-count'))).toHaveText('Down: 3')
91
+ await expect(element(by.id('up-count'))).toHaveText('Up: 3')
92
+ await expect(element(by.id('enter-count'))).toHaveText('Enter: 3')
93
+ await expect(element(by.id('leave-count'))).toHaveText('Leave: 3')
94
+ })
95
+
96
+ // skipping this test because the capture-target (second 200px square) is often
97
+ // partially off-screen and longPressAndDrag requires 100% visibility
98
+ // the core pointer capture functionality is tested in web tests
99
+ it.skip('should receive moves outside bounds when pointer is captured', async () => {
100
+ // drag from capture target to outside (root area)
101
+ // with setPointerCapture, moves should still fire even outside bounds
102
+ await element(by.id('capture-target')).longPressAndDrag(
103
+ 500,
104
+ 0.5,
105
+ 0.5,
106
+ element(by.id('pointer-events-root')),
107
+ 0.5,
108
+ 0.05, // drag way up outside the target
109
+ 'slow',
110
+ 0
111
+ )
112
+
113
+ // should have received move events even while outside bounds
114
+ await expect(element(by.id('capture-move-count'))).not.toHaveText('CapMove: 0')
115
+ })
116
+ })
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Native press style tests WITHOUT gesture handler (usePressability fallback)
3
+ *
4
+ * This test runs with RNGH disabled via launch args to verify that press handling
5
+ * works correctly when falling back to RN's usePressability.
6
+ */
7
+
8
+ import { by, device, element, expect, waitFor } from 'detox'
9
+ import * as fs from 'fs'
10
+ import * as assert from 'assert'
11
+ import { PNG } from 'pngjs'
12
+ import { navigateToTestCase } from './utils/navigation'
13
+ import { getDominantColor, isBlueish, formatRGB } from './utils/colors'
14
+
15
+ async function navigateToPressStyleNative() {
16
+ await navigateToTestCase('PressStyleNative', 'color-test-pressable')
17
+ // navigateToTestCase re-enables sync, but we need it disabled for no-RNGH tests
18
+ // because the RNManualRecognizer gesture blocks Detox synchronization in CI
19
+ await device.disableSynchronization()
20
+ }
21
+
22
+ describe('PressStyleNative (no RNGH)', () => {
23
+ beforeAll(async () => {
24
+ // launch with RNGH disabled
25
+ await device.launchApp({
26
+ newInstance: true,
27
+ launchArgs: { disableGestureHandler: true },
28
+ })
29
+ // disable synchronization for the entire suite - without RNGH, there's a
30
+ // RNManualRecognizer gesture that stays in "Possible" state which blocks Detox
31
+ await device.disableSynchronization()
32
+ })
33
+
34
+ afterAll(async () => {
35
+ await device.enableSynchronization()
36
+ })
37
+
38
+ beforeEach(async () => {
39
+ // use launchApp instead of reloadReactNative — on RN 0.83, reloadReactNative
40
+ // doesn't work reliably when RNGH is disabled (JS run loop stays busy)
41
+ await device.launchApp({
42
+ newInstance: true,
43
+ launchArgs: { disableGestureHandler: true },
44
+ })
45
+ await device.disableSynchronization()
46
+ // wait for app to stabilize after launch
47
+ await new Promise((resolve) => setTimeout(resolve, 1500))
48
+ await navigateToPressStyleNative()
49
+ })
50
+
51
+ it('should render the test case screen', async () => {
52
+ await waitFor(element(by.id('color-test-pressable')))
53
+ .toBeVisible()
54
+ .withTimeout(5000)
55
+ await waitFor(element(by.id('animated-color-test-pressable')))
56
+ .toBeVisible()
57
+ .withTimeout(5000)
58
+ })
59
+
60
+ describe('pressStyle without transition', () => {
61
+ it('should fire pressIn and pressOut events on tap', async () => {
62
+ await waitFor(element(by.id('simple-press-in-count')))
63
+ .toHaveText('In: 0')
64
+ .withTimeout(5000)
65
+ await waitFor(element(by.id('simple-press-out-count')))
66
+ .toHaveText('Out: 0')
67
+ .withTimeout(5000)
68
+
69
+ await element(by.id('color-test-pressable')).tap()
70
+ await new Promise((resolve) => setTimeout(resolve, 300))
71
+
72
+ await waitFor(element(by.id('simple-press-in-count')))
73
+ .toHaveText('In: 1')
74
+ .withTimeout(5000)
75
+ await waitFor(element(by.id('simple-press-out-count')))
76
+ .toHaveText('Out: 1')
77
+ .withTimeout(5000)
78
+ })
79
+
80
+ it('should not be stuck in pressed state after tap', async () => {
81
+ await element(by.id('color-test-pressable')).tap()
82
+ await new Promise((resolve) => setTimeout(resolve, 300))
83
+ await waitFor(element(by.id('simple-is-pressed')))
84
+ .toHaveText('Pressed: NO')
85
+ .withTimeout(5000)
86
+ })
87
+
88
+ it('should show blue background at rest', async () => {
89
+ await new Promise((resolve) => setTimeout(resolve, 300))
90
+ const restScreenshot = await element(by.id('color-test-pressable')).takeScreenshot(
91
+ 'color-test-rest-norngh'
92
+ )
93
+ const color = getDominantColor(restScreenshot)
94
+ assert.ok(isBlueish(color), `Expected blue at rest, got ${formatRGB(color)}`)
95
+ })
96
+
97
+ it('should unpress when finger drags off element', async () => {
98
+ await waitFor(element(by.id('simple-press-in-count')))
99
+ .toHaveText('In: 0')
100
+ .withTimeout(5000)
101
+ await waitFor(element(by.id('simple-press-out-count')))
102
+ .toHaveText('Out: 0')
103
+ .withTimeout(5000)
104
+
105
+ await element(by.id('color-test-pressable')).longPressAndDrag(
106
+ 500,
107
+ 0.5,
108
+ 0.5,
109
+ element(by.id('press-style-native-root')),
110
+ 0.5,
111
+ 0.1,
112
+ 'slow',
113
+ 100
114
+ )
115
+
116
+ await new Promise((resolve) => setTimeout(resolve, 400))
117
+
118
+ await waitFor(element(by.id('simple-press-in-count')))
119
+ .toHaveText('In: 1')
120
+ .withTimeout(5000)
121
+ await waitFor(element(by.id('simple-press-out-count')))
122
+ .toHaveText('Out: 1')
123
+ .withTimeout(5000)
124
+ await waitFor(element(by.id('simple-is-pressed')))
125
+ .toHaveText('Pressed: NO')
126
+ .withTimeout(5000)
127
+ })
128
+
129
+ it('should return to blue after drag off', async () => {
130
+ await element(by.id('color-test-pressable')).longPressAndDrag(
131
+ 500,
132
+ 0.5,
133
+ 0.5,
134
+ element(by.id('press-style-native-root')),
135
+ 0.5,
136
+ 0.1,
137
+ 'slow',
138
+ 100
139
+ )
140
+
141
+ await new Promise((resolve) => setTimeout(resolve, 400))
142
+
143
+ const afterScreenshot = await element(by.id('color-test-pressable')).takeScreenshot(
144
+ 'color-test-after-drag-norngh'
145
+ )
146
+ const color = getDominantColor(afterScreenshot)
147
+ assert.ok(isBlueish(color), `Expected blue after drag off, got ${formatRGB(color)}`)
148
+ })
149
+ })
150
+
151
+ describe('pressStyle with transition (animation driver)', () => {
152
+ it('should fire pressIn and pressOut events on animated pressable', async () => {
153
+ await waitFor(element(by.id('animated-press-in-count')))
154
+ .toHaveText('In: 0')
155
+ .withTimeout(5000)
156
+ await waitFor(element(by.id('animated-press-out-count')))
157
+ .toHaveText('Out: 0')
158
+ .withTimeout(5000)
159
+
160
+ await element(by.id('animated-color-test-pressable')).tap()
161
+ await new Promise((resolve) => setTimeout(resolve, 300))
162
+
163
+ await waitFor(element(by.id('animated-press-in-count')))
164
+ .toHaveText('In: 1')
165
+ .withTimeout(5000)
166
+ await waitFor(element(by.id('animated-press-out-count')))
167
+ .toHaveText('Out: 1')
168
+ .withTimeout(5000)
169
+ })
170
+
171
+ it('should not be stuck in pressed state after tap (animated)', async () => {
172
+ await element(by.id('animated-color-test-pressable')).tap()
173
+ await new Promise((resolve) => setTimeout(resolve, 300))
174
+ await waitFor(element(by.id('animated-is-pressed')))
175
+ .toHaveText('Pressed: NO')
176
+ .withTimeout(5000)
177
+ })
178
+
179
+ it('should show blue background at rest (animated)', async () => {
180
+ await new Promise((resolve) => setTimeout(resolve, 300))
181
+ const restScreenshot = await element(
182
+ by.id('animated-color-test-pressable')
183
+ ).takeScreenshot('animated-color-test-rest-norngh')
184
+ const color = getDominantColor(restScreenshot)
185
+ assert.ok(
186
+ isBlueish(color),
187
+ `Expected blue at rest (animated), got ${formatRGB(color)}`
188
+ )
189
+ })
190
+ })
191
+ })
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Detox E2E tests for native press style behaviors
3
+ *
4
+ * Tests verify:
5
+ * 1. Press events fire correctly (onPressIn/onPressOut)
6
+ * 2. Press state doesn't get stuck after tap or drag-off
7
+ * 3. Both non-animated and animated (transition) pressables work
8
+ * 4. Actual pixel colors are verified via screenshots
9
+ */
10
+
11
+ import { by, device, element, expect, waitFor } from 'detox'
12
+ import * as fs from 'fs'
13
+ import * as assert from 'assert'
14
+ import { PNG } from 'pngjs'
15
+ import { navigateToTestCase } from './utils/navigation'
16
+
17
+ // helper to get the dominant color from a PNG screenshot
18
+ // samples pixels from the center region to avoid edges/text
19
+ function getDominantColor(screenshotPath: string): { r: number; g: number; b: number } {
20
+ const data = fs.readFileSync(screenshotPath)
21
+ const png = PNG.sync.read(data)
22
+
23
+ // sample the center 50% of the image to avoid edges and text
24
+ const startX = Math.floor(png.width * 0.25)
25
+ const endX = Math.floor(png.width * 0.75)
26
+ const startY = Math.floor(png.height * 0.25)
27
+ const endY = Math.floor(png.height * 0.75)
28
+
29
+ let totalR = 0,
30
+ totalG = 0,
31
+ totalB = 0,
32
+ count = 0
33
+
34
+ for (let y = startY; y < endY; y++) {
35
+ for (let x = startX; x < endX; x++) {
36
+ const idx = (png.width * y + x) * 4
37
+ totalR += png.data[idx]
38
+ totalG += png.data[idx + 1]
39
+ totalB += png.data[idx + 2]
40
+ count++
41
+ }
42
+ }
43
+
44
+ return {
45
+ r: Math.round(totalR / count),
46
+ g: Math.round(totalG / count),
47
+ b: Math.round(totalB / count),
48
+ }
49
+ }
50
+
51
+ // check if a color is predominantly blue (for $blue10)
52
+ function isBlueish(color: { r: number; g: number; b: number }): boolean {
53
+ // blue should have high B, low R, and low-medium G
54
+ return color.b > 100 && color.b > color.r && color.b > color.g
55
+ }
56
+
57
+ // TODO: These tests are flaky on iOS simulator - press events don't fire reliably
58
+ // Need to investigate press event handling in simulator environment
59
+ describe.skip('PressStyleNative', () => {
60
+ beforeAll(async () => {
61
+ await device.launchApp({ newInstance: true })
62
+ })
63
+
64
+ beforeEach(async () => {
65
+ await device.reloadReactNative()
66
+ await navigateToPressStyleNative()
67
+ })
68
+
69
+ it('should render the test case screen', async () => {
70
+ await expect(element(by.id('color-test-pressable'))).toBeVisible()
71
+ await expect(element(by.id('animated-color-test-pressable'))).toBeVisible()
72
+ })
73
+
74
+ describe('pressStyle without transition', () => {
75
+ it('should fire pressIn and pressOut events on tap', async () => {
76
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 0')
77
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 0')
78
+
79
+ await element(by.id('color-test-pressable')).tap()
80
+
81
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 1')
82
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 1')
83
+ })
84
+
85
+ it('should not be stuck in pressed state after tap', async () => {
86
+ await element(by.id('color-test-pressable')).tap()
87
+ await new Promise((resolve) => setTimeout(resolve, 100))
88
+ await expect(element(by.id('simple-is-pressed'))).toHaveText('Pressed: NO')
89
+ })
90
+
91
+ it('should show blue background at rest', async () => {
92
+ const restScreenshot = await element(by.id('color-test-pressable')).takeScreenshot(
93
+ 'color-test-rest'
94
+ )
95
+
96
+ const color = getDominantColor(restScreenshot)
97
+ assert.ok(
98
+ isBlueish(color),
99
+ `Expected blue at rest, got RGB(${color.r}, ${color.g}, ${color.b})`
100
+ )
101
+ })
102
+
103
+ it('should unpress when finger drags off element', async () => {
104
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 0')
105
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 0')
106
+
107
+ await element(by.id('color-test-pressable')).longPressAndDrag(
108
+ 500,
109
+ 0.5,
110
+ 0.5,
111
+ element(by.id('press-style-native-root')),
112
+ 0.5,
113
+ 0.1,
114
+ 'slow',
115
+ 100
116
+ )
117
+
118
+ await new Promise((resolve) => setTimeout(resolve, 200))
119
+
120
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 1')
121
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 1')
122
+ await expect(element(by.id('simple-is-pressed'))).toHaveText('Pressed: NO')
123
+ })
124
+
125
+ it('should return to blue after drag off', async () => {
126
+ await element(by.id('color-test-pressable')).longPressAndDrag(
127
+ 500,
128
+ 0.5,
129
+ 0.5,
130
+ element(by.id('press-style-native-root')),
131
+ 0.5,
132
+ 0.1,
133
+ 'slow',
134
+ 100
135
+ )
136
+
137
+ await new Promise((resolve) => setTimeout(resolve, 200))
138
+
139
+ const afterDragScreenshot = await element(
140
+ by.id('color-test-pressable')
141
+ ).takeScreenshot('color-test-after-drag')
142
+
143
+ const color = getDominantColor(afterDragScreenshot)
144
+ assert.ok(
145
+ isBlueish(color),
146
+ `Expected blue after drag off, got RGB(${color.r}, ${color.g}, ${color.b})`
147
+ )
148
+ })
149
+
150
+ it('should handle multiple press-drag-off cycles', async () => {
151
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 0')
152
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 0')
153
+
154
+ for (let i = 0; i < 3; i++) {
155
+ await element(by.id('color-test-pressable')).longPressAndDrag(
156
+ 500,
157
+ 0.5,
158
+ 0.5,
159
+ element(by.id('press-style-native-root')),
160
+ 0.5,
161
+ 0.1,
162
+ 'slow',
163
+ 100
164
+ )
165
+ await new Promise((resolve) => setTimeout(resolve, 200))
166
+ }
167
+
168
+ await expect(element(by.id('simple-press-in-count'))).toHaveText('In: 3')
169
+ await expect(element(by.id('simple-press-out-count'))).toHaveText('Out: 3')
170
+ await expect(element(by.id('simple-is-pressed'))).toHaveText('Pressed: NO')
171
+ })
172
+ })
173
+
174
+ describe('pressStyle with transition (animation driver)', () => {
175
+ it('should fire pressIn and pressOut events on animated pressable', async () => {
176
+ await expect(element(by.id('animated-press-in-count'))).toHaveText('In: 0')
177
+ await expect(element(by.id('animated-press-out-count'))).toHaveText('Out: 0')
178
+
179
+ await element(by.id('animated-color-test-pressable')).tap()
180
+ await new Promise((resolve) => setTimeout(resolve, 100))
181
+
182
+ await expect(element(by.id('animated-press-in-count'))).toHaveText('In: 1')
183
+ await expect(element(by.id('animated-press-out-count'))).toHaveText('Out: 1')
184
+ })
185
+
186
+ it('should not be stuck in pressed state after tap (animated)', async () => {
187
+ await element(by.id('animated-color-test-pressable')).tap()
188
+ await new Promise((resolve) => setTimeout(resolve, 100))
189
+ await expect(element(by.id('animated-is-pressed'))).toHaveText('Pressed: NO')
190
+ })
191
+
192
+ it('should show blue background at rest (animated)', async () => {
193
+ await new Promise((resolve) => setTimeout(resolve, 100))
194
+ const restScreenshot = await element(
195
+ by.id('animated-color-test-pressable')
196
+ ).takeScreenshot('animated-color-test-rest')
197
+
198
+ const color = getDominantColor(restScreenshot)
199
+ assert.ok(
200
+ isBlueish(color),
201
+ `Expected blue at rest (animated), got RGB(${color.r}, ${color.g}, ${color.b})`
202
+ )
203
+ })
204
+
205
+ it('should unpress when finger drags off animated element', async () => {
206
+ await expect(element(by.id('animated-press-in-count'))).toHaveText('In: 0')
207
+ await expect(element(by.id('animated-press-out-count'))).toHaveText('Out: 0')
208
+
209
+ await element(by.id('animated-color-test-pressable')).longPressAndDrag(
210
+ 500,
211
+ 0.5,
212
+ 0.5,
213
+ element(by.id('press-style-native-root')),
214
+ 0.5,
215
+ 0.1,
216
+ 'slow',
217
+ 100
218
+ )
219
+
220
+ await new Promise((resolve) => setTimeout(resolve, 100))
221
+
222
+ await expect(element(by.id('animated-press-in-count'))).toHaveText('In: 1')
223
+ await expect(element(by.id('animated-press-out-count'))).toHaveText('Out: 1')
224
+ await expect(element(by.id('animated-is-pressed'))).toHaveText('Pressed: NO')
225
+ })
226
+ })
227
+ })
228
+
229
+ async function navigateToPressStyleNative() {
230
+ await navigateToTestCase('PressStyleNative', 'color-test-pressable')
231
+ }