detox 20.12.0-smoke.0 → 20.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar → 20.12.0/detox-20.12.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar → 20.12.0/detox-20.12.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0.pom → 20.12.0/detox-20.12.0.pom} +1 -1
  17. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.12.0/detox-20.12.0.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/android/detox/build.gradle +1 -1
  29. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
  30. package/android/detox/src/full/java/com/wix/detox/espresso/EspressoDetox.java +6 -7
  31. package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +4 -4
  32. package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +43 -0
  33. package/android/detox/src/full/java/com/wix/detox/espresso/performer/SingleViewActionPerformer.kt +19 -0
  34. package/android/detox/src/full/java/com/wix/detox/espresso/performer/ViewActionPerformer.kt +24 -0
  35. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +5 -4
  36. package/android/detox/src/main/java/com/wix/detox/espresso/MultipleViewsAction.kt +4 -0
  37. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -1
  38. package/android/detox/src/main/java/com/wix/detox/espresso/ViewActionWithResult.kt +2 -1
  39. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +6 -5
  40. package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
  41. package/index.d.ts +4 -3
  42. package/local-cli/reset-lock-file.js +9 -5
  43. package/package.json +6 -6
  44. package/src/DetoxWorker.js +9 -5
  45. package/src/android/core/NativeElement.js +26 -29
  46. package/src/android/espressoapi/DetoxAssertion.js +16 -14
  47. package/src/android/espressoapi/EspressoDetox.js +9 -2
  48. package/src/android/interactions/native.js +2 -3
  49. package/src/artifacts/providers/index.js +3 -3
  50. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +17 -0
  51. package/src/devices/DeviceRegistry.js +176 -0
  52. package/src/devices/allocation/DeviceAllocator.js +15 -50
  53. package/src/devices/allocation/drivers/AllocationDriverBase.js +4 -10
  54. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +6 -7
  55. package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +13 -0
  56. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +26 -108
  57. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +72 -0
  58. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +43 -33
  59. package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
  60. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
  61. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +27 -87
  62. package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +16 -0
  63. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +65 -0
  64. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +28 -39
  65. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +40 -70
  66. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +7 -11
  67. package/src/devices/allocation/factories/android.js +35 -29
  68. package/src/devices/allocation/factories/ios.js +5 -7
  69. package/src/devices/common/drivers/DeviceAllocationHelper.js +20 -0
  70. package/src/devices/common/drivers/DeviceLauncher.js +19 -0
  71. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +5 -17
  72. package/src/devices/common/drivers/android/exec/ADB.js +0 -1
  73. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +25 -0
  74. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +38 -0
  75. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +14 -0
  76. package/src/devices/{allocation → common}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  77. package/src/devices/{allocation → common}/drivers/android/genycloud/services/dto/GenyInstance.js +1 -6
  78. package/src/devices/{allocation/drivers/android → common/drivers/android/tools}/FreeDeviceFinder.js +10 -11
  79. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +1 -1
  80. package/src/devices/cookies/AndroidDeviceCookie.js +0 -4
  81. package/src/devices/cookies/GenycloudEmulatorCookie.js +5 -3
  82. package/src/devices/cookies/IosSimulatorCookie.js +0 -4
  83. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +71 -0
  84. package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +18 -0
  85. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +2 -2
  86. package/src/devices/runtime/factories/android.js +1 -1
  87. package/src/devices/runtime/factories/ios.js +2 -3
  88. package/src/environmentFactory.js +11 -1
  89. package/src/ipc/IPCClient.js +1 -17
  90. package/src/ipc/IPCServer.js +1 -25
  91. package/src/realms/DetoxContext.js +0 -6
  92. package/src/realms/DetoxPrimaryContext.js +42 -42
  93. package/src/realms/DetoxSecondaryContext.js +0 -19
  94. package/src/realms/symbols.js +0 -4
  95. package/src/{devices/servicelocator → servicelocator}/android/emulatorServiceLocator.js +1 -1
  96. package/src/servicelocator/android/genycloudServiceLocator.js +21 -0
  97. package/src/servicelocator/android/index.js +25 -0
  98. package/src/servicelocator/ios.js +7 -0
  99. package/src/utils/environment.js +15 -8
  100. package/src/utils/errorUtils.js +2 -2
  101. package/src/{devices/validation → validation}/android/GenycloudEnvValidator.js +2 -2
  102. package/src/{devices/validation → validation}/factories/index.js +1 -1
  103. package/src/{devices/validation → validation}/ios/IosSimulatorEnvValidator.js +2 -2
  104. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.md5 +0 -1
  105. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha1 +0 -1
  106. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha256 +0 -1
  107. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha512 +0 -1
  108. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.md5 +0 -1
  109. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha1 +0 -1
  110. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha256 +0 -1
  111. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha512 +0 -1
  112. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar +0 -0
  113. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.md5 +0 -1
  114. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha1 +0 -1
  115. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha256 +0 -1
  116. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha512 +0 -1
  117. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.md5 +0 -1
  118. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha1 +0 -1
  119. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha256 +0 -1
  120. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha512 +0 -1
  121. package/src/devices/allocation/DeviceList.js +0 -44
  122. package/src/devices/allocation/DeviceRegistry.js +0 -186
  123. package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +0 -16
  124. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +0 -93
  125. package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -24
  126. package/src/devices/allocation/drivers/ios/SimulatorQuery.js +0 -24
  127. package/src/devices/servicelocator/android/genycloudServiceLocator.js +0 -17
  128. package/src/devices/servicelocator/android/index.js +0 -23
  129. package/src/utils/PIDService.js +0 -27
  130. /package/src/devices/{allocation → common}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
  131. /package/src/devices/{allocation → common}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
  132. /package/src/devices/{allocation → common}/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -0
  133. /package/src/{devices/validation → validation}/EnvironmentValidatorBase.js +0 -0
