detox 20.20.2 → 20.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/Detox-android/com/wix/detox/{20.20.2/detox-20.20.2-sources.jar → 20.21.0/detox-20.21.0-sources.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0-sources.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0-sources.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0-sources.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0-sources.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.aar +0 -0
  7. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.aar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.aar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.aar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.aar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/{20.20.2/detox-20.20.2.pom → 20.21.0/detox-20.21.0.pom} +1 -1
  12. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.pom.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.pom.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.pom.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.21.0/detox-20.21.0.pom.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  17. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  18. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  19. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  20. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  21. package/Detox-android/com/wix/detox-legacy/{20.20.2/detox-legacy-20.20.2-sources.jar → 20.21.0/detox-legacy-20.21.0-sources.jar} +0 -0
  22. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0-sources.jar.md5 +1 -0
  23. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0-sources.jar.sha1 +1 -0
  24. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0-sources.jar.sha256 +1 -0
  25. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0-sources.jar.sha512 +1 -0
  26. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.aar +0 -0
  27. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.aar.md5 +1 -0
  28. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.aar.sha1 +1 -0
  29. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.aar.sha256 +1 -0
  30. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.aar.sha512 +1 -0
  31. package/Detox-android/com/wix/detox-legacy/{20.20.2/detox-legacy-20.20.2.pom → 20.21.0/detox-legacy-20.21.0.pom} +1 -1
  32. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.pom.md5 +1 -0
  33. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.pom.sha1 +1 -0
  34. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.pom.sha256 +1 -0
  35. package/Detox-android/com/wix/detox-legacy/20.21.0/detox-legacy-20.21.0.pom.sha512 +1 -0
  36. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml +4 -4
  37. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.md5 +1 -1
  38. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha1 +1 -1
  39. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha256 +1 -1
  40. package/Detox-android/com/wix/detox-legacy/maven-metadata.xml.sha512 +1 -1
  41. package/Detox-ios-src.tbz +0 -0
  42. package/Detox-ios.tbz +0 -0
  43. package/android/detox/src/coreNative/java/com/wix/detox/actions/DetoxViewActions.kt +2 -2
  44. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAction.java +39 -15
  45. package/android/detox/src/full/java/com/wix/detox/espresso/action/RNClickAction.java +13 -11
  46. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactMarkersLogger.kt +3 -1
  47. package/android/detox/src/main/java/com/wix/detox/espresso/action/{DetoxMultiTap.kt → DetoxCustomTapper.kt} +8 -6
  48. package/android/detox/src/main/java/com/wix/detox/espresso/action/DetoxSingleTap.kt +1 -1
  49. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/DetoxViewConfiguration.kt +10 -0
  50. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/TapEvents.kt +12 -4
  51. package/android/detox/src/main/java/com/wix/detox/espresso/scroll/DetoxScrollActions.kt +3 -1
  52. package/android/detox/src/main/java/com/wix/detox/espresso/scroll/DetoxSwipe.kt +1 -1
  53. package/android/detox/src/main/java/com/wix/detox/espresso/scroll/ScrollHelper.java +2 -2
  54. package/android/detox/src/testFull/java/com/wix/detox/common/TapEventsSpec.kt +15 -3
  55. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/{DetoxMultiTapSpec.kt → DetoxCustomTapperSpec.kt} +21 -11
  56. package/detox.d.ts +34 -22
  57. package/jest.config.js +1 -1
  58. package/package.json +3 -3
  59. package/src/android/actions/native.js +4 -2
  60. package/src/android/core/NativeElement.js +6 -3
  61. package/src/android/espressoapi/DetoxAction.js +105 -0
  62. package/src/ios/expectTwo.js +23 -12
  63. package/src/utils/assertArgument.js +28 -0
  64. package/src/utils/invocationTraceDescriptions.js +1 -1
  65. package/src/utils/mapLongPressArguments.js +32 -0
  66. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2-sources.jar.md5 +0 -1
  67. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2-sources.jar.sha1 +0 -1
  68. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2-sources.jar.sha256 +0 -1
  69. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2-sources.jar.sha512 +0 -1
  70. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.aar +0 -0
  71. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.aar.md5 +0 -1
  72. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.aar.sha1 +0 -1
  73. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.aar.sha256 +0 -1
  74. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.aar.sha512 +0 -1
  75. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.pom.md5 +0 -1
  76. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.pom.sha1 +0 -1
  77. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.pom.sha256 +0 -1
  78. package/Detox-android/com/wix/detox/20.20.2/detox-20.20.2.pom.sha512 +0 -1
  79. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2-sources.jar.md5 +0 -1
  80. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2-sources.jar.sha1 +0 -1
  81. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2-sources.jar.sha256 +0 -1
  82. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2-sources.jar.sha512 +0 -1
  83. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.aar +0 -0
  84. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.aar.md5 +0 -1
  85. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.aar.sha1 +0 -1
  86. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.aar.sha256 +0 -1
  87. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.aar.sha512 +0 -1
  88. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.pom.md5 +0 -1
  89. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.pom.sha1 +0 -1
  90. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.pom.sha256 +0 -1
  91. package/Detox-android/com/wix/detox-legacy/20.20.2/detox-legacy-20.20.2.pom.sha512 +0 -1
  92. package/android/detox/src/main/java/com/wix/detox/espresso/scroll/FlinglessSwiper.kt +0 -50
  93. package/android/detox/src/testFull/java/com/wix/detox/espresso/scroll/FlinglessSwiperSpec.kt +0 -237
@@ -0,0 +1 @@
1
+ 3387de0925b210d074f132cf01ac3de0
@@ -0,0 +1 @@
1
+ 559b5fbefe99b614d2a1dd80e0ad47f06ffc5408
@@ -0,0 +1 @@
1
+ c3b9ef703b247428ada96d85eacf933c8c2b7d274335c75f9d4d32dd25028e9d
@@ -0,0 +1 @@
1
+ 492d5dbb4ffc6c504fcc121021595d03221c7ede4d2ef61bc5c959df19968d732baf6940a2b839a551a52b65ef721c08e7b9f4028d4b90808b224a8d80bbc984
@@ -0,0 +1 @@
1
+ 31bc3655525c5e1de60651828dbe4b23
@@ -0,0 +1 @@
1
+ 05e3d3c1fb1dfe0ef619885bd89f3e23ad265c14
@@ -0,0 +1 @@
1
+ 4c664be552f9844c390dcf9843c16195ee71ae5fac82340fc2fa26d7f98f97da
@@ -0,0 +1 @@
1
+ b9a385a9b94cf5b0bec34751c9c7e03fd7cd8f6f094beac31df31bed89dbe93895289e45a08cf230a9806c71786ae74c75e8f58f3f57814624af8fa28e6b76d6
@@ -3,7 +3,7 @@
3
3
  <modelVersion>4.0.0</modelVersion>
4
4
  <groupId>com.wix</groupId>
5
5
  <artifactId>detox</artifactId>
6
- <version>20.20.2</version>
6
+ <version>20.21.0</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>
@@ -0,0 +1 @@
1
+ 05807a16588292d8975405f31295b594
@@ -0,0 +1 @@
1
+ f0ad65330c51d3a57e1e381edc64ddd7f10d5d11
@@ -0,0 +1 @@
1
+ 720b6a69502a1047d143f23b5db0793c965f04f1d6fccd04b3472f64eac38d67
@@ -0,0 +1 @@
1
+ 4857f694c3a4ba4c0a0e3a14e78906032687be8062d9630b658bbd7bedd3fb1098a989f86b11f7fc00ffad1b9927ff2dbaf48dfd74818f5e1c08ed9d26a267a5
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.20.2</latest>
7
- <release>20.20.2</release>
6
+ <latest>20.21.0</latest>
7
+ <release>20.21.0</release>
8
8
  <versions>
9
- <version>20.20.2</version>
9
+ <version>20.21.0</version>
10
10
  </versions>
11
- <lastUpdated>20240413085537</lastUpdated>
11
+ <lastUpdated>20240513104458</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- b134664763a162e01d64004a8608d797
1
+ ee4539794be82f984845b866ce47d797
@@ -1 +1 @@
1
- 3bcc241bab8016602b4b8b17712e202423625e9d
1
+ 047da11f8d7764ce83a44415f5ca14150b0d26e8
@@ -1 +1 @@
1
- 9dd3c8a8de9979cbe9b7a05d40f67eab21ff57ff02c0402cbe19e9a6bbdfb943
1
+ aa8c3fb9036b5f238114a0cc799621647355991b7b8d2d45653a4f283d2a1426
@@ -1 +1 @@
1
- 0ffda11da4e0d1d79df1bfd756c6707fae5b0b863089cd9c9a8568f938a649e2ee1b70641bb8c49478ab3508964fdc057390cdbfd16ab7352a320ce0339831c3
1
+ 749a441df252d5a784d527cfb9e9179724c3bdfc95f10f40c305a7e260f717a63813b933921861a8593f61ea548f70bf7f9f8f4a5c19aaa1cd3b3480b081fc8e
@@ -0,0 +1 @@
1
+ f297dccee1b070c04339c6d3a44aaf98
@@ -0,0 +1 @@
1
+ 67a54cce54b41b23776bb74111f65aa2690445c1
@@ -0,0 +1 @@
1
+ 54663486b8606482cc50334d106f99584d8ed62a030a7599d3a74328606e2175
@@ -0,0 +1 @@
1
+ 79ac3563b92cd6ac25acc93885c0e866a2f1190d08988499261cfdf247f5fa4c5f8d3f5aa297f8682e822fdf751f89196fe4e0556d7328a40b39f7079179cddb
@@ -0,0 +1 @@
1
+ f35c1d0b6e6002973dc3a27dcd693666
@@ -0,0 +1 @@
1
+ 95b13b9d33524b8c704258c314a3e21572086d45
@@ -0,0 +1 @@
1
+ a40f50e7629a8076af5698aa1a533523ea1bc53782240ff01be641911d8865b2
@@ -0,0 +1 @@
1
+ c3c9d8eca84ce4da0e1a75a7364ec0a8df8fd1b910db22769b719d4c222fbb726ba973a41c35eeab77db3603c87a31d8b85bb71cd6c5d25bdb36d48f72733fa4
@@ -3,7 +3,7 @@
3
3
  <modelVersion>4.0.0</modelVersion>
4
4
  <groupId>com.wix</groupId>
5
5
  <artifactId>detox-legacy</artifactId>
6
- <version>20.20.2</version>
6
+ <version>20.21.0</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>
@@ -0,0 +1 @@
1
+ 16fb38e9f0b98073b38adbc235fe3be4
@@ -0,0 +1 @@
1
+ 043d16e8f617a51b47e9f9f53f96acd4a7bd5958
@@ -0,0 +1 @@
1
+ a31050af14f97ee5232e932d0ff9c7e6f7703b6eb07c528da9c86ddc6b9e7670
@@ -0,0 +1 @@
1
+ 037112076433da9365a46eeffd53e9556da255f081a7af4b781b902d9f52508242d0a9d8bb1e5f6a64ad2e243bdb54cab48c301b1c3e39853dde2ed0c1deffe1
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox-legacy</artifactId>
5
5
  <versioning>
6
- <latest>20.20.2</latest>
7
- <release>20.20.2</release>
6
+ <latest>20.21.0</latest>
7
+ <release>20.21.0</release>
8
8
  <versions>
9
- <version>20.20.2</version>
9
+ <version>20.21.0</version>
10
10
  </versions>
11
- <lastUpdated>20240413085703</lastUpdated>
11
+ <lastUpdated>20240513104609</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- cff8b68da66e7bcfd7ba77d71e03a5e2
1
+ d545ee1d9b3d980031a6d7f23ae6622e
@@ -1 +1 @@
1
- 7dbc9b7569e8af9e77ffb115a24cb32ec21136be
1
+ bf54a3a7dc2ac2d25d618a4c0426024abbec7163
@@ -1 +1 @@
1
- b7b643569d4382cfa7960e967a3ff2d99098baceb0174b1c5e63b4a4be045fe4
1
+ d4d8c6d7ec27c61a5846b9cfe99277edaf6fa785c41e33ac1b5fc91d263696a1
@@ -1 +1 @@
1
- 8f1f9f5adc530f4a2c04e3faa269ff3c0e20da8d802e92c49f01c9e0dc2d0fe87c8f6996d1f9af655653054dbf40dc171f409e2a8e2332de0816cdfac6c5d15b
1
+ 6b6bff10ef38514b6e3c3898837a22e219ca01d19f77e98b95cc317ec857713435d0392e5a49147b9db41397f6cf7f7cabc006b5bf641d341e144288291a19a7
package/Detox-ios-src.tbz CHANGED
Binary file
package/Detox-ios.tbz CHANGED
Binary file
@@ -9,14 +9,14 @@ import com.wix.detox.action.common.MOTION_DIR_DOWN
9
9
  import com.wix.detox.action.common.MOTION_DIR_LEFT
10
10
  import com.wix.detox.action.common.MOTION_DIR_RIGHT
11
11
  import com.wix.detox.action.common.MOTION_DIR_UP
12
- import com.wix.detox.espresso.action.DetoxMultiTap
12
+ import com.wix.detox.espresso.action.DetoxCustomTapper
13
13
  import com.wix.detox.espresso.scroll.DetoxScrollAction
14
14
 
15
15
  public object DetoxViewActions {
16
16
  public fun tap() = multiTap(1)
17
17
  public fun doubleTap() = multiTap(2)
18
18
  public fun multiTap(times: Int): ViewAction =
19
- actionWithAssertions(GeneralClickAction(DetoxMultiTap(times), GeneralLocation.CENTER, Press.FINGER, 0, 0))
19
+ actionWithAssertions(GeneralClickAction(DetoxCustomTapper(times), GeneralLocation.CENTER, Press.FINGER, 0, 0))
20
20
 
21
21
  public fun scrollUpBy(amountInDp: Double, startOffsetPercentX: Float? = null, startOffsetPercentY: Float? = null): ViewAction =
22
22
  actionWithAssertions(DetoxScrollAction(MOTION_DIR_UP, amountInDp, startOffsetPercentX, startOffsetPercentY))
@@ -20,7 +20,7 @@ import com.wix.detox.action.common.MotionDir;
20
20
  import com.wix.detox.common.DetoxErrors.DetoxRuntimeException;
21
21
  import com.wix.detox.common.DetoxErrors.StaleActionException;
22
22
  import com.wix.detox.espresso.action.AdjustSliderToPositionAction;
23
- import com.wix.detox.espresso.action.DetoxMultiTap;
23
+ import com.wix.detox.espresso.action.DetoxCustomTapper;
24
24
  import com.wix.detox.espresso.action.GetAttributesAction;
25
25
  import com.wix.detox.espresso.action.LongPressAndDragAction;
26
26
  import com.wix.detox.espresso.action.RNClickAction;
@@ -29,6 +29,7 @@ import com.wix.detox.espresso.action.ScreenshotResult;
29
29
  import com.wix.detox.espresso.action.ScrollToIndexAction;
30
30
  import com.wix.detox.espresso.action.TakeViewScreenshotAction;
31
31
  import com.wix.detox.espresso.action.common.utils.ViewInteractionExt;
32
+ import com.wix.detox.espresso.action.common.DetoxViewConfigurations;
32
33
  import com.wix.detox.espresso.scroll.DetoxScrollAction;
33
34
  import com.wix.detox.espresso.scroll.DetoxScrollActionStaleAtEdge;
34
35
  import com.wix.detox.espresso.scroll.ScrollEdgeException;
@@ -42,7 +43,6 @@ import java.text.SimpleDateFormat;
42
43
  import java.util.Calendar;
43
44
  import java.util.Date;
44
45
 
45
-
46
46
  /**
47
47
  * Created by simonracz on 10/07/2017.
48
48
  */
@@ -57,24 +57,29 @@ public class DetoxAction {
57
57
  }
58
58
 
59
59
  public static ViewAction multiClick(int times) {
60
- return actionWithAssertions(new GeneralClickAction(new DetoxMultiTap(times), GeneralLocation.CENTER, Press.FINGER, 0, 0));
60
+ return actionWithAssertions(new GeneralClickAction(new DetoxCustomTapper(times), GeneralLocation.CENTER, Press.FINGER, 0, 0));
61
61
  }
62
62
 
63
63
  public static ViewAction tapAtLocation(final int x, final int y) {
64
+ CoordinatesProvider coordinatesProvider = createCoordinatesProvider(x, y);
65
+ return actionWithAssertions(new RNClickAction(coordinatesProvider));
66
+ }
67
+
68
+ private static CoordinatesProvider createCoordinatesProvider(final int x, final int y) {
64
69
  final int px = DeviceDisplay.convertDpiToPx(x);
65
70
  final int py = DeviceDisplay.convertDpiToPx(y);
66
- CoordinatesProvider c = new CoordinatesProvider() {
67
- @Override
68
- public float[] calculateCoordinates(View view) {
69
- final int[] xy = new int[2];
70
- view.getLocationOnScreen(xy);
71
- final float fx = xy[0] + px;
72
- final float fy = xy[1] + py;
73
- return new float[]{fx, fy};
74
- }
75
- };
76
- return actionWithAssertions(new RNClickAction(c));
77
- }
71
+
72
+ return new CoordinatesProvider() {
73
+ @Override
74
+ public float[] calculateCoordinates(View view) {
75
+ final int[] xy = new int[2];
76
+ view.getLocationOnScreen(xy);
77
+ final float fx = xy[0] + px;
78
+ final float fy = xy[1] + py;
79
+ return new float[]{fx, fy};
80
+ }
81
+ };
82
+ };
78
83
 
79
84
  /**
80
85
  * Scrolls to the edge of the given scrollable view.
@@ -208,6 +213,25 @@ public class DetoxAction {
208
213
  ));
209
214
  }
210
215
 
216
+ public static ViewAction longPress() {
217
+ return longPress(null, null, null);
218
+ }
219
+
220
+ public static ViewAction longPress(Integer duration) {
221
+ return longPress(null, null, duration);
222
+ }
223
+
224
+ public static ViewAction longPress(Integer x, Integer y) {
225
+ return longPress(x, y, null);
226
+ }
227
+
228
+ public static ViewAction longPress(Integer x, Integer y, Integer duration) {
229
+ Long finalDuration = duration != null ? duration : DetoxViewConfigurations.getLongPressTimeout();
230
+ CoordinatesProvider coordinatesProvider = x == null || y == null ? null : createCoordinatesProvider(x, y);
231
+
232
+ return actionWithAssertions(new RNClickAction(coordinatesProvider, finalDuration));
233
+ }
234
+
211
235
  public static ViewAction takeViewScreenshot() {
212
236
  return new ViewActionWithResult<String>() {
213
237
  private final TakeViewScreenshotAction action = new TakeViewScreenshotAction();
@@ -21,21 +21,23 @@ public class RNClickAction implements ViewAction {
21
21
  private final GeneralClickAction clickAction;
22
22
 
23
23
  public RNClickAction() {
24
- clickAction = new GeneralClickAction(
25
- new DetoxSingleTap(),
26
- GeneralLocation.VISIBLE_CENTER,
27
- Press.FINGER,
28
- InputDevice.SOURCE_UNKNOWN,
29
- MotionEvent.BUTTON_PRIMARY);
24
+ this(null, null);
30
25
  }
31
26
 
32
27
  public RNClickAction(CoordinatesProvider coordinatesProvider) {
28
+ this(coordinatesProvider, null);
29
+ }
30
+
31
+ public RNClickAction(CoordinatesProvider coordinatesProvider, Long duration) {
32
+ coordinatesProvider = coordinatesProvider != null ? coordinatesProvider : GeneralLocation.VISIBLE_CENTER;
33
+
33
34
  clickAction = new GeneralClickAction(
34
- new DetoxSingleTap(),
35
- coordinatesProvider,
36
- Press.FINGER,
37
- InputDevice.SOURCE_UNKNOWN,
38
- MotionEvent.BUTTON_PRIMARY);
35
+ new DetoxSingleTap(duration),
36
+ coordinatesProvider,
37
+ Press.FINGER,
38
+ InputDevice.SOURCE_UNKNOWN,
39
+ MotionEvent.BUTTON_PRIMARY
40
+ );
39
41
  }
40
42
 
41
43
  @Override
@@ -8,7 +8,9 @@ import com.facebook.react.bridge.ReactMarkerConstants.*
8
8
  object ReactMarkersLogger : ReactMarker.MarkerListener {
9
9
 
10
10
  fun attach() {
11
- ReactMarker.addListener(this)
11
+ if (ReactNativeInfo.rnVersion().minor >= 71) {
12
+ ReactMarker.addListener(this)
13
+ }
12
14
  }
13
15
 
14
16
  override fun logMarker(marker: ReactMarkerConstants, p1: String?, p2: Int) {
@@ -29,7 +29,7 @@ import com.wix.detox.espresso.action.common.TapEvents
29
29
  *
30
30
  * This should be Espresso's default implementation IMO.
31
31
  */
32
- open class DetoxMultiTap
32
+ open class DetoxCustomTapper
33
33
  @JvmOverloads constructor(
34
34
  private val times: Int,
35
35
  private val interTapsDelayMs: Long = getDoubleTapMinTime(),
@@ -37,8 +37,9 @@ open class DetoxMultiTap
37
37
  private val longTapMinTimeMs: Long = getLongTapMinTime(),
38
38
  private val tapEvents: TapEvents = TapEvents(),
39
39
  private val uiControllerCallSpy: UiControllerSpy = UiControllerSpy.instance,
40
- private val log: DetoxLog = DetoxLog.instance)
41
- : Tapper {
40
+ private val log: DetoxLog = DetoxLog.instance,
41
+ private val duration: Long? = null
42
+ ) : Tapper {
42
43
 
43
44
  override fun sendTap(uiController: UiController?, coordinates: FloatArray?, precision: FloatArray?)
44
45
  = sendTap(uiController, coordinates, precision, 0, 0)
@@ -69,11 +70,12 @@ open class DetoxMultiTap
69
70
  var downTimestamp: Long? = null
70
71
 
71
72
  for (i in 1..times) {
72
- val tapEvents = tapEvents.createEventsSeq(coordinates, precision, downTimestamp)
73
+ val tapEvents = tapEvents.createEventsSeq(coordinates, precision, downTimestamp, duration)
73
74
  eventSequence.addAll(tapEvents)
74
75
 
75
76
  downTimestamp = tapEvents.last().eventTime + interTapsDelayMs
76
77
  }
78
+
77
79
  return eventSequence
78
80
  }
79
81
 
@@ -104,8 +106,8 @@ open class DetoxMultiTap
104
106
 
105
107
  private fun verifyTapEventTimes(upEvent: CallInfo, downEvent: CallInfo) {
106
108
  val delta: Long = (upEvent - downEvent)!!
107
- if (delta >= longTapMinTimeMs) {
109
+ if (delta >= longTapMinTimeMs && duration == null) {
108
110
  log.warn(LOG_TAG, "Tap handled too slowly, and turned into a long-tap!") // TODO conditionally turn into an error, based on a global strict-mode detox config
109
111
  }
110
112
  }
111
- }
113
+ }
@@ -1,3 +1,3 @@
1
1
  package com.wix.detox.espresso.action
