detox 21.0.0-rc.6 → 21.0.0-rc.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. package/.eslintignore +1 -0
  2. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar → 21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar} +0 -0
  3. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.md5 +1 -0
  4. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha1 +1 -0
  5. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha256 +1 -0
  6. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-javadoc.jar.sha512 +1 -0
  7. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar → 21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar} +0 -0
  8. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.md5 +1 -0
  9. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha1 +1 -0
  10. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha256 +1 -0
  11. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8-sources.jar.sha512 +1 -0
  12. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar +0 -0
  13. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.md5 +1 -0
  14. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha1 +1 -0
  15. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha256 +1 -0
  16. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.aar.sha512 +1 -0
  17. package/Detox-android/com/wix/detox/{21.0.0-rc.6/detox-21.0.0-rc.6.pom → 21.0.0-rc.8/detox-21.0.0-rc.8.pom} +1 -7
  18. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.md5 +1 -0
  19. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha1 +1 -0
  20. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha256 +1 -0
  21. package/Detox-android/com/wix/detox/21.0.0-rc.8/detox-21.0.0-rc.8.pom.sha512 +1 -0
  22. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  26. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  27. package/Detox-ios-framework.tbz +0 -0
  28. package/Detox-ios-src.tbz +0 -0
  29. package/Detox-ios-xcuitest.tbz +0 -0
  30. package/android/detox/build.gradle +13 -8
  31. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
  32. package/android/detox/src/full/java/com/wix/detox/espresso/EspressoDetox.java +6 -7
  33. package/android/detox/src/full/java/com/wix/detox/espresso/action/AdjustSliderToPositionAction.kt +2 -2
  34. package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +34 -35
  35. package/android/detox/src/full/java/com/wix/detox/espresso/common/MaterialSliderHelper.kt +21 -0
  36. package/android/detox/src/full/java/com/wix/detox/espresso/common/{SliderHelper.kt → ReactSliderHelper.kt} +6 -5
  37. package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +2 -2
  38. package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +43 -0
  39. package/android/detox/src/full/java/com/wix/detox/espresso/performer/SingleViewActionPerformer.kt +19 -0
  40. package/android/detox/src/full/java/com/wix/detox/espresso/performer/ViewActionPerformer.kt +24 -0
  41. package/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java +4 -4
  42. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +7 -6
  43. package/android/detox/src/main/java/com/wix/detox/espresso/MultipleViewsAction.kt +4 -0
  44. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -1
  45. package/android/detox/src/main/java/com/wix/detox/espresso/ViewActionWithResult.kt +2 -1
  46. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/MotionEvents.kt +60 -4
  47. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +6 -5
  48. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/MaterialSliderHelperTest.kt +33 -0
  49. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/{SliderHelperTest.kt → ReactSliderHelperTest.kt} +3 -3
  50. package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
  51. package/android/detox/src/testFull/java/com/wix/invoke/JsonParserTest.java +23 -7
  52. package/android/detox/src/testFull/resources/targetInvocationEspressoWebDetoxScript.json +47 -0
  53. package/detox.d.ts +1840 -0
  54. package/globals.d.ts +23 -0
  55. package/index.d.ts +2 -1823
  56. package/internals.d.ts +11 -1
  57. package/jest.config.js +108 -0
  58. package/local-cli/reset-lock-file.js +5 -9
  59. package/local-cli/testCommand/TestRunnerCommand.js +26 -3
  60. package/local-cli/utils/interruptListeners.js +15 -0
  61. package/package.json +2 -100
  62. package/runners/jest/reporter.js +21 -1
  63. package/runners/jest/reporters/DetoxIPCReporter.js +34 -0
  64. package/runners/jest/reporters/DetoxReporterDispatcher.js +144 -0
  65. package/runners/jest/reporters/DetoxSummaryReporter.js +16 -0
  66. package/runners/jest/reporters/DetoxVerboseReporter.js +16 -0
  67. package/runners/jest/reporters/index.js +6 -0
  68. package/runners/jest/testEnvironment/index.js +11 -0
  69. package/src/DetoxWorker.js +5 -11
  70. package/src/android/core/NativeElement.js +26 -29
  71. package/src/android/core/WebElement.js +24 -6
  72. package/src/android/espressoapi/DetoxAssertion.js +16 -14
  73. package/src/android/espressoapi/EspressoDetox.js +9 -2
  74. package/src/android/espressoapi/web/WebElement.js +1 -4
  75. package/src/android/interactions/native.js +2 -3
  76. package/src/android/matchers/index.js +2 -1
  77. package/src/android/matchers/web.js +9 -1
  78. package/src/artifacts/providers/index.js +3 -3
  79. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
  80. package/src/configuration/composeLoggerConfig.js +1 -0
  81. package/src/configuration/composeRunnerConfig.js +3 -1
  82. package/src/devices/allocation/DeviceAllocator.js +66 -20
  83. package/src/devices/allocation/DeviceList.js +44 -0
  84. package/src/devices/allocation/DeviceRegistry.js +189 -0
  85. package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
  86. package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
  87. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +22 -17
  88. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +97 -38
  89. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +32 -45
  90. package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
  91. package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +37 -0
  92. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
  93. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +104 -32
  94. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +40 -31
  95. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +121 -0
  96. package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
  97. package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  98. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyInstance.js +83 -0
  99. package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyRecipe.js +25 -0
  100. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +95 -54
  101. package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
  102. package/src/devices/allocation/factories/android.js +29 -35
  103. package/src/devices/allocation/factories/ios.js +6 -7
  104. package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
  105. package/src/devices/common/drivers/android/cookies.d.ts +11 -0
  106. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
  107. package/src/devices/common/drivers/android/exec/ADB.js +1 -0
  108. package/src/devices/common/drivers/android/tools/instrumentationArgs.js +7 -1
  109. package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
  110. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +3 -1
  111. package/src/devices/cookies/index.js +0 -6
  112. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
  113. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +5 -4
  114. package/src/devices/runtime/factories/android.js +3 -11
  115. package/src/devices/runtime/factories/ios.js +3 -4
  116. package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
  117. package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
  118. package/src/devices/servicelocator/android/index.js +23 -0
  119. package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +1 -0
  120. package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
  121. package/src/{validation → devices/validation}/factories/index.js +1 -1
  122. package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
  123. package/src/environmentFactory.js +1 -11
  124. package/src/ios/web.js +27 -5
  125. package/src/ipc/IPCClient.js +22 -1
  126. package/src/ipc/IPCServer.js +42 -1
  127. package/src/ipc/SessionState.js +1 -0
  128. package/src/logger/DetoxLogger.js +2 -2
  129. package/src/realms/DetoxContext.js +8 -0
  130. package/src/realms/DetoxInternalsFacade.js +1 -0
  131. package/src/realms/DetoxPrimaryContext.js +48 -42
  132. package/src/realms/DetoxSecondaryContext.js +27 -0
  133. package/src/realms/symbols.js +6 -0
  134. package/src/utils/PIDService.js +27 -0
  135. package/src/utils/assertIsFunction.js +35 -0
  136. package/src/utils/environment.js +8 -15
  137. package/src/utils/errorUtils.js +3 -3
  138. package/src/utils/isArrowFunction.js +24 -0
  139. package/tsconfig.json +8 -3
  140. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.md5 +0 -1
  141. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha1 +0 -1
  142. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha256 +0 -1
  143. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-javadoc.jar.sha512 +0 -1
  144. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.md5 +0 -1
  145. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha1 +0 -1
  146. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha256 +0 -1
  147. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6-sources.jar.sha512 +0 -1
  148. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar +0 -0
  149. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.md5 +0 -1
  150. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha1 +0 -1
  151. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha256 +0 -1
  152. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.aar.sha512 +0 -1
  153. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.md5 +0 -1
  154. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha1 +0 -1
  155. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha256 +0 -1
  156. package/Detox-android/com/wix/detox/21.0.0-rc.6/detox-21.0.0-rc.6.pom.sha512 +0 -1
  157. package/runners/jest/reporters/DetoxReporter.js +0 -36
  158. package/src/devices/DeviceRegistry.js +0 -176
  159. package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -30
  160. package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
  161. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
  162. package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
  163. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
  164. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +0 -21
  165. package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
  166. package/src/devices/common/drivers/DeviceLauncher.js +0 -19
  167. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
  168. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
  169. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
  170. package/src/devices/common/drivers/android/genycloud/services/dto/GenyInstance.js +0 -66
  171. package/src/devices/common/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -13
  172. package/src/devices/cookies/AndroidDeviceCookie.js +0 -13
  173. package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
  174. package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
  175. package/src/devices/cookies/DeviceCookie.js +0 -4
  176. package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -20
  177. package/src/devices/cookies/IosCookie.js +0 -6
  178. package/src/devices/cookies/IosSimulatorCookie.js +0 -10
  179. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
  180. package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
  181. package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
  182. package/src/servicelocator/android/index.js +0 -25
  183. package/src/servicelocator/ios.js +0 -7
  184. /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
  185. /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