@@ -0,0 +1 @@
1
+ fd803ad3b1d79693779077e2d5a030be
@@ -0,0 +1 @@
1
+ 6e783294674107a7a02ffce8f5fc9bf5b5fa56de
@@ -0,0 +1 @@
1
+ 250dd66ec2b951c59dd18d382ff84a0e05e9210543d66965d1c3704a36a5f16f
@@ -0,0 +1 @@
1
+ b6b8f084acbebaa8057529fe74ce10a2a700ef882f863aecf01a6e263f76164deb3ace7c5aa49164f3345bc3c930d18ca37e704f8814194906f32641187aa0d3
@@ -0,0 +1 @@
1
+ 47c93868c2f09b970c68a3c21de6c2e8
@@ -0,0 +1 @@
1
+ 6513d86c59c32e3b5a0d41e86f55e01c15dc0b8a
@@ -0,0 +1 @@
1
+ dbf7d435856960f5a0440f74248d677c6b7bcec0d9100f1e0f941401bd05f554
@@ -0,0 +1 @@
1
+ 175323a595f1be240650f3d5109f0c7c099e93bdf1e9799b25f6ade82339aa42764dedbedefbfe6a9803cab1c0885f97dcd25ca77dd8840c9d5330bbbb66a9be
@@ -0,0 +1 @@
1
+ c90cc85230997f3663da1741d1eabc0e
@@ -0,0 +1 @@
1
+ 0e17ccf18dbb2e0295e72b77cae67275591d956a
@@ -0,0 +1 @@
1
+ 00528b5d136df63bc93f55c2f890a1ad69179f341663310b520227f6b7aad63b
@@ -0,0 +1 @@
1
+ 37984e2491685ede0325d74f460ad2a13dc55bd906124e0932fa09e29e2394a91cbbf691aa854848503113f04dfe148a483e616c736918f6e0077af6aa311a31
@@ -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.12.0-smoke.0</version>
6
+ <version>20.12.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
+ f936530422c3b067b14acf6882eb15c8
@@ -0,0 +1 @@
1
+ 2528825c4917ba8994b81030daef2f0a7a908227
@@ -0,0 +1 @@
1
+ a0a195aa8f7511f6ee3b1bacc22f29d444e3d3eaacb96bf902c3e06df9afef5d
@@ -0,0 +1 @@
1
+ 9702d3696a7170e3ac6cc0cdd15490cd1cd954903b602453a4ac53d336feda62822aef2796c83fd33552639f576a0234cb0052a76bd7ed2b2bc67a87df08544a
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.12.0-smoke.0</latest>
7
- <release>20.12.0-smoke.0</release>
6
+ <latest>20.12.0</latest>
7
+ <release>20.12.0</release>
8
8
  <versions>
9
- <version>20.12.0-smoke.0</version>
9
+ <version>20.12.0</version>
10
10
  </versions>