2
2
 
3
- open class DetoxSingleTap : DetoxMultiTap(1)
3
+ class DetoxSingleTap(duration: Long? = null) : DetoxCustomTapper(1, duration = duration)
@@ -9,6 +9,16 @@ private const val LOG_TAG = "Detox-ViewConfig"
9
9
 
10
10
  object DetoxViewConfigurations {
11
11
 
12
+ /**
13
+ * Duration before a press turns into a long press.
14
+ * Due to `Tap.LONG`, factor 1.5 is needed, otherwise a long press is not safely detected.
15
+ *
16
+ * @see androidx.test.espresso.action.Tap.LONG
17
+ * @see android.test.TouchUtils.longClickView
18
+ */
19
+ @JvmStatic
20
+ fun getLongPressTimeout(): Long = (ViewConfiguration.getLongPressTimeout() * 1.5).toLong()
21
+
12
22
  fun getPostTapCoolDownTime() = ViewConfiguration.getDoubleTapTimeout().toLong()
13
23
 
14
24
  /**
@@ -15,16 +15,24 @@ import android.view.MotionEvent
15
15
  * Lastly, With the case of _that_ specific bug, we implicitly indirectly work around it with this approach, because we highly increase
16
16
  * the chance of allowing a frame to be drawn in between the _down_ and _up_ events.
17
17
  */
18
- private const val EVENTS_TIME_GAP_MS = 30
18
+ private const val EVENTS_TIME_GAP_MS = 30L
19
19
 
20
20
  class TapEvents(private val motionEvents: MotionEvents = MotionEvents()) {
21
21
  fun createEventsSeq(coordinates: FloatArray, precision: FloatArray)
22
- = createEventsSeq(coordinates, precision, null)
22
+ = createEventsSeq(coordinates, precision, null, null)
23
23
 
24
- fun createEventsSeq(coordinates: FloatArray, precision: FloatArray, downTimestamp: Long?): List<MotionEvent> {
24
+ fun createEventsSeq(
25
+ coordinates: FloatArray,
26
+ precision: FloatArray,
27
+ downTimestamp: Long?,
28
+ duration: Long?
29
+ ): List<MotionEvent> {
25
30
  val (x, y) = coordinates
26
31
  val downEvent = motionEvents.obtainDownEvent(x, y, precision, downTimestamp)
27
- val upEvent = motionEvents.obtainUpEvent(downEvent, downEvent.eventTime + EVENTS_TIME_GAP_MS, x, y)
32
+
33
+ val upEventDuration = duration ?: EVENTS_TIME_GAP_MS
34
+ val upEvent = motionEvents.obtainUpEvent(downEvent, downEvent.eventTime + upEventDuration, x, y)
35
+
28
36
  return arrayListOf(downEvent, upEvent)
29
37
  }
30
38
  }
@@ -20,7 +20,7 @@ abstract class DetoxScrollActionBase internal constructor(
20
20
  : ViewAction {
21
21
  override fun getConstraints(): Matcher<View> = allOf(isAssignableFrom(View::class.java), isDisplayed())
22
22
  override fun perform(uiController: UiController?, view: View?) =
23
- ScrollHelper.perform(uiController, view, direction, amountInDp, startOffsetPercentX, startOffsetPercentY)
23
+ ScrollHelper.perform(uiController, view, direction, amountInDp, startOffsetPercentX, startOffsetPercentY)
24
24
  }
25
25
 
26
26
  class DetoxScrollAction(@MotionDir direction: Int, amountInDp: Double, startOffsetPercentX: Float?, startOffsetPercentY: Float?)
@@ -30,6 +30,8 @@ class DetoxScrollAction(@MotionDir direction: Int, amountInDp: Double, startOffs
30
30
  override fun perform(uiController: UiController?, view: View?) {
31
31
  try {
32
32
  super.perform(uiController, view)
33
+ } catch (e: ScrollEdgeException) {
34
+ // Hit the edge
33
35
  } catch (e: Exception) {
34
36
  throw DetoxRuntimeException(e)
35
37
  }
@@ -1,7 +1,7 @@
1
1
  package com.wix.detox.espresso.scroll
2
2
 
3
3
  /**
4
- * Along with [FlinglessSwiper], this is based on from Espresso's implementation of Swiping
4
+ * Along with [LinearSwiper], this is based on from Espresso's implementation of Swiping
5
5
  * (i.e. in [androidx.test.espresso.action.Swipe] - typically dispatched via the
6
6
  * [androidx.test.espresso.action.GeneralSwipeAction] action class).
7
7
  *
@@ -29,7 +29,7 @@ import static com.wix.detox.espresso.scroll.ScrollProbes.getScrollableProbe;
29
29
  public class ScrollHelper {
30
30
  private static final String LOG_TAG = "DetoxScrollHelper";
31
31
 
32
- private static final int SCROLL_MOTIONS = 70;
32
+ private static final int SCROLL_MOTIONS = 40;
33
33
  private static final int MAX_FLING_WAITS = 3;
34
34
 
35
35
  private static final double DEFAULT_DEADZONE_PERCENT = 0.05;
@@ -95,7 +95,7 @@ public class ScrollHelper {
95
95
  }
96
96
 
97
97
  private static void doScroll(final Context context, final UiController uiController, int downX, int downY, int upX, int upY) {
98
- final DetoxSwiper swiper = new FlinglessSwiper(SCROLL_MOTIONS, uiController, ViewConfiguration.get(context));
98
+ final DetoxSwiper swiper = new LinearSwiper(uiController);
99
99
  final DetoxSwipe swipe = new DetoxSwipe(downX, downY, upX, upY, SCROLL_MOTIONS, swiper);
100
100
  swipe.perform();
101
101
  }
@@ -90,16 +90,28 @@ object TapEventsSpec: Spek({
90
90
  val precision = fancyPrecision()
91
91
  val downTimestamp = 10203040L
92
92
 
93
- uut().createEventsSeq(coordinates, precision, downTimestamp)
93
+ uut().createEventsSeq(coordinates, precision, downTimestamp, null)
94
94
 
95
95
  verifyDownEventObtainedWithDownTimestamp(coordinates, precision, downTimestamp)
96
96
  }
97
97
 
98
- it("should allow for down-time to be null") {
98
+ it("should allow for duration to be set") {
99
+ val duration = 1000L
100
+ val expectedUpEventTime = DEFAULT_EVENT_TIME + duration
99
101
  val coordinates = dontCareCoordinates()
100
102
  val precision = dontCarePrecision()
101
103
 
102
- uut().createEventsSeq(coordinates, precision, downTimestamp = null as Long?)
104
+ uut().createEventsSeq(coordinates, precision, null, duration)
105
+
106
+ verifyDownEventObtainedWithDownTimestamp(coordinates, precision, null)
107
+ verifyUpEventObtainedWithTimestamp(expectedUpEventTime)
108
+ }
109
+
110
+ it("should allow for down-time and duration to be null") {
111
+ val coordinates = dontCareCoordinates()
112
+ val precision = dontCarePrecision()
113
+
114
+ uut().createEventsSeq(coordinates, precision, null, null)
103
115
 
104
116
  verifyDownEventObtainedWithDownTimestamp(coordinates, precision, null)
105
117
  }
@@ -14,8 +14,8 @@ import org.spekframework.spek2.style.specification.describe
14
14
  import java.lang.NullPointerException
15
15
  import kotlin.test.assertFailsWith
16
16
 
17
- object DetoxMultiTapSpec: Spek({
18
- describe("Detox multi-tapper replacement for Espresso") {
17
+ object DetoxCustomTapperSpec: Spek({
18
+ describe("Detox custom-tapper replacement for Espresso") {
19
19
 
20
20
  val coolDownTimeMs = 111L
21
21
  val interTapsDelayMs = 667L
@@ -41,8 +41,10 @@ object DetoxMultiTapSpec: Spek({
41
41
  mock1stTapEventsSeq = arrayListOf(downEvent, upEvent)
42
42
  mock2ndTapEventsSeq = arrayListOf(mock(name = "mockSeq2Event1"), mock(name = "mockSeq2Event2"))
43
43
  tapEvents = mock {
44
- on { createEventsSeq(any(), any(), isNull()) }.doReturn(mock1stTapEventsSeq)
45
- on { createEventsSeq(any(), any(), any()) }.doReturn(mock2ndTapEventsSeq)
44
+ on { createEventsSeq(any(), any(), isNull(), isNull()) }.doReturn(mock1stTapEventsSeq)
45
+ on { createEventsSeq(any(), any(), isNull(), any()) }.doReturn(mock1stTapEventsSeq)
46
+ on { createEventsSeq(any(), any(), any(), isNull()) }.doReturn(mock2ndTapEventsSeq)
47
+ on { createEventsSeq(any(), any(), any(), any()) }.doReturn(mock2ndTapEventsSeq)
46
48
  }
47
49
 
48
50
  uiControllerCallSpy = mock() {
@@ -52,9 +54,10 @@ object DetoxMultiTapSpec: Spek({
52
54
  log = mock()
53
55
  }
54
56
 
55
- fun verify1stTapEventsSeqGenerated() = verify(tapEvents).createEventsSeq(coordinates, precision, null)
56
- fun verify2ndTapEventsSeqGenerated() = verify(tapEvents).createEventsSeq(eq(coordinates), eq(precision), any())
57
- fun verify2ndTapEventsGenerateWithTimestamp(downTimestamp: Long) = verify(tapEvents).createEventsSeq(any(), any(), eq(downTimestamp))
57
+ fun verify1stTapEventsSeqGenerated(duration: Long? = null) = verify(tapEvents).createEventsSeq(eq(coordinates), eq(precision), isNull(), eq(duration))
58
+ fun verify2ndTapEventsSeqGenerated() = verify(tapEvents).createEventsSeq(eq(coordinates), eq(precision), isNull(), isNull())
59
+ fun verify2ndTapEventsGenerateWithTimestamp(downTimestamp: Long) = verify(tapEvents).createEventsSeq(eq(coordinates), eq(precision), eq(downTimestamp), isNull())
60
+
58
61
  fun verifyAllTapEventsInjected() = verify(uiController).injectMotionEventSequence(arrayListOf(mock1stTapEventsSeq, mock2ndTapEventsSeq).flatten())
59
62
  fun verifyMainThreadSynced() = verify(uiController).loopMainThreadForAtLeast(eq(coolDownTimeMs))
60
63
  fun verifyMainThreadNeverSynced() = verify(uiController, never()).loopMainThreadForAtLeast(any())
@@ -64,17 +67,24 @@ object DetoxMultiTapSpec: Spek({
64
67
  fun givenInjectionError() = whenever(uiController.injectMotionEventSequence(any())).doThrow(RuntimeException("exceptionMock"))
65
68
 
66
69
  fun givenInjectionCallsHistory(injectionsHistory: List<CallInfo?>) =
67
- whenever(uiControllerCallSpy.eventInjectionsIterator()).thenReturn(injectionsHistory.iterator())
70
+ whenever(uiControllerCallSpy.eventInjectionsIterator()).thenReturn(injectionsHistory.iterator())
71
+
72
+ fun uut(times: Int, duration: Long? = null) =
73
+ DetoxCustomTapper(times, interTapsDelayMs, coolDownTimeMs, longTapMinTimeMs, tapEvents, uiControllerCallSpy, log, duration)
68
74
 
69
- fun uut(times: Int) = DetoxMultiTap(times, interTapsDelayMs, coolDownTimeMs, longTapMinTimeMs, tapEvents, uiControllerCallSpy, log)
70
- fun sendOneTap(uut: DetoxMultiTap = uut(1)) = uut.sendTap(uiController, coordinates, precision, -1, -1)
71
- fun sendTwoTaps(uut: DetoxMultiTap = uut(2)) = uut.sendTap(uiController, coordinates, precision, -1, -1)
75
+ fun sendOneTap(duration: Long? = null) = uut(1, duration).sendTap(uiController, coordinates, precision, -1, -1)
76
+ fun sendTwoTaps(uut: DetoxCustomTapper = uut(2)) = uut.sendTap(uiController, coordinates, precision, -1, -1)
72
77
 
73
78
  it("should generate a single-tap events sequence using tap-events helper") {
74
79
  sendOneTap()
75
80
  verify1stTapEventsSeqGenerated()
76
81
  }
77
82
 
83
+ it("should generate a single-tap events sequence with a custom duration") {
84
+ sendOneTap(1000L)
85
+ verify1stTapEventsSeqGenerated(1000L)
86
+ }
87
+
78
88
  it("should generate multiple sets of single-tap event sequences using tap-events helper") {
79
89
  sendTwoTaps()
80
90
  verify1stTapEventsSeqGenerated()