package/.eslintignore CHANGED
@@ -1,3 +1,4 @@
1
+ *.d.ts
1
2
  /src/android/espressoapi/**/*.js
2
3
  /coverage
3
4
  /ios
@@ -0,0 +1 @@
1
+ 6f8df92328cba3c347dd4e4427396250
@@ -0,0 +1 @@
1
+ 5be4813876a084e04c493d60a92eb2c589f10789
@@ -0,0 +1 @@
1
+ 80ca5fcc5a96587755eb9c9baa1a8eb345037cf9645260320e0a8ecf170feec4
@@ -0,0 +1 @@
1
+ 8d5e6bafb794589e3ab60e6f324a2f2a4c1b89fb5048ff11db276cbcf682a60d222e3b3858e52ef2aebf37f98f20afda5142c0e05c482664614b674af6a9d25a
@@ -0,0 +1 @@
1
+ 5637f554cf5e23fe5d0e725ab23dbacb
@@ -0,0 +1 @@
1
+ ea41dbdf5eb71a62381c36a693ede65b5e6ae921
@@ -0,0 +1 @@
1
+ b89f30cd8de1c6bebeba153b84772afec0e7f3191352dc48922d76dc2a6cac7f
@@ -0,0 +1 @@
1
+ 61c96cabc733333637f6173df7c538ebed44aed656d0a54cdab5419d473df5e150bea2070f73086563896efa0e888e6bbfd1d7f17eb73ac505ac516dd3a1eb5f
@@ -0,0 +1 @@
1
+ 5037d89ac5d98e47d69d63b8731e7e3a
@@ -0,0 +1 @@
1
+ b4a0f9db575d92cb2da51c617e0ff531330cc2c6
@@ -0,0 +1 @@
1
+ 1fa253115965db1c97bc6c8b0c1ab0dff9ac9f8714e063dc972332cc6798b63a
@@ -0,0 +1 @@
1
+ 8174914ad6abe68c79f4812a32d292e80d922239045a30401bc39f43801f3cd2ea2807786248ffb58e84dfcdb8eddc00c7f606a874eb216def9350d325442af3
@@ -3,7 +3,7 @@
3
3
  <modelVersion>4.0.0</modelVersion>