11
- <lastUpdated>20230905081618</lastUpdated>
11
+ <lastUpdated>20230912212516</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- c0ebd655b45d26da7f4503b42682e6ac
1
+ f9657c7ea977fa12455aefb694554e0b
@@ -1 +1 @@
1
- b28e7e113a3adf4f4ac956666bef4767712332c5
1
+ e237f10dcfb62432425cceaa085e7abbbccce171
@@ -1 +1 @@
1
- 428cdbf9560b42fa11a47e4ad09d61f067e46c0222b046489e8cfdb914d43d3e
1
+ 973055b62aa343c2551197a1f9b730cdad4fe64ff6aa327ac43e4de24aea047a
@@ -1 +1 @@
1
- c7042d22a9567df5b06587e91169041fb202a4881b61f76a2b8a3db7b31c571cd8a1b51e4a44fe54ac80499bc249e0b195f67854408cfa47f2388c2c2d0f76ca
1
+ 00e33c2cefd740754934b7635d42ff6933ff1b387d806b3503c08fc16955d49e0297b0f4875d3ccdf532b4409459692e2b367947164e6ac7a75db84259cb0fab
package/Detox-ios-src.tbz CHANGED
Binary file
package/Detox-ios.tbz CHANGED
Binary file
@@ -140,7 +140,7 @@ dependencies {
140
140
  // Unit-testing deps.
141
141
  dependencies {
142
142
  testImplementation "${_rnNativeArtifact}"
143
- testImplementation 'org.json:json:20140107'
143
+ testImplementation 'org.json:json:20230227'
144
144
 
145
145
  // https://github.com/spekframework/spek/issues/232#issuecomment-610732158
146
146
  testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
@@ -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) {
@@ -9,6 +9,7 @@ import android.widget.TextView
9
9
  import androidx.test.espresso.UiController
10
10
  import com.google.android.material.slider.Slider
11
11
  import com.wix.detox.espresso.ViewActionWithResult
12
+ import com.wix.detox.espresso.MultipleViewsAction
12
13
  import com.wix.detox.espresso.common.SliderHelper
13
14
  import com.wix.detox.reactnative.ui.getAccessibilityLabel
14
15
  import org.hamcrest.Matcher
@@ -17,26 +18,25 @@ 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
+ class GetAttributesAction() : ViewActionWithResult<JSONObject?>, MultipleViewsAction {
21
22
  private val commonAttributes = CommonAttributes()
22
23
  private val textViewAttributes = TextViewAttributes()
23
24
  private val checkBoxAttributes = CheckBoxAttributes()
24
25
  private val progressBarAttributes = ProgressBarAttributes()
25
26
  private val sliderAttributes = SliderAttributes()
26
- private var result: String = ""
27
+ private var result: JSONObject? = null
27
28
 
28
29
  override fun perform(uiController: UiController?, view: View?) {
29
30
  view!!
30
31
 
31
32
  val json = JSONObject()
32
-
33
33
  commonAttributes.get(json, view)
34
34
  textViewAttributes.get(json, view)
35
35
  checkBoxAttributes.get(json, view)
36
36
  progressBarAttributes.get(json, view)
37
37
  sliderAttributes.get(json, view)
38
38
 
39
- result = json.toString()
39
+ result = json
40
40
  }
41
41
 
42
42
  override fun getResult() = result
@@ -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
+ }
@@ -0,0 +1,24 @@
1
+ package com.wix.detox.espresso.performer
2
+
3
+ import com.wix.detox.espresso.MultipleViewsAction
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
+ interface ViewActionPerformer {
12
+ fun performOn(matcher: Matcher<View>): Any?
13
+
14
+ companion object {
15
+ @JvmStatic
16
+ fun forAction(action: ViewAction): ViewActionPerformer {
17
+ return if (action is MultipleViewsAction) {
18
+ MultipleViewsActionPerformer(action)
19
+ } else {
20
+ SingleViewActionPerformer(action)
21
+ }
22
+ }
23
+ }
24
+ }
@@ -92,9 +92,9 @@ public class Invocation {
92
92
  } else if (type.equals("boolean")) {
93
93
  argument = jsonArgument.optBoolean("value");
94
94
  } else if (type.equals("Invocation")) {
95
- argument = new Invocation(jsonArgument.optJSONObject("value"));
95
+ argument = new Invocation(jsonArgument.optJSONObject("value"));
96
96
  } else {
97
- throw new RuntimeException("Unhandled arg type" + type);
97
+ throw new RuntimeException("Unhandled arg type " + type);
98
98
  }
99
99
  }
100
100
  }
@@ -105,6 +105,8 @@ public class Invocation {
105
105
  }
106
106
 
107
107
  public void setArgs(Object[] args) {
108
+ JsonParser parser = new JsonParser();
109
+
108
110
  for (int i = 0; i < args.length; i++) {
109
111
  Object argument = args[i];
110
112
  if (argument instanceof HashMap && !((HashMap) argument).isEmpty()) {
@@ -125,10 +127,9 @@ public class Invocation {
125
127
  } else if (type.equals("boolean")) {
126
128
  argument = ((Boolean) value).booleanValue();
127
129
  } else if (type.equals("Invocation")) {
128
- JsonParser parser = new JsonParser();
129
130
  argument = parser.parse((String)value);
130
131
  } else {
131
- throw new RuntimeException("Unhandled arg type" + type);
132
+ throw new RuntimeException("Unhandled arg type " + type);
132
133
  }
133
134
 
134
135
  args[i] = argument;
@@ -0,0 +1,4 @@
1
+ package com.wix.detox.espresso
2
+
3
+ // Marker interface for actions that should be applied to all matching elements without ambiguity.
4
+ interface MultipleViewsAction
@@ -1,4 +1,3 @@
1
-
2
1
  package com.wix.detox.espresso
3
2
 
4
3
  import androidx.test.espresso.UiController
@@ -2,6 +2,7 @@ package com.wix.detox.espresso
2
2
 
3
3
  import androidx.test.espresso.ViewAction
4
4
 
5
- interface ViewActionWithResult<R: Any?>: ViewAction {
5
+ // Interface for actions that return a result.
6
+ interface ViewActionWithResult<R: Any?> : ViewAction {
6
7
  fun getResult(): R
7
8
  }
@@ -37,7 +37,7 @@ class GetAttributesActionTest {
37
37
 
38
38
  private fun perform(v: View = view): JSONObject {
39
39
  uut.perform(null, v)
40
- return JSONObject(uut.getResult())
40
+ return uut.getResult()!!
41
41
  }
42
42
 
43
43
  @Test
@@ -135,10 +135,10 @@ class GetAttributesActionTest {
135
135
  }
136
136
 
137
137
  val resultJson = perform()
138
- assertThat(resultJson.opt("alpha")).isEqualTo(0.42)
138
+ assertThat(resultJson.opt("alpha")).isEqualTo(0.42f)
139
139
  assertThat(resultJson.opt("width")).isEqualTo(123)
140
140
  assertThat(resultJson.opt("height")).isEqualTo(456)
141
- assertThat(resultJson.opt("elevation")).isEqualTo(0.314)
141
+ assertThat(resultJson.opt("elevation")).isEqualTo(0.314f)
142
142
  }
143
143
 
144
144
  @Test
@@ -208,7 +208,8 @@ class GetAttributesActionTest {
208
208
  }
209
209
 
210
210
  val resultJson = perform(slider)
211
- assertThat(resultJson.opt("value")).isEqualTo(0.42)
211
+ android.util.Log.i("TESTS", "should return material-Slider state through value attribute: "+ resultJson)
212
+ assertThat(resultJson.opt("value")).isEqualTo(0.42f)
212
213
  }
213
214
 
214
215
  @Test
@@ -221,7 +222,7 @@ class GetAttributesActionTest {
221
222
 
222
223
  val resultJson = perform(textView)
223
224
  assertThat(resultJson.opt("text")).isEqualTo("mock-text")
224
- assertThat(resultJson.opt("textSize")).isEqualTo(24)
225
+ assertThat(resultJson.opt("textSize")).isEqualTo(24f)
225
226
  assertThat(resultJson.opt("length")).isEqualTo(111)
226
227
  }
227
228
 
@@ -0,0 +1,37 @@
1
+ package com.wix.detox.espresso.performer
2
+
3
+ import org.spekframework.spek2.Spek
4
+ import org.spekframework.spek2.style.specification.describe
5
+ import androidx.test.espresso.ViewAction
6
+ import com.wix.detox.espresso.MultipleViewsAction
7
+ import org.hamcrest.Matcher
8
+ import org.mockito.Mockito.*
9
+ import org.mockito.kotlin.mock
10
+
11
+ object ViewActionPerformerSpec : Spek({
12
+
13
+ describe("ViewActionPerformer") {
14
+ context("forAction") {
15
+ context("given a regular ViewAction") {
16
+ val action = mock(ViewAction::class.java)
17
+
18
+ it("should return a SingleViewActionPerformer") {
19
+ val performer = ViewActionPerformer.forAction(action)
20
+ assert(performer is SingleViewActionPerformer)
21
+ }
22
+ }
23
+
24
+ context("given a MultipleViewsAction") {
25
+ val multipleViewsAction: ViewAction = mock(
26
+ ViewAction::class.java,
27
+ withSettings().extraInterfaces(MultipleViewsAction::class.java)
28
+ )
29
+
30
+ it("should return a MultipleViewsActionPerformer") {
31
+ val performer = ViewActionPerformer.forAction(multipleViewsAction)
32
+ assert(performer is MultipleViewsActionPerformer)
33
+ }
34
+ }
35
+ }
36
+ }
37
+ })
package/index.d.ts CHANGED
@@ -1430,8 +1430,9 @@ declare global {
1430
1430
  takeScreenshot(name: string): Promise<string>;
1431
1431
 
1432
1432
  /**
1433
- * Gets the native (OS-dependent) attributes of the element.
1434
- * For more information, see {@link https://wix.github.io/Detox/docs/api/actions-on-element/#getattributes}
1433
+ * Retrieves the OS-dependent attributes of an element.
1434
+ * If there are multiple matches, it returns an array of attributes for all matched elements.
1435
+ * For detailed information, refer to {@link https://wix.github.io/Detox/docs/api/actions-on-element/#getattributes}
1435
1436
  *
1436
1437
  * @example
1437
1438
  * test('Get the attributes for my text element', async () => {
@@ -1445,7 +1446,7 @@ declare global {
1445
1446
  * jestExpect(attributes.width).toHaveValue(100);
1446
1447
  * })
1447
1448
  */
1448
- getAttributes(): Promise<IosElementAttributes | AndroidElementAttributes | { elements: IosElementAttributes[]; }>;
1449
+ getAttributes(): Promise<IosElementAttributes | AndroidElementAttributes | { elements: IosElementAttributes[] } | { elements: AndroidElementAttributes[] } >;
1449
1450
  }
1450
1451
 
1451
1452
  interface WebExpect<R = Promise<void>> {
@@ -1,12 +1,16 @@
1
1
  const { log } = require('../internals');
2
- const DeviceRegistry = require('../src/devices/allocation/DeviceRegistry');
2
+ const DeviceRegistry = require('../src/devices/DeviceRegistry');
3
+ const { getDetoxLibraryRootPath } = require('../src/utils/environment');
4
+
3
5
 
4
6
  module.exports.command = 'reset-lock-file';
5
- module.exports.desc = 'Resets all Detox lock files. Useful when you need to clean up leftover locks from a crashed Detox instance.';
7
+ module.exports.desc = 'Resets all Detox lock files. Useful when you need to run multiple `detox test` commands in parallel with --keepLockFile.';
6
8
 
7
9
  module.exports.handler = async function resetLockFile() {
8
- const registry = new DeviceRegistry();
9
- await registry.reset();
10
+ await Promise.all([
11
+ DeviceRegistry.forIOS().reset(),
12
+ DeviceRegistry.forAndroid().reset(),
13
+ ]);
10
14
 
11
- log.info(`Cleaned lock file at: ${registry.lockFilePath}`);
15
+ log.info(`Cleaned lock files from: ${getDetoxLibraryRootPath()}`);
12
16
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "detox",
3
3
  "description": "E2E tests and automation for mobile",
4
- "version": "20.12.0-smoke.0",
4
+ "version": "20.12.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -196,15 +196,15 @@
196
196
  ],
197
197
  "coverageThreshold": {
198
198
  "global": {
199
- "statements": 50,
200
- "branches": 50,
201
- "functions": 50,
202
- "lines": 50
199
+ "statements": 100,
200
+ "branches": 100,
201
+ "functions": 100,
202
+ "lines": 100
203
203
  }
204
204
  }
205
205
  },
206
206
  "browserslist": [
207
207
  "node 14"
208
208
  ],
209
- "gitHead": "6a0b45ddbd1eaae9158e6e27f7d6b85b1411f553"
209
+ "gitHead": "8102c59b8bf62854f7767c68e35412eb981792d0"
210
210
  }