detox 20.40.2 → 20.41.1

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 (54) hide show
  1. package/Detox-android/com/wix/detox/{20.40.2/detox-20.40.2-sources.jar → 20.41.1/detox-20.41.1-sources.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1-sources.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1-sources.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1-sources.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1-sources.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.aar +0 -0
  7. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.aar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.aar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.aar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.aar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/{20.40.2/detox-20.40.2.pom → 20.41.1/detox-20.41.1.pom} +1 -1
  12. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.pom.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.pom.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.pom.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.41.1/detox-20.41.1.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-ios-framework.tbz +0 -0
  22. package/Detox-ios-src.tbz +0 -0
  23. package/Detox-ios-xcuitest.tbz +0 -0
  24. package/android/detox/src/full/java/com/wix/detox/DetoxMain.kt +5 -0
  25. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionHandlers.kt +13 -13
  26. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxFailureHandler.kt +47 -0
  27. package/android/detox/src/full/java/com/wix/detox/espresso/errors/DetoxAmbiguousViewMatcherException.kt +17 -0
  28. package/android/detox/src/full/java/com/wix/detox/espresso/errors/DetoxExceptionUtils.kt +12 -0
  29. package/android/detox/src/full/java/com/wix/detox/espresso/errors/DetoxExceptionWithHierarchy.kt +10 -0
  30. package/android/detox/src/full/java/com/wix/detox/espresso/errors/DetoxNoMatchingViewException.kt +17 -0
  31. package/android/detox/src/full/java/com/wix/detox/espresso/hierarchy/ViewHierarchyGenerator.kt +7 -0
  32. package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +2 -2
  33. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/ReactNativeIdlingResources.kt +1 -0
  34. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/animations/AnimatedModuleIdlingResource.kt +1 -1
  35. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/uimodule/fabric/FabricUIManagerIdlingResources.kt +2 -2
  36. package/android/detox/src/testFull/java/com/wix/detox/adapters/server/DetoxActionHandlersSpec.kt +14 -9
  37. package/android/detox/src/testFull/java/com/wix/detox/espresso/errors/DetoxExceptionUtilsTest.kt +56 -0
  38. package/package.json +10 -10
  39. package/src/client/Client.js +1 -1
  40. package/src/client/actions/SyncStatusSchema.json +6 -0
  41. package/src/client/actions/formatters/sync-resources/UIFormatter.js +2 -0
  42. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2-sources.jar.md5 +0 -1
  43. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2-sources.jar.sha1 +0 -1
  44. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2-sources.jar.sha256 +0 -1
  45. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2-sources.jar.sha512 +0 -1
  46. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.aar +0 -0
  47. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.aar.md5 +0 -1
  48. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.aar.sha1 +0 -1
  49. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.aar.sha256 +0 -1
  50. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.aar.sha512 +0 -1
  51. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.pom.md5 +0 -1
  52. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.pom.sha1 +0 -1
  53. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.pom.sha256 +0 -1
  54. package/Detox-android/com/wix/detox/20.40.2/detox-20.40.2.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ 97968da55f240e611120a4ba7e897e6d
@@ -0,0 +1 @@
1
+ b912e6c17ef3218c8354acd79131de14e0448939
@@ -0,0 +1 @@
1
+ 32dd60b47992976bdba3a16ca29aa41465fd55ca32b753eb199f7bf635da9e36
@@ -0,0 +1 @@
1
+ 28bb95f127648d30674af1094f453878aa38110a343a736a79ed30afbcb77666b09734bb8f6cc6023cb2dfac29ed8ed37c22d465360fcc53d6d01b11db5c9487
@@ -0,0 +1 @@
1
+ 4bb098d649a4fdfa8da731a13328f37c
@@ -0,0 +1 @@
1
+ 7eb7b72ea93111298c4bd1c7fc0dcf37af928f2b
@@ -0,0 +1 @@
1
+ b478899eb20e565464f25f111b670f8e4373a63ba61745ad6bb5107c30b9911e
@@ -0,0 +1 @@
1
+ 089dfef507028175839a71599ed64d6c938c59336a41a0fa59d5069b1782eb33ad6d4ba1b5e0efaff3ce7d5f13dfc07646a59105df0df04e9bb8b63094d269e1
@@ -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.40.2</version>
6
+ <version>20.41.1</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
+ 1218ce00d445ca0ca30d8bc2dd59805e
@@ -0,0 +1 @@
1
+ 20211dfcb93a60e9fcc3963f87a618b333c168cb
@@ -0,0 +1 @@
1
+ b6b4542f4a3a9bc525ebb3b4f60cf42a6f9dd1c436be47a6f8527fe3bb1c0a28
@@ -0,0 +1 @@
1
+ 7ec3b3de35caff931d161876b62b8a5ae528d5d3dbe1d66b1edec0dc828df666e866c33b8cb00a1c12f48c3a9476fd2db794bcae1cb9238b39dcb85519774198
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.40.2</latest>
7
- <release>20.40.2</release>
6
+ <latest>20.41.1</latest>
7
+ <release>20.41.1</release>
8
8
  <versions>
9
- <version>20.40.2</version>
9
+ <version>20.41.1</version>
10
10
  </versions>
11
- <lastUpdated>20250714113314</lastUpdated>
11
+ <lastUpdated>20250902150145</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- c8c68cc098d5ea979ebb5d232b745b3f
1
+ 26255dfef3d35603ef3cc58d847b134b
@@ -1 +1 @@
1
- 1a321c7835c033b9834bbac15e61ea6f78a36f49
1
+ f74b348fd5620867b74020889fc42e7645de6b87
@@ -1 +1 @@
1
- 95bde0b1e44cb7bc643535740ce36af75fab80a8f136e537f7691b081c70f2b3
1
+ 02ccfce690001b13bb22a389daa3f5be077cd63d45034bc9cca5783a35a520e2
@@ -1 +1 @@
1
- 232c04d61df93be67214a9c807e65ef80ae2972dc489d88a925473cfd54d9504521b326479a1b5d58d8b5f406226d24f84b699764854d72910b02d95385ffd67
1
+ fa3f21c0eef3aa60cc7231ce88e6323e2ba76b6fced9deb54cdbe5ec8d33c2c483fb09b4c49270dbf453178d197b68a469698a87886f84908f1c09dcc1893724
Binary file
package/Detox-ios-src.tbz CHANGED
Binary file
Binary file
@@ -5,6 +5,8 @@ import android.util.Log
5
5
  import com.wix.detox.adapters.server.*
6
6
  import com.wix.detox.common.DetoxLog
7
7
  import com.wix.detox.espresso.UiControllerSpy
8
+ import com.wix.detox.espresso.DetoxFailureHandler
9
+ import androidx.test.espresso.Espresso
8
10
  import com.wix.detox.instruments.DetoxInstrumentsManager
9
11
  import com.wix.detox.reactnative.ReactNativeExtension
10
12
  import com.wix.invoke.MethodInvocation
@@ -116,6 +118,9 @@ object DetoxMain {
116
118
 
117
119
  private fun initEspresso() {
118
120
  UiControllerSpy.attachThroughProxy()
121
+
122
+ // Set up custom failure handler that replaces human-readable hierarchy with XML format
123
+ Espresso.setFailureHandler(DetoxFailureHandler())
119
124
  }
120
125
 
121
126
  private fun initReactNative() {
@@ -4,6 +4,8 @@ import android.content.Context
4
4
  import android.util.Log
5
5
  import com.wix.detox.TestEngineFacade
6
6
  import com.wix.detox.common.extractRootCause
7
+ import com.wix.detox.espresso.errors.DetoxExceptionWithHierarchy
8
+ import com.wix.detox.espresso.hierarchy.ViewHierarchyGenerator
7
9
  import com.wix.detox.instruments.DetoxInstrumentsException
8
10
  import com.wix.detox.instruments.DetoxInstrumentsManager
9
11
  import com.wix.invoke.MethodInvocation
@@ -47,8 +49,6 @@ class InvokeActionHandler @JvmOverloads constructor(
47
49
  private val errorParse: (e: Throwable?) -> String = Log::getStackTraceString)
48
50
  : DetoxActionHandler {
49
51
 
50
- private val VIEW_HIERARCHY_TEXT = "View Hierarchy:"
51
-
52
52
  override fun handle(params: String, messageId: Long) {
53
53
  try {
54
54
  val invocationResult = methodInvocation.invoke(params)
@@ -63,17 +63,17 @@ class InvokeActionHandler @JvmOverloads constructor(
63
63
  }
64
64
  }
65
65
 
66
- private fun extractFailurePayload(e: InvocationTargetException): Map<String, Any?>
67
- = e.targetException.message?.let { message: String ->
68
- if (message.contains(VIEW_HIERARCHY_TEXT)) {
69
- val error = message.substringBefore(VIEW_HIERARCHY_TEXT).trim()
70
- val viewHierarchy = message.substringAfter(VIEW_HIERARCHY_TEXT).trim()
71
- mapOf<String, Any?>("details" to "${error}\n", "viewHierarchy" to viewHierarchy)
72
- } else {
73
- val error = extractRootCause(e.targetException)
74
- mapOf<String, Any?>("details" to error.message)
75
- }
76
- } ?: emptyMap()
66
+ private fun extractFailurePayload(e: InvocationTargetException): Map<String, Any?> {
67
+ val error = extractRootCause(e.targetException)
68
+ val errorMessage = error.message ?: "Unknown error"
69
+ val viewHierarchy = if (error is DetoxExceptionWithHierarchy) {
70
+ error.xmlHierarchy
71
+ } else {
72
+ null
73
+ }
74
+
75
+ return mapOf<String, Any?>("details" to "${errorMessage}\n", "viewHierarchy" to viewHierarchy)
76
+ }
77
77
  }
78
78
 
79
79
  class CleanupActionHandler(
@@ -0,0 +1,47 @@
1
+ package com.wix.detox.espresso
2
+
3
+ import android.view.View
4
+ import android.util.Log
5
+ import androidx.test.espresso.FailureHandler
6
+ import androidx.test.espresso.NoMatchingViewException
7
+ import androidx.test.espresso.AmbiguousViewMatcherException
8
+ import com.wix.detox.espresso.errors.DetoxNoMatchingViewException
9
+ import com.wix.detox.espresso.errors.DetoxAmbiguousViewMatcherException
10
+ import com.wix.detox.espresso.hierarchy.ViewHierarchyGenerator
11
+ import org.hamcrest.Matcher
12
+
13
+ private const val LOG_TAG = "DetoxFailureHandler"
14
+
15
+ /**
16
+ * Enhanced failure handler that wraps Espresso exceptions with cleaned error messages
17
+ * and provides XML hierarchy for debugging while eliminating verbose view hierarchy
18
+ * from exception messages.
19
+ */
20
+ class DetoxFailureHandler : FailureHandler {
21
+
22
+ override fun handle(error: Throwable, viewMatcher: Matcher<View>) {
23
+ when (error) {
24
+ is NoMatchingViewException -> {
25
+ val xmlHierarchy = getSafeViewHierarchy(error.rootView)
26
+ throw DetoxNoMatchingViewException(error, xmlHierarchy)
27
+ }
28
+ is AmbiguousViewMatcherException -> {
29
+ val xmlHierarchy = getSafeViewHierarchy(error.rootView)
30
+ throw DetoxAmbiguousViewMatcherException(error, xmlHierarchy)
31
+ }
32
+ else -> {
33
+ // For other exceptions, just re-throw as-is
34
+ throw error
35
+ }
36
+ }
37
+ }
38
+
39
+ private fun getSafeViewHierarchy(rootView: View): String {
40
+ return try {
41
+ ViewHierarchyGenerator.generateXml(rootView, shouldInjectTestIds = false)
42
+ } catch (hierarchyException: Exception) {
43
+ Log.w(LOG_TAG, "Failed to generate view hierarchy", hierarchyException)
44
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ViewHierarchy>\n <!-- Failed to generate hierarchy: ${hierarchyException.message} -->\n</ViewHierarchy>"
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,17 @@
1
+ package com.wix.detox.espresso.errors
2
+
3
+ import android.view.View
4
+ import androidx.test.espresso.AmbiguousViewMatcherException
5
+ import androidx.test.espresso.RootViewException
6
+
7
+ /**
8
+ * Detox wrapper for AmbiguousViewMatcherException that provides cleaned error messages
9
+ * and preserves the XML hierarchy for debugging.
10
+ */
11
+ class DetoxAmbiguousViewMatcherException(
12
+ private val originalException: AmbiguousViewMatcherException,
13
+ override val xmlHierarchy: String
14
+ ) : RuntimeException(DetoxExceptionUtils.cleanEspressoMessage(originalException.message)), RootViewException, DetoxExceptionWithHierarchy {
15
+
16
+ override fun getRootView(): View = originalException.rootView
17
+ }
@@ -0,0 +1,12 @@
1
+ package com.wix.detox.espresso.errors
2
+
3
+ /**
4
+ * Utility class for cleaning and processing Espresso exception messages.
5
+ */
6
+ object DetoxExceptionUtils {
7
+ fun cleanEspressoMessage(originalMessage: String?): String {
8
+ val message = originalMessage ?: ""
9
+ // Remove everything after "View Hierarchy:\n" (including it)
10
+ return message.substringBefore("View Hierarchy:\n").trim()
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ package com.wix.detox.espresso.errors
2
+
3
+ /**
4
+ * Interface for exceptions that provide XML view hierarchy for debugging.
5
+ * Exceptions implementing this interface will have their xmlHierarchy property
6
+ * extracted and used in error reporting.
7
+ */
8
+ interface DetoxExceptionWithHierarchy {
9
+ val xmlHierarchy: String
10
+ }
@@ -0,0 +1,17 @@
1
+ package com.wix.detox.espresso.errors
2
+
3
+ import android.view.View
4
+ import androidx.test.espresso.NoMatchingViewException
5
+ import androidx.test.espresso.RootViewException
6
+
7
+ /**
8
+ * Detox wrapper for NoMatchingViewException that provides cleaned error messages
9
+ * and preserves the XML hierarchy for debugging.
10
+ */
11
+ class DetoxNoMatchingViewException(
12
+ private val originalException: NoMatchingViewException,
13
+ override val xmlHierarchy: String
14
+ ) : RuntimeException(DetoxExceptionUtils.cleanEspressoMessage(originalException.message)), RootViewException, DetoxExceptionWithHierarchy {
15
+
16
+ override fun getRootView(): View = originalException.rootView
17
+ }
@@ -49,6 +49,13 @@ object ViewHierarchyGenerator {
49
49
  }
50
50
  }
51
51
 
52
+ @JvmStatic
53
+ fun generateXml(rootView: View, shouldInjectTestIds: Boolean): String {
54
+ return runBlocking {
55
+ generateXmlFromViews(listOf(rootView), shouldInjectTestIds)
56
+ }
57
+ }
58
+
52
59
  private suspend fun generateXmlFromViews(rootViews: List<View?>?, shouldInjectTestIds: Boolean): String {
53
60
  return StringWriter().use { writer ->
54
61
  val serializer = Xml.newSerializer().apply {
@@ -2,10 +2,10 @@ package com.wix.detox.espresso.performer
2
2
 
3
3
  import com.wix.detox.espresso.DetoxMatcher
4
4
  import com.wix.detox.espresso.ViewActionWithResult
5
+ import com.wix.detox.espresso.errors.DetoxNoMatchingViewException
5
6
 
6
7
  import android.view.View
7
8
  import androidx.test.espresso.Espresso.onView
8
- import androidx.test.espresso.NoMatchingViewException
9
9
  import androidx.test.espresso.ViewAction
10
10
  import org.hamcrest.Matcher
11
11
 
@@ -25,7 +25,7 @@ class MultipleViewsActionPerformer(
25
25
  (action as? ViewActionWithResult<*>)?.getResult()?.let { results.add(it) }
26
26
 
27
27
  index++
28
- } catch (e: NoMatchingViewException) {
28
+ } catch (e: DetoxNoMatchingViewException) {
29
29
  if (index == 0) {
30
30
  throw e
31
31
  }
@@ -115,6 +115,7 @@ class ReactNativeIdlingResources(
115
115
  loopers.clear()
116
116
  }
117
117
 
118
+ @OptIn(ExperimentalStdlibApi::class)
118
119
  private fun unregisterIdlingResources() {
119
120
  IdlingResourcesName.entries.forEach {
120
121
  removeIdlingResource(it)
@@ -27,7 +27,7 @@ class AnimatedModuleIdlingResource(private val reactContext: ReactContext) : Det
27
27
  override fun getName() = AnimatedModuleIdlingResource::class.java.name
28
28
 
29
29
  override fun getDebugName(): String {
30
- return "AnimatedModule"
30
+ return "ui"
31
31
  }
32
32
 
33
33
  override fun getBusyHint(): Map<String, Any> {
@@ -35,11 +35,11 @@ class FabricUIManagerIdlingResources(
35
35
  }
36
36
 
37
37
  override fun getDebugName(): String {
38
- return "Fabric UI"
38
+ return "ui"
39
39
  }
40
40
 
41
41
  override fun getBusyHint(): Map<String, Any> {
42
- return mapOf("mountItems" to getMountItemsSize(), "viewCommandMountItems" to getViewCommandMountItemsSize())
42
+ return mapOf("mount_items" to getMountItemsSize(), "view_command_mount_items" to getViewCommandMountItemsSize())
43
43
  }
44
44
 
45
45
  override fun getName() = FabricUIManagerIdlingResources::class.java.name
@@ -1,8 +1,11 @@
1
1
  package com.wix.detox.adapters.server
2
2
 
3
3
  import android.content.Context
4
+ import androidx.test.espresso.AmbiguousViewMatcherException
5
+ import androidx.test.espresso.NoMatchingViewException
4
6
  import com.wix.detox.TestEngineFacade
5
7
  import com.wix.detox.UTHelpers.yieldToOtherThreads
8
+ import com.wix.detox.espresso.errors.DetoxExceptionWithHierarchy
6
9
  import com.wix.detox.instruments.DetoxInstrumentsException
7
10
  import com.wix.detox.instruments.DetoxInstrumentsManager
8
11
  import com.wix.invoke.MethodInvocation
@@ -139,9 +142,11 @@ object DetoxActionHandlersSpec : Spek({
139
142
  eq(messageId))
140
143
  }
141
144
 
142
- it("should handle an InvocationTargetException and extract view hierarchy") {
143
- val targetException = Exception("before View Hierarchy: after")
144
- val exception = InvocationTargetException(targetException)
145
+ it("should handle DetoxExceptionWithHierarchy and extract xmlHierarchy") {
146
+ val detoxException = object : RuntimeException("Test exception"), DetoxExceptionWithHierarchy {
147
+ override val xmlHierarchy: String = "<ViewHierarchy><TestView/></ViewHierarchy>"
148
+ }
149
+ val exception = InvocationTargetException(detoxException)
145
150
  whenever(methodInvocationMock.invoke(isA<String>())).thenThrow(exception)
146
151
 
147
152
  uut().handle(params, messageId)
@@ -149,14 +154,14 @@ object DetoxActionHandlersSpec : Spek({
149
154
  verify(outboundServerAdapter).sendMessage(
150
155
  eq("testFailed"),
151
156
  argThat {
152
- this["details"] == "before\n" &&
153
- this["viewHierarchy"] == "after" &&
157
+ this["details"] == "Test exception\n" &&
158
+ this["viewHierarchy"] == "<ViewHierarchy><TestView/></ViewHierarchy>" &&
154
159
  size == 2
155
160
  },
156
161
  eq(messageId))
157
162
  }
158
163
 
159
- it("should handle a non-view-hierarchy InvocationTargetException") {
164
+ it("should handle non-Detox exceptions with null viewHierarchy") {
160
165
  val rootException = RuntimeException("root-exception-mock")
161
166
  val targetException = Exception("target-exception-mock", rootException)
162
167
  val exception = InvocationTargetException(targetException)
@@ -167,11 +172,11 @@ object DetoxActionHandlersSpec : Spek({
167
172
  verify(outboundServerAdapter).sendMessage(
168
173
  eq("testFailed"),
169
174
  argThat {
170
- this["details"] == "root-exception-mock" &&
171
- size == 1
175
+ this["details"] == "root-exception-mock\n" &&
176
+ this["viewHierarchy"] == null &&
177
+ size == 2
172
178
  },
173
179
  eq(messageId))
174
-
175
180
  }
176
181
  }
177
182
 
@@ -0,0 +1,56 @@
1
+ package com.wix.detox.espresso.errors
2
+
3
+ import org.assertj.core.api.Assertions
4
+ import org.junit.Test
5
+ import org.junit.runner.RunWith
6
+ import org.robolectric.RobolectricTestRunner
7
+
8
+ @RunWith(RobolectricTestRunner::class)
9
+ class DetoxExceptionUtilsTest {
10
+
11
+ @Test
12
+ fun `should clean espresso message by removing view hierarchy`() {
13
+ val originalMessage = """androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (an instance of android.widget.TextView and view.getText() with or without transformation to match: is "supercalifragilisticexpialidocious" and view has effective visibility <VISIBLE>)
14
+
15
+ View Hierarchy:
16
+ +>DecorView{id=-1, visibility=VISIBLE, width=1080, height=2400, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) sim={adjust=resize} ty=BASE_APPLICATION wanim=0x1030309
17
+ fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
18
+ pfl=NO_MOVE_ANIMATION EDGE_TO_EDGE_ENFORCED FORCE_DRAW_STATUS_BAR_BACKGROUND FIT_INSETS_CONTROLLED
19
+ bhv=DEFAULT
20
+ fitSides=
21
+ frameRateBoostOnTouch=true
22
+ dvrrWindowFrameRateHint=true}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"""
23
+
24
+ val cleanedMessage = DetoxExceptionUtils.cleanEspressoMessage(originalMessage)
25
+
26
+ val expectedMessage = """androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (an instance of android.widget.TextView and view.getText() with or without transformation to match: is "supercalifragilisticexpialidocious" and view has effective visibility <VISIBLE>)"""
27
+
28
+ Assertions.assertThat(cleanedMessage).isEqualTo(expectedMessage)
29
+ }
30
+
31
+ @Test
32
+ fun `should handle null message`() {
33
+ val cleanedMessage = DetoxExceptionUtils.cleanEspressoMessage(null)
34
+ Assertions.assertThat(cleanedMessage).isEqualTo("")
35
+ }
36
+
37
+ @Test
38
+ fun `should handle empty message`() {
39
+ val cleanedMessage = DetoxExceptionUtils.cleanEspressoMessage("")
40
+ Assertions.assertThat(cleanedMessage).isEqualTo("")
41
+ }
42
+
43
+ @Test
44
+ fun `should handle message without view hierarchy`() {
45
+ val message = "Simple error message without view hierarchy"
46
+ val cleanedMessage = DetoxExceptionUtils.cleanEspressoMessage(message)
47
+ Assertions.assertThat(cleanedMessage).isEqualTo(message)
48
+ }
49
+
50
+ @Test
51
+ fun `should trim whitespace`() {
52
+ val message = " Error message with whitespace "
53
+ val cleanedMessage = DetoxExceptionUtils.cleanEspressoMessage(message)
54
+ Assertions.assertThat(cleanedMessage).isEqualTo("Error message with whitespace")
55
+ }
56
+ }
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.40.2",
4
+ "version": "20.41.1",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -34,13 +34,13 @@
34
34
  "postinstall": "node scripts/postinstall.js"
35
35
  },
36
36
  "devDependencies": {
37
- "@react-native-community/cli": "15.0.1",
38
- "@react-native-community/cli-platform-android": "15.0.1",
39
- "@react-native-community/cli-platform-ios": "15.0.1",
40
- "@react-native/babel-preset": "0.78.2",
41
- "@react-native/eslint-config": "0.78.2",
42
- "@react-native/metro-config": "0.78.2",
43
- "@react-native/typescript-config": "0.78.2",
37
+ "@react-native-community/cli": "18.0.0",
38
+ "@react-native-community/cli-platform-android": "18.0.0",
39
+ "@react-native-community/cli-platform-ios": "18.0.0",
40
+ "@react-native/babel-preset": "0.79.5",
41
+ "@react-native/eslint-config": "0.79.5",
42
+ "@react-native/metro-config": "0.79.5",
43
+ "@react-native/typescript-config": "0.79.5",
44
44
  "@tsconfig/react-native": "^3.0.0",
45
45
  "@types/bunyan": "^1.8.8",
46
46
  "@types/child-process-promise": "^2.2.1",
@@ -62,7 +62,7 @@
62
62
  "jest-allure2-reporter": "^2.2.6",
63
63
  "metro-react-native-babel-preset": "0.76.8",
64
64
  "prettier": "^3.1.1",
65
- "react-native": "0.78.2",
65
+ "react-native": "0.79.5",
66
66
  "react-native-codegen": "^0.0.8",
67
67
  "typescript": "~5.3.3",
68
68
  "wtfnode": "^0.9.1"
@@ -120,5 +120,5 @@
120
120
  "browserslist": [
121
121
  "node 14"
122
122
  ],
123
- "gitHead": "4e6798ec5682611cc6b1c420c2561e2981d82d91"
123
+ "gitHead": "5f19fc2c3902a58d7ce2c7bb70ac5c4021dca6ea"
124
124
  }
@@ -274,7 +274,7 @@ class Client {
274
274
  status = await this.currentStatus();
275
275
  log.info({ event: 'APP_STATUS' }, status);
276
276
  } catch (_e) {
277
- log.debug({ event: 'APP_STATUS' }, 'Failed to execute the current status query.');
277
+ log.debug({ event: 'APP_STATUS' }, 'Failed to execute the current status query.', _e);
278
278
  this._slowInvocationStatusHandle = null;
279
279
  }
280
280
 
@@ -219,6 +219,12 @@
219
219
  "type":"number",
220
220
  "minimum":1
221
221
  },
222
+ "mount_items":{
223
+ "type":"number"
224
+ },
225
+ "view_command_mount_items":{
226
+ "type":"number"
227
+ },
222
228
  "reason":{
223
229
  "type":"string"
224
230
  }
@@ -10,6 +10,8 @@ const propertyToDescriptionMapping = {
10
10
  'view_controller_will_disappear_count': `View controllers will disappear`,
11
11
  'view_needs_display_count': `View needs display`,
12
12
  'view_needs_layout_count': `View needs layout`,
13
+ 'mount_items': `Mount items pending`,
14
+ 'view_command_mount_items': `View command mount items pending`,
13
15
  'reason': `Reason`
14
16
  };
15
17
 
@@ -1 +0,0 @@
1
- cda086eff253bc511cfdbdbf813e3fc7
@@ -1 +0,0 @@
1
- 3aa9496fcf17c82fb56bdb6837cd70d2599069d4
@@ -1 +0,0 @@
1
- 1e4238e611bb9e23eb514288d44a3008ca2fe62e728f97d171415bd2b821fa59
@@ -1 +0,0 @@
1
- 20e0596b7f36dc247d54453883b3222f5914a9d84984372a31a95c585549f25f2c06648758246b1d841f8071f9a9a6d6599d3df47197e51295e30731a7670037
@@ -1 +0,0 @@
1
- fa7ccdf50c24a95bab851dd96a3b450f
@@ -1 +0,0 @@
1
- d39448a7f0587d381996e0e7f36f8d22710934ce
@@ -1 +0,0 @@
1
- f99396bd6afb30ec76ddde2ccaa5bedfcabf6615d5fb084855a8b09b74daeabf
@@ -1 +0,0 @@
1
- 67391f029cd5a68db7c0ddda1c965234e6af91efc9087a98af95c76067a004c80a24da755be52fa3843422917015509ab6d5c61ea522e0b37e310f11cf7902b9
@@ -1 +0,0 @@
1
- e1d9ee64c2de9b98c9c111b3fa696b1b
@@ -1 +0,0 @@
1
- 5115014d32913b8f02d21d5a95eceaf96cc395eb
@@ -1 +0,0 @@
1
- 96c19d1412a02f323ae2249d5415b9222b2cb5e539f9efd4ec971e55fddf5305
@@ -1 +0,0 @@
1
- 29e3a5bd9423e937788003192fcdb06392ad4acf036e01ddbcb117e8174f5c597b52ae84132b1ff3301b19933cbfb2efbdd83e944ff8690709faa215677cf98d