4
4
  <groupId>com.wix</groupId>
5
5
  <artifactId>detox</artifactId>
6
- <version>21.0.0-rc.6</version>
6
+ <version>21.0.0-rc.8</version>
7
7
  <packaging>aar</packaging>
8
8
  <name>Detox</name>
9
9
  <description>Gray box end-to-end testing and automation library for mobile apps</description>
@@ -84,12 +84,6 @@
84
84
  <version>1.2.0</version>
85
85
  <scope>runtime</scope>
86
86
  </dependency>
87
- <dependency>
88
- <groupId>com.google.android.material</groupId>
89
- <artifactId>material</artifactId>
90
- <version>1.2.1</version>
91
- <scope>runtime</scope>
92
- </dependency>
93
87
  <dependency>
94
88
  <groupId>org.apache.commons</groupId>
95
89
  <artifactId>commons-lang3</artifactId>
@@ -0,0 +1 @@
1
+ 3666928049418f36238914ca430da3cd
@@ -0,0 +1 @@
1
+ 51596249cac9333a3e338740d52ff66699e15487
@@ -0,0 +1 @@
1
+ d4443a8744f5892a3297abbd3cc2249cc120cd89fb6f691cbfc806b3d1a84f9c
@@ -0,0 +1 @@
1
+ 34c19639936e8564b19dc66eb4efe93f649531bb4195913e480b3b57fa6483c175577a9a3bfdd898969b8017d41b74d3bed41ff43d3a648676b076ff2bdb4b84
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>21.0.0-rc.6</latest>
7
- <release>21.0.0-rc.6</release>
6
+ <latest>21.0.0-rc.8</latest>
7
+ <release>21.0.0-rc.8</release>
8
8
  <versions>
9
- <version>21.0.0-rc.6</version>
9
+ <version>21.0.0-rc.8</version>
10
10
  </versions>
11
- <lastUpdated>20231123122346</lastUpdated>
11
+ <lastUpdated>20231127142350</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 18eb4201618fabf33fcda7db7908fdce
1
+ b0fd2f4dcbd09935339fa69f32c91f40
@@ -1 +1 @@
1
- c0b642dd49ff218e421b75e8c14b995100411dbf
1
+ 930dfd4f45cab0a39d6fb2177f97a4d4966e9ed5
@@ -1 +1 @@
1
- 8a66b29ad27d11424c46bdf0392b95115709ef0e5cfa184cc9821a394d59f4f5
1
+ 1fa5da83f6119fc6bd7b673908597f7b7ca3acfdfad64c7f625b354200dc9fe4
@@ -1 +1 @@
1
- 3b1a51eba4bf3a471e6a4514e84f65ee458d089aede954723a7cffa14c473b959a03d14d9a183854435746f6d7bc7716f960f9819cc34c97732446d887fae9c2
1
+ 64eb3e238392456747f732d8e11566850d0b8cc0643d68f1e0fb988d88a58ffc6b5c98c2307d02048b3c4bcc7651b899c76f09107721be0f13ce0a44083b4299
Binary file
package/Detox-ios-src.tbz CHANGED
Binary file
Binary file
@@ -21,8 +21,12 @@ def _rnNativeArtifact = rnInfo.isRN71OrHigher
21
21
  : 'com.facebook.react:react-native:+'
22
22
 
23
23
  android {
24
- compileSdkVersion _compileSdkVersion
25
- buildToolsVersion _buildToolsVersion
24
+ def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
25
+ if (agpVersion >= 7) {
26
+ namespace "com.wix.detox"
27
+ }
28
+ compileSdk _compileSdkVersion
29
+ buildToolsVersion = _buildToolsVersion
26
30
 
27
31
  defaultConfig {
28
32
  minSdkVersion _minSdkVersion
@@ -33,7 +37,7 @@ android {
33
37
  consumerProguardFiles 'proguard-rules.pro'
34
38
  }
35
39
 
36
- flavorDimensions 'detox'
40
+ flavorDimensions = ['detox']
37
41
  productFlavors {
38
42
  full {
39
43
  dimension 'detox'
@@ -48,7 +52,7 @@ android {
48
52
  unitTests.returnDefaultValues = true
49
53
  unitTests.all { t ->
50
54
  reports {
51
- html.enabled true
55
+ html.required = true
52
56
  }
53
57
  testLogging {
54
58
  events "passed", "skipped", "failed", "standardOut", "standardError"
@@ -126,9 +130,6 @@ dependencies {
126
130
 
127
131
  // Third-party/extension deps.
128
132
  dependencies {
129
- implementation("com.google.android.material:material:$_materialMinVersion") {
130
- because 'Material components are mentioned explicitly (e.g. Slider in get-attributes handler)'
131
- }
132
133
  implementation('org.apache.commons:commons-lang3:3.7') {
133
134
  because 'Needed by invoke. Warning: Upgrading to newer versions is not seamless.'
134
135
  }
@@ -140,7 +141,7 @@ dependencies {
140
141
  // Unit-testing deps.
141
142
  dependencies {
142
143
  testImplementation "${_rnNativeArtifact}"
143
- testImplementation 'org.json:json:20140107'
144
+ testImplementation 'org.json:json:20230227'
144
145
 
145
146
  // https://github.com/spekframework/spek/issues/232#issuecomment-610732158
146
147
  testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
@@ -150,6 +151,10 @@ dependencies {
150
151
  testImplementation 'org.apache.commons:commons-io:1.3.2'
151
152
  testImplementation 'org.mockito.kotlin:mockito-kotlin:4.0.0'
152
153
  testImplementation 'org.robolectric:robolectric:4.4'
154
+
155
+ testImplementation("com.google.android.material:material:$_materialMinVersion") {
156
+ because 'Material components are mentioned explicitly (e.g. Slider in get-attributes handler)'
157
+ }
153
158
  }
154
159
 
155
160
  // Spek (https://spekframework.org/setup-android)
@@ -24,42 +24,57 @@ import static org.hamcrest.Matchers.not;
24
24
 
25
25
  public class DetoxAssertion {
26
26
 
27
+ private static final double NANOSECONDS_IN_A_SECOND = 1_000_000_000.0;
28
+
27
29
  private DetoxAssertion() {
28
- // static class
30
+ // This is a utility class and shouldn't be instantiated.
29
31
  }
30
32
 
31
- public static ViewInteraction assertMatcher(ViewInteraction i, Matcher<View> m) {
32
- return i.check(matches(m));
33
+ /**
34
+ * Asserts the given matcher for the provided view interaction.
35
+ */
36
+ public static ViewInteraction assertMatcher(ViewInteraction viewInteraction, Matcher<View> viewMatcher) {
37
+ return viewInteraction.check(matches(viewMatcher));
33
38
  }
34
39
 
35
- public static ViewInteraction assertNotVisible(ViewInteraction i) {
36
- ViewInteraction ret;
40
+ /**
41
+ * Asserts that the given view interaction is not visible.
42
+ */
43
+ public static ViewInteraction assertNotVisible(ViewInteraction viewInteraction) {
44
+ ViewInteraction result;
37
45
  try {
38
- ret = i.check(doesNotExist());
39
- return ret;
46
+ result = viewInteraction.check(doesNotExist());
47
+ return result;
40
48
  } catch (AssertionFailedError e) {
41
- ret = i.check(matches(not(isDisplayed())));
42
- return ret;
49
+ result = viewInteraction.check(matches(not(isDisplayed())));
50
+ return result;
43
51
  }
44
52
  }
45
53
 
46
- public static ViewInteraction assertNotExists(ViewInteraction i) {
47
- return i.check(doesNotExist());
54
+ /**
55
+ * Asserts that the given view interaction does not exist.
56
+ */
57
+ public static ViewInteraction assertNotExists(ViewInteraction viewInteraction) {
58
+ return viewInteraction.check(doesNotExist());
48
59
  }
49
60
 
50
- public static void waitForAssertMatcher(final ViewInteraction i, final Matcher<View> m, double timeoutSeconds) {
51
- final long originTime = System.nanoTime();
61
+ /**
62
+ * Waits until the provided matcher matches the view interaction or a timeout occurs.
63
+ */
64
+ public static void waitForAssertMatcher(final ViewInteraction viewInteraction, final Matcher<View> viewMatcher, double timeoutSeconds) {
65
+ final long startTime = System.nanoTime();
52
66
 
53
67
  while (true) {
54
68
  long currentTime = System.nanoTime();
55
- long elapsed = currentTime - originTime;
56
- double seconds = (double) elapsed / 1000000000.0;
57
- if (seconds >= timeoutSeconds) {
58
- throw new DetoxRuntimeException("" + timeoutSeconds + "sec timeout expired without matching of given matcher: " + m);
69
+ long elapsedTime = currentTime - startTime;
70
+ double elapsedSeconds = (double) elapsedTime / NANOSECONDS_IN_A_SECOND;
71
+ if (elapsedSeconds >= timeoutSeconds) {
72
+ throw new DetoxRuntimeException(
73
+ "" + timeoutSeconds + "sec timeout expired without matching of given matcher: " + viewMatcher);
59
74
  }
60
75
 
61
76
  try {
62
- i.check(matches(m));
77
+ viewInteraction.check(matches(viewMatcher));
63
78
  break;
64
79
  } catch (AssertionFailedError err) {
65
80
  UiAutomatorHelper.espressoSync(20);
@@ -67,21 +82,25 @@ public class DetoxAssertion {
67
82
  }
68
83
  }
69
84
 
85
+ /**
86
+ * Continually asserts the provided matcher until a search action returns a matching view or a
87
+ * `StaleActionException` error is thrown.
88
+ */
70
89
  public static void waitForAssertMatcherWithSearchAction(
71
- final ViewInteraction i,
72
- final Matcher<View> vm,
73
- final ViewAction searchAction,
74
- final Matcher<View> searchMatcher) {
75
-
90
+ final ViewInteraction viewInteraction,
91
+ final Matcher<View> viewMatcher,
92
+ final ViewAction searchAction,
93
+ final Matcher<View> searchMatcher
94
+ ) {
76
95
  while (true) {
77
96
  try {
78
- assertMatcher(i, vm);
97
+ assertMatcher(viewInteraction, viewMatcher);
79
98
  break;
80
99
  } catch (AssertionFailedError err) {
81
100
  try {
82
101
  onView(searchMatcher).perform(searchAction);
83
102
  } catch (StaleActionException exStaleAction) {
84
- assertMatcher(i, vm);
103
+ assertMatcher(viewInteraction, viewMatcher);
85
104
  break;
86
105
  }
87
106
  }
@@ -1,5 +1,7 @@
1
1
  package com.wix.detox.espresso;
2
2
 
3
+ import com.wix.detox.espresso.performer.ViewActionPerformer;
4
+
3
5
  import android.app.Activity;
4
6
  import android.content.Context;
5
7
  import android.content.ContextWrapper;
@@ -20,6 +22,7 @@ import java.util.ArrayList;
20
22
  import androidx.test.espresso.UiController;
21
23
  import androidx.test.espresso.ViewAction;
22
24
  import androidx.test.espresso.ViewInteraction;
25
+ import androidx.test.espresso.NoMatchingViewException;
23
26
  import androidx.test.platform.app.InstrumentationRegistry;
24
27
 
25
28
  import static androidx.test.espresso.Espresso.onView;
@@ -31,13 +34,9 @@ import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
31
34
  public class EspressoDetox {
32
35
  private static final String LOG_TAG = "detox";
33
36
 
34
- public static Object perform(ViewInteraction interaction, ViewAction action) {
35
- interaction.perform(action);
36
-
37
- if (action instanceof ViewActionWithResult) {
38
- return ((ViewActionWithResult) action).getResult();
39
- }
40
- return null;
37
+ public static Object perform(Matcher<View> matcher, ViewAction action) {
38
+ ViewActionPerformer performer = ViewActionPerformer.forAction(action);
39
+ return performer.performOn(matcher);
41
40
  }
42
41
 
43
42
  public static Activity getActivity(Context context) {
@@ -6,7 +6,7 @@ import androidx.test.espresso.UiController
6
6
  import androidx.test.espresso.ViewAction
7
7
  import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
8
8
  import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
9
- import com.wix.detox.espresso.common.SliderHelper
9
+ import com.wix.detox.espresso.common.ReactSliderHelper
10
10
  import org.hamcrest.Matcher
11
11
  import org.hamcrest.Matchers
12
12
 
@@ -16,7 +16,7 @@ class AdjustSliderToPositionAction(private val targetPositionPct: Double) : View
16
16
  Matchers.allOf( isDisplayed(), isAssignableFrom(AppCompatSeekBar::class.java) )
17
17
 
18
18
  override fun perform(uiController: UiController?, view: View) {
19
- val sliderHelper = SliderHelper.create(view)
19
+ val sliderHelper = ReactSliderHelper.create(view)
20
20
  sliderHelper.setProgressPct(targetPositionPct)
21
21
  }
22
22
  }
@@ -7,9 +7,10 @@ import android.widget.CheckBox
7
7
  import android.widget.ProgressBar
8
8
  import android.widget.TextView
9
9
  import androidx.test.espresso.UiController
10
- import com.google.android.material.slider.Slider
11
10
  import com.wix.detox.espresso.ViewActionWithResult
12
- import com.wix.detox.espresso.common.SliderHelper
11
+ import com.wix.detox.espresso.MultipleViewsAction
12
+ import com.wix.detox.espresso.common.ReactSliderHelper
13
+ import com.wix.detox.espresso.common.MaterialSliderHelper
13
14
  import com.wix.detox.reactnative.ui.getAccessibilityLabel
14
15
  import org.hamcrest.Matcher
15
16
  import org.hamcrest.Matchers
@@ -17,26 +18,27 @@ import org.hamcrest.Matchers.allOf
17
18
  import org.hamcrest.Matchers.notNullValue
18
19
  import org.json.JSONObject
19
20
 
20
- class GetAttributesAction() : ViewActionWithResult<String?> {
21
- private val commonAttributes = CommonAttributes()
22
- private val textViewAttributes = TextViewAttributes()
23
- private val checkBoxAttributes = CheckBoxAttributes()
24
- private val progressBarAttributes = ProgressBarAttributes()
25
- private val sliderAttributes = SliderAttributes()
26
- private var result: String = ""
21
+ private interface AttributeExtractor {
22
+ fun extractAttributes(json: JSONObject, view: View)
23
+ }
24
+
25
+ class GetAttributesAction() : ViewActionWithResult<JSONObject?>, MultipleViewsAction {
26
+ private val attributeExtractors = listOf(
27
+ CommonAttributes(),
28
+ TextViewAttributes(),
29
+ CheckBoxAttributes(),
30
+ ProgressBarAttributes(),
31
+ MaterialSliderAttributes()
32
+ )
33
+ private var result: JSONObject? = null
27
34
 
28
35
  override fun perform(uiController: UiController?, view: View?) {
29
36
  view!!
30
37
 
31
38
  val json = JSONObject()
39
+ attributeExtractors.forEach { it.extractAttributes(json, view) }
32
40
 
33
- commonAttributes.get(json, view)
34
- textViewAttributes.get(json, view)
35
- checkBoxAttributes.get(json, view)
36
- progressBarAttributes.get(json, view)
37
- sliderAttributes.get(json, view)
38
-
39
- result = json.toString()
41
+ result = json
40
42
  }
41
43
 
42
44
  override fun getResult() = result
@@ -44,8 +46,8 @@ class GetAttributesAction() : ViewActionWithResult<String?> {
44
46
  override fun getConstraints(): Matcher<View> = allOf(notNullValue(), Matchers.isA(View::class.java))
45
47
  }
46
48
 
47
- private class CommonAttributes {
48
- fun get(json: JSONObject, view: View) {
49
+ private class CommonAttributes : AttributeExtractor {
50
+ override fun extractAttributes(json: JSONObject, view: View) {
49
51
  getId(json, view)
50
52
  getVisibility(json, view)
51
53
  getAccessibilityLabel(json, view)
@@ -89,8 +91,8 @@ private class CommonAttributes {
89
91
  }
90
92
  }
91
93
 
92
- private class TextViewAttributes {
93
- fun get(json: JSONObject, view: View) {
94
+ private class TextViewAttributes : AttributeExtractor {
95
+ override fun extractAttributes(json: JSONObject, view: View) {
94
96
  if (view is TextView) {
95
97
  getText(json, view)
96
98
  getLength(json, view)
@@ -118,8 +120,8 @@ private class TextViewAttributes {
118
120
  }
119
121
  }
120
122
 
121
- private class CheckBoxAttributes {
122
- fun get(json: JSONObject, view: View) {
123
+ private class CheckBoxAttributes : AttributeExtractor {
124
+ override fun extractAttributes(json: JSONObject, view: View) {
123
125
  if (view is CheckBox) {
124
126
  getCheckboxValue(json, view)
125
127
  }
@@ -133,31 +135,28 @@ private class CheckBoxAttributes {
133
135
  * Note: this applies also to [androidx.appcompat.widget.AppCompatSeekBar], which
134
136
  * is anything RN-slider-ish.
135
137
  */
136
- private class ProgressBarAttributes {
137
- fun get(json: JSONObject, view: View) {
138
+ private class ProgressBarAttributes : AttributeExtractor {
139
+ override fun extractAttributes(json: JSONObject, view: View) {
138
140
  if (view is ProgressBar) {
139
- SliderHelper.maybeCreate(view)?.let {
140
- getRNSliderValue(json, it)
141
+ ReactSliderHelper.maybeCreate(view)?.let {
142
+ getReactSliderValue(json, it)
141
143
  } ?:
142
144
  getProgressBarValue(json, view)
143
145
  }
144
146
  }
145
147
 
146
- private fun getRNSliderValue(rootObject: JSONObject, sliderHelper: SliderHelper) {
147
- rootObject.put("value", sliderHelper.getCurrentProgressPct())
148
+ private fun getReactSliderValue(rootObject: JSONObject, reactSliderHelper: ReactSliderHelper) {
149
+ rootObject.put("value", reactSliderHelper.getCurrentProgressPct())
148
150
  }
149
151
 
150
152
  private fun getProgressBarValue(rootObject: JSONObject, view: ProgressBar) =
151
153
  rootObject.put("value", view.progress)
152
154
  }
153
155
 
154
- private class SliderAttributes {
155
- fun get(json: JSONObject, view: View) {
156
- if (view is Slider) {
157
- getSliderValue(json, view)
156
+ private class MaterialSliderAttributes : AttributeExtractor {
157
+ override fun extractAttributes(json: JSONObject, view: View) {
158
+ MaterialSliderHelper(view).getValueIfSlider()?.let {
159
+ json.put("value", it)
158
160
  }
159
161
  }
160
-
161
- private fun getSliderValue(rootObject: JSONObject, view: Slider) =
162
- rootObject.put("value", view.value)
163
162
  }
@@ -0,0 +1,21 @@
1
+ package com.wix.detox.espresso.common
2
+
3
+ import android.view.View
4
+ import com.wix.detox.espresso.action.common.ReflectUtils
5
+ import org.joor.Reflect
6
+
7
+ private const val CLASS_MATERIAL_SLIDER = "com.google.android.material.slider.Slider"
8
+
9
+ open class MaterialSliderHelper(protected val view: View) {
10
+ fun getValueIfSlider(): Float? {
11
+ if (!isSlider()) {
12
+ return null
13
+ }
14
+
15
+ return getValue()
16
+ }
17
+
18
+ private fun isSlider() = ReflectUtils.isAssignableFrom(view, CLASS_MATERIAL_SLIDER)
19
+
20
+ private fun getValue() = Reflect.on(view).call("getValue").get() as Float
21
+ }
@@ -11,8 +11,9 @@ import org.joor.Reflect
11
11
 
12
12
  private const val CLASS_REACT_SLIDER_LEGACY = "com.facebook.react.views.slider.ReactSlider"
13
13
  private const val CLASS_REACT_SLIDER_COMMUNITY = "com.reactnativecommunity.slider.ReactSlider"
14
+ private const val CLASS_REACT_SLIDER_COMMUNITY_MANAGER = "com.reactnativecommunity.slider.ReactSliderManager"
14
15
 
15
- abstract class SliderHelper(protected val slider: AppCompatSeekBar) {
16
+ abstract class ReactSliderHelper(protected val slider: AppCompatSeekBar) {
16
17
  fun getCurrentProgressPct(): Double {
17
18
  val nativeProgress = slider.progress.toDouble()
18
19
  val nativeMax = slider.max
@@ -46,7 +47,7 @@ abstract class SliderHelper(protected val slider: AppCompatSeekBar) {
46
47
  ?: throw DetoxIllegalStateException("Cannot handle this type of a seek-bar view (Class ${view.javaClass.canonicalName}). " +
47
48
  "Only React Native sliders are currently supported.")
48
49
 
49
- fun maybeCreate(view: View): SliderHelper? =
50
+ fun maybeCreate(view: View): ReactSliderHelper? =
50
51
  when {
51
52
  ReflectUtils.isAssignableFrom(view, CLASS_REACT_SLIDER_LEGACY)
52
53
  -> LegacySliderHelper(view as ReactSlider)
@@ -58,7 +59,7 @@ abstract class SliderHelper(protected val slider: AppCompatSeekBar) {
58
59
  }
59
60
  }
60
61
 
61
- private class LegacySliderHelper(slider: ReactSlider): SliderHelper(slider) {
62
+ private class LegacySliderHelper(slider: ReactSlider): ReactSliderHelper(slider) {
62
63
  override fun setProgressJS(valueJS: Double) {
63
64
  val reactSliderManager = com.facebook.react.views.slider.ReactSliderManager()
64
65
  reactSliderManager.updateProperties(slider as ReactSlider, buildStyles("value", valueJS))
@@ -67,9 +68,9 @@ private class LegacySliderHelper(slider: ReactSlider): SliderHelper(slider) {
67
68
  private fun buildStyles(vararg keysAndValues: Any) = ReactStylesDiffMap(JavaOnlyMap.of(*keysAndValues))
68
69
  }
69
70
 
70
- private class CommunitySliderHelper(slider: AppCompatSeekBar): SliderHelper(slider) {
71
+ private class CommunitySliderHelper(slider: AppCompatSeekBar): ReactSliderHelper(slider) {
71
72
  override fun setProgressJS(valueJS: Double) {
72
- val reactSliderManager = Class.forName("com.reactnativecommunity.slider.ReactSliderManager").newInstance()
73
+ val reactSliderManager = Class.forName(CLASS_REACT_SLIDER_COMMUNITY_MANAGER).newInstance()
73
74
  Reflect.on(reactSliderManager).call("setValue", slider, valueJS)
74
75
  }
75
76
  }
@@ -7,7 +7,7 @@ import androidx.appcompat.widget.AppCompatSeekBar
7
7
  import androidx.test.espresso.matcher.BoundedMatcher
8
8
  import androidx.test.espresso.matcher.ViewMatchers
9
9
  import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
10
- import com.wix.detox.espresso.common.SliderHelper
10
+ import com.wix.detox.espresso.common.ReactSliderHelper
11
11
  import org.hamcrest.*
12
12
  import org.hamcrest.Matchers.*
13
13
  import kotlin.math.abs
@@ -60,7 +60,7 @@ fun toHaveSliderPosition(expectedValuePct: Double, tolerance: Double): Matcher<V
60
60
  }
61
61
 
62
62
  override fun matchesSafely(view: AppCompatSeekBar): Boolean {
63
- val sliderHelper = SliderHelper.create(view)
63
+ val sliderHelper = ReactSliderHelper.create(view)
64
64
  val progressPct = sliderHelper.getCurrentProgressPct()
65
65
  return (abs(progressPct - expectedValuePct) <= tolerance)
66
66
  }
@@ -0,0 +1,43 @@
1
+ package com.wix.detox.espresso.performer
2
+
3
+ import com.wix.detox.espresso.DetoxMatcher
4
+ import com.wix.detox.espresso.ViewActionWithResult
5
+
6
+ import android.view.View
7
+ import androidx.test.espresso.Espresso.onView
8
+ import androidx.test.espresso.NoMatchingViewException
9
+ import androidx.test.espresso.ViewAction
10
+ import org.hamcrest.Matcher
11
+
12
+ class MultipleViewsActionPerformer(
13
+ private val action: ViewAction
14
+ ) : ViewActionPerformer {
15
+ override fun performOn(matcher: Matcher<View>): Any? {
16
+ val results = mutableListOf<Any?>()
17
+ var index = 0
18
+
19
+ while (true) {
20
+ val indexedMatcher = DetoxMatcher.matcherForAtIndex(index, matcher)
21
+
22
+ try {
23
+ onView(indexedMatcher).perform(action)
24
+
25
+ (action as? ViewActionWithResult<*>)?.getResult()?.let { results.add(it) }
26
+
27
+ index++
28
+ } catch (e: NoMatchingViewException) {
29
+ if (index == 0) {
30
+ throw e
31
+ }
32
+
33
+ break
34
+ }
35
+ }
36
+
37
+ return when {
38
+ results.isEmpty() -> null
39
+ results.size == 1 -> results.first()
40
+ else -> mapOf("elements" to results)
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,19 @@
1
+ package com.wix.detox.espresso.performer
2
+
3
+ import com.wix.detox.espresso.ViewActionWithResult
4
+
5
+ import android.view.View
6
+ import androidx.test.espresso.Espresso.onView
7
+ import androidx.test.espresso.NoMatchingViewException
8
+ import androidx.test.espresso.ViewAction
9
+ import org.hamcrest.Matcher
10
+
11
+ class SingleViewActionPerformer(
12
+ private val action: ViewAction
13
+ ) : ViewActionPerformer {
14
+ override fun performOn(matcher: Matcher<View>): Any? {
15
+ onView(matcher).perform(action)
16
+
17
+ return (action as? ViewActionWithResult<*>)?.getResult()
18
+ }
19
+ }