detox 20.0.6-breaking.new-global-lifecycle.0 → 20.0.7-prerelease.0
Sign up to get free protection for your applications and to get access to all the features.
- package/Detox-android/com/wix/detox/{20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-sources.jar → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.pom → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom} +1 -1
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.sha512 +1 -0
- package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
- package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
- package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
- package/Detox-ios-src.tbz +0 -0
- package/Detox-ios.tbz +0 -0
- package/android/detox/proguard-rules-app.pro +4 -0
- package/android/detox/src/full/java/com/wix/detox/DetoxCrashHandler.kt +1 -1
- package/android/detox/src/full/java/com/wix/detox/LaunchArgs.java +9 -0
- package/android/detox/src/full/java/com/wix/detox/TestEngineFacade.kt +1 -1
- package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +15 -2
- package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeIdlingResources.kt +43 -38
- package/index.d.ts +10 -1
- package/package.json +2 -2
- package/runners/jest/testEnvironment/index.js +3 -2
- package/src/DetoxWorker.js +0 -6
- package/src/android/core/NativeElement.js +56 -20
- package/src/android/core/NativeExpect.js +28 -9
- package/src/android/interactions/native.js +24 -18
- package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
- package/src/client/Client.js +18 -1
- package/src/devices/common/drivers/android/tools/MonitoredInstrumentation.js +1 -1
- package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +3 -1
- package/src/devices/runtime/RuntimeDevice.js +2 -4
- package/src/devices/runtime/drivers/android/AndroidDriver.js +9 -1
- package/src/ios/expectTwo.js +152 -67
- package/src/logger/DetoxLogger.js +5 -1
- package/src/logger/utils/tracerLegacy.js +24 -1
- package/src/utils/errorUtils.js +4 -3
- package/src/utils/invocationTraceDescriptions.js +43 -0
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.0.6-breaking.new-global-lifecycle.0/detox-20.0.6-breaking.new-global-lifecycle.0.pom.sha512 +0 -1
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.md5
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
effab7a47e7869043e38424a2a1320ee
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha1
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
6ee9bcfa6e27561a20785f38d6978a16091d3da2
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha256
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
06ad5ed2c2c02a65f50c2913c88d9d83361b43decd36f3094ebbe088bbb5f784
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha512
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
4eaa276ed4517115f488a2fd76b24df233eb630eacf10544a90d7ef57ab0bf827d7495c9b0f39fd79edf7568bbde0b693d8bec308257bc1f0804a7dc6a32161f
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.md5
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
61e4258cf4c8c851cfafb2103a2d3b5e
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha1
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
f4fe7c3a998cef8964ff7f5af05eb529b38e09ee
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha256
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
114b949bbbf5f8fe5f6f355f5f629edb38e08e2221b6303e34a638c7bb824765
|
package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha512
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
c77832e978a4e102716c7fd6fa70d04645e02c8a377bdf09cfa482a8f70a514c5d35d7dd4f0c10b5dcd690817a3fb740f2a7914fc905a22489522e7363f9f44d
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
90f9a8b95a3f10adc93442d4f4684092
|
@@ -0,0 +1 @@
|
|
1
|
+
f03ce7143af53f09f8734c8ee3eb5a532f8143fa
|
@@ -0,0 +1 @@
|
|
1
|
+
742ad662c67c18780e0844567205b1d02772f160b1876154cbe485bf8048c461
|
@@ -0,0 +1 @@
|
|
1
|
+
dfd697ec8d6f5ee8296379bbbf3f5b487ad70a729a658c6118b2e4923c10959bdd56a30959eb48afa1cf0bfe210ba8a500423d6b9f3993c2570505d59288c0de
|
@@ -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.0.
|
6
|
+
<version>20.0.7-prerelease.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
|
+
7bf66c5ea2c958c30ac7565193ba4bc8
|
@@ -0,0 +1 @@
|
|
1
|
+
2485b54c1a62e1557d76ebc51a1741ccc4f10304
|
@@ -0,0 +1 @@
|
|
1
|
+
d133d5b090110c223f578f117b344a1bb1e86c3df2d55f50dfd00f1b17498254
|
@@ -0,0 +1 @@
|
|
1
|
+
11a29cc20eb22ce2133475e187c0941b7d32bff186857ddceb2ee88f3f3b1d46e32eb0cbed032598f57933cca7b9ed8d36008d9c8b882dc202afdd20d9fe5def
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<groupId>com.wix</groupId>
|
4
4
|
<artifactId>detox</artifactId>
|
5
5
|
<versioning>
|
6
|
-
<latest>20.0.
|
7
|
-
<release>20.0.
|
6
|
+
<latest>20.0.7-prerelease.0</latest>
|
7
|
+
<release>20.0.7-prerelease.0</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.0.
|
9
|
+
<version>20.0.7-prerelease.0</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20220906143110</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
443209a3d276fc780cececc129d8e70b
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
283f03aa8235477f8b3070d4cfa36018d5a7fe7f
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
40762b77b08b8369c14f0f11ecf0832d7fd56ecaa618b1a0a62c3c5d16938ed9
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
5b3fceef49c72fa0bd12736858bf0e6f16cefc317c648ff83525d2fdc4b7831cce101c206d3640ba7a79edc432b90d481f279cba5285f7c36ce1f613caf163f6
|
package/Detox-ios-src.tbz
CHANGED
Binary file
|
package/Detox-ios.tbz
CHANGED
Binary file
|
@@ -6,6 +6,10 @@
|
|
6
6
|
-keep class com.facebook.react.ReactNativeHost { *; }
|
7
7
|
-keep class com.facebook.react.ReactInstanceManager { *; }
|
8
8
|
-keep class com.facebook.react.ReactInstanceManager** { *; }
|
9
|
+
-keep class com.facebook.react.ReactInstanceEventListener { *; }
|
10
|
+
|
11
|
+
-keep class com.facebook.react.views.slider.ReactSlider { *; }
|
12
|
+
-keep class com.reactnativecommunity.slider.ReactSlider { *; }
|
9
13
|
-keep class com.reactnativecommunity.asyncstorage.** { *; }
|
10
14
|
|
11
15
|
-keep class kotlin.jvm.** { *; }
|
@@ -6,7 +6,7 @@ import com.wix.detox.adapters.server.OutboundServerAdapter
|
|
6
6
|
class DetoxCrashHandler(private val outboundServerAdapter: OutboundServerAdapter) {
|
7
7
|
fun attach() {
|
8
8
|
Thread.setDefaultUncaughtExceptionHandler { thread, exception ->
|
9
|
-
Log.e(LOG_TAG, "Crash detected!!! thread=${thread.name} (${thread.id})")
|
9
|
+
Log.e(LOG_TAG, "Crash detected!!! thread=${thread.name} (${thread.id})", exception)
|
10
10
|
|
11
11
|
val crashInfo = mapOf("errorDetails" to "@Thread ${thread.name}(${thread.id}):\n${Log.getStackTraceString(exception)}\nCheck device logs for full details!")
|
12
12
|
outboundServerAdapter.sendMessage(ACTION_NAME, crashInfo, MESSAGE_ID)
|
@@ -14,6 +14,7 @@ public class LaunchArgs {
|
|
14
14
|
private static final String DETOX_NOTIFICATION_PATH_ARG = "detoxUserNotificationDataURL";
|
15
15
|
private static final String DETOX_BLACKLIST_URLS_ARG = "detoxURLBlacklistRegex";
|
16
16
|
private static final String DETOX_URL_OVERRIDE_ARG = "detoxURLOverride";
|
17
|
+
private static final String DETOX_ENABLE_SYNCHRONIZATION = "detoxEnableSynchronization";
|
17
18
|
private static final List<String> RESERVED_INSTRUMENTATION_ARGS = Arrays.asList("class", "package", "func", "unit", "size", "perf", "debug", "log", "emma", "coverageFile");
|
18
19
|
|
19
20
|
public boolean hasNotificationPath() {
|
@@ -36,6 +37,14 @@ public class LaunchArgs {
|
|
36
37
|
return InstrumentationRegistry.getArguments().containsKey(DETOX_BLACKLIST_URLS_ARG);
|
37
38
|
}
|
38
39
|
|
40
|
+
public String getEnableSynchronization() {
|
41
|
+
return InstrumentationRegistry.getArguments().getString(DETOX_ENABLE_SYNCHRONIZATION);
|
42
|
+
}
|
43
|
+
|
44
|
+
public boolean hasEnableSynchronization() {
|
45
|
+
return InstrumentationRegistry.getArguments().containsKey(DETOX_ENABLE_SYNCHRONIZATION);
|
46
|
+
}
|
47
|
+
|
39
48
|
public String getUrlOverride() {
|
40
49
|
return InstrumentationRegistry.getArguments().getString(DETOX_URL_OVERRIDE_ARG);
|
41
50
|
}
|
@@ -10,7 +10,7 @@ import com.wix.detox.reactnative.ReactNativeExtension
|
|
10
10
|
|
11
11
|
class TestEngineFacade {
|
12
12
|
fun awaitIdle(): Unit? = Espresso.onIdle() {
|
13
|
-
Log.i(LOG_TAG, "Wait is over:
|
13
|
+
Log.i(LOG_TAG, "Wait is over: App is now idle!")
|
14
14
|
null
|
15
15
|
}
|
16
16
|
fun syncIdle() = UiAutomatorHelper.espressoSync() // TODO Check whether this can be replaced with #awaitIdle()
|
@@ -39,7 +39,7 @@ object ReactNativeExtension {
|
|
39
39
|
reloadReactNativeInBackground(it)
|
40
40
|
val reactContext = awaitNewReactNativeContext(it, previousReactContext)
|
41
41
|
|
42
|
-
|
42
|
+
enableOrDisableSynchronization(reactContext, networkSyncEnabled)
|
43
43
|
hackRN50OrHigherWaitForReady()
|
44
44
|
}
|
45
45
|
}
|
@@ -58,7 +58,7 @@ object ReactNativeExtension {
|
|
58
58
|
(applicationContext as ReactApplication).let {
|
59
59
|
val reactContext = awaitNewReactNativeContext(it, null)
|
60
60
|
|
61
|
-
|
61
|
+
enableOrDisableSynchronization(reactContext)
|
62
62
|
hackRN50OrHigherWaitForReady()
|
63
63
|
}
|
64
64
|
}
|
@@ -124,6 +124,19 @@ object ReactNativeExtension {
|
|
124
124
|
return rnLoadingMonitor.getNewContext()!!
|
125
125
|
}
|
126
126
|
|
127
|
+
private fun enableOrDisableSynchronization(reactContext: ReactContext, networkSyncEnabled: Boolean = true) {
|
128
|
+
if (shouldDisableSynchronization()) {
|
129
|
+
clearAllSynchronization()
|
130
|
+
} else {
|
131
|
+
setupIdlingResources(reactContext, networkSyncEnabled)
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
private fun shouldDisableSynchronization(): Boolean {
|
136
|
+
val launchArgs = LaunchArgs()
|
137
|
+
return launchArgs.hasEnableSynchronization() && launchArgs.enableSynchronization.equals("0")
|
138
|
+
}
|
139
|
+
|
127
140
|
private fun setupIdlingResources(reactContext: ReactContext, networkSyncEnabled: Boolean = true) {
|
128
141
|
val launchArgs = LaunchArgs()
|
129
142
|
|
@@ -2,6 +2,7 @@ package com.wix.detox.reactnative
|
|
2
2
|
|
3
3
|
import android.os.Looper
|
4
4
|
import android.util.Log
|
5
|
+
import androidx.test.espresso.Espresso
|
5
6
|
import androidx.test.espresso.IdlingRegistry
|
6
7
|
import androidx.test.espresso.base.IdlingResourceRegistry
|
7
8
|
import com.facebook.react.bridge.ReactContext
|
@@ -12,7 +13,6 @@ import com.wix.detox.reactnative.idlingresources.timers.getInterrogationStrategy
|
|
12
13
|
import com.wix.detox.reactnative.idlingresources.uimodule.UIModuleIdlingResource
|
13
14
|
import org.joor.Reflect
|
14
15
|
import org.joor.ReflectException
|
15
|
-
import java.util.Set
|
16
16
|
|
17
17
|
private const val LOG_TAG = "DetoxRNIdleRes"
|
18
18
|
|
@@ -46,15 +46,11 @@ private class MQThreadReflected(private val queue: Any?, private val queueName:
|
|
46
46
|
}
|
47
47
|
|
48
48
|
class ReactNativeIdlingResources constructor(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
{
|
55
|
-
|
49
|
+
private val reactContext: ReactContext,
|
50
|
+
private var launchArgs: LaunchArgs,
|
51
|
+
internal var networkSyncEnabled: Boolean = true
|
52
|
+
) {
|
56
53
|
companion object {
|
57
|
-
private const val FIELD_UI_BG_MSG_QUEUE = "mUiBackgroundMessageQueueThread"
|
58
54
|
private const val FIELD_NATIVE_MODULES_MSG_QUEUE = "mNativeModulesMessageQueueThread"
|
59
55
|
private const val FIELD_JS_MSG_QUEUE = "mJSMessageQueueThread"
|
60
56
|
}
|
@@ -69,17 +65,11 @@ class ReactNativeIdlingResources constructor(
|
|
69
65
|
|
70
66
|
fun registerAll() {
|
71
67
|
Log.i(LOG_TAG, "Setting up Espresso Idling Resources for React Native")
|
72
|
-
|
73
68
|
unregisterAll()
|
74
69
|
|
75
|
-
|
76
|
-
val blacklistUrls = launchArgs.getURLBlacklist()
|
77
|
-
setBlacklistUrls(blacklistUrls)
|
78
|
-
}
|
79
|
-
|
70
|
+
setupUrlBlacklist()
|
80
71
|
setupMQThreadsInterrogators()
|
81
72
|
syncIdlingResources()
|
82
|
-
|
83
73
|
setupCustomRNIdlingResources()
|
84
74
|
syncIdlingResources()
|
85
75
|
}
|
@@ -108,28 +98,42 @@ class ReactNativeIdlingResources constructor(
|
|
108
98
|
networkIdlingResource?.resume()
|
109
99
|
}
|
110
100
|
}
|
101
|
+
|
111
102
|
fun pauseRNTimersIdlingResource() = timersIdlingResource?.pause()
|
112
103
|
fun resumeRNTimersIdlingResource() = timersIdlingResource?.resume()
|
113
104
|
fun pauseUIIdlingResource() = uiModuleIdlingResource?.pause()
|
114
105
|
fun resumeUIIdlingResource() = uiModuleIdlingResource?.resume()
|
115
|
-
|
116
|
-
fun
|
106
|
+
|
107
|
+
fun setBlacklistUrls(urlList: String) {
|
108
|
+
setIldingResourceBlacklist(urlList)
|
109
|
+
}
|
110
|
+
|
111
|
+
private fun setIldingResourceBlacklist(urlList: String) {
|
112
|
+
val urlArray = toFormattedUrlArray(urlList)
|
113
|
+
NetworkIdlingResource.setURLBlacklist(urlArray)
|
114
|
+
}
|
117
115
|
|
118
116
|
private fun setupMQThreadsInterrogators() {
|
119
117
|
if (IdlingRegistry.getInstance().loopers.isEmpty()) {
|
120
118
|
val mqThreadsReflector = MQThreadsReflector(reactContext)
|
121
|
-
// val mqUIBackground = mqThreadsReflector.getQueue(FIELD_UI_BG_MSG_QUEUE)?.getLooper() TODO
|
122
119
|
val mqJS = mqThreadsReflector.getQueue(FIELD_JS_MSG_QUEUE)?.getLooper()
|
123
|
-
val mqNativeModules =
|
120
|
+
val mqNativeModules =
|
121
|
+
mqThreadsReflector.getQueue(FIELD_NATIVE_MODULES_MSG_QUEUE)?.getLooper()
|
124
122
|
|
125
123
|
IdlingRegistry.getInstance().apply {
|
126
|
-
// registerLooperAsIdlingResource(mqUIBackground)
|
127
124
|
registerLooperAsIdlingResource(mqJS)
|
128
125
|
registerLooperAsIdlingResource(mqNativeModules)
|
129
126
|
}
|
130
127
|
}
|
131
128
|
}
|
132
129
|
|
130
|
+
private fun setupUrlBlacklist() {
|
131
|
+
if (launchArgs.hasURLBlacklist()) {
|
132
|
+
val blacklistUrls = launchArgs.urlBlacklist
|
133
|
+
setIldingResourceBlacklist(blacklistUrls)
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
133
137
|
private fun setupCustomRNIdlingResources() {
|
134
138
|
rnBridgeIdlingResource = BridgeIdlingResource(reactContext)
|
135
139
|
timersIdlingResource = TimersIdlingResource(getInterrogationStrategy(reactContext)!!)
|
@@ -151,13 +155,16 @@ class ReactNativeIdlingResources constructor(
|
|
151
155
|
|
152
156
|
private fun syncIdlingResources() {
|
153
157
|
IdlingRegistry.getInstance().apply {
|
154
|
-
val irr: IdlingResourceRegistry =
|
158
|
+
val irr: IdlingResourceRegistry =
|
159
|
+
Reflect.on(Espresso::class.java).field("baseRegistry").get()
|
155
160
|
irr.sync(this.resources, this.loopers)
|
156
161
|
}
|
157
162
|
}
|
158
163
|
|
159
164
|
private fun unregisterMQThreadsInterrogators() {
|
160
|
-
|
165
|
+
val idlingResourceInstance = IdlingRegistry.getInstance()
|
166
|
+
val loopersField = Reflect.on(idlingResourceInstance).field("loopers")
|
167
|
+
loopersField.get<MutableSet<Any>>().clear()
|
161
168
|
}
|
162
169
|
|
163
170
|
private fun unregisterCustomRNIdlingResources() {
|
@@ -166,7 +173,8 @@ class ReactNativeIdlingResources constructor(
|
|
166
173
|
timersIdlingResource,
|
167
174
|
rnBridgeIdlingResource,
|
168
175
|
uiModuleIdlingResource,
|
169
|
-
animIdlingResource
|
176
|
+
animIdlingResource
|
177
|
+
)
|
170
178
|
rnBridgeIdlingResource?.onDetach()
|
171
179
|
|
172
180
|
removeNetworkIdlingResource()
|
@@ -174,13 +182,15 @@ class ReactNativeIdlingResources constructor(
|
|
174
182
|
}
|
175
183
|
|
176
184
|
private fun setupAsyncStorageIdlingResource() {
|
177
|
-
asyncStorageIdlingResource =
|
178
|
-
|
179
|
-
|
185
|
+
asyncStorageIdlingResource =
|
186
|
+
AsyncStorageIdlingResource.createIfNeeded(reactContext, false)?.also {
|
187
|
+
IdlingRegistry.getInstance().register(it)
|
188
|
+
}
|
180
189
|
|
181
|
-
legacyAsyncStorageIdlingResource =
|
182
|
-
|
183
|
-
|
190
|
+
legacyAsyncStorageIdlingResource =
|
191
|
+
AsyncStorageIdlingResource.createIfNeeded(reactContext, true)?.also {
|
192
|
+
IdlingRegistry.getInstance().register(it)
|
193
|
+
}
|
184
194
|
}
|
185
195
|
|
186
196
|
private fun removeAsyncStorageIdlingResource() {
|
@@ -212,13 +222,8 @@ class ReactNativeIdlingResources constructor(
|
|
212
222
|
|
213
223
|
private fun toFormattedUrlArray(urlList: String): List<String> {
|
214
224
|
var formattedUrls = urlList
|
215
|
-
formattedUrls = formattedUrls.replace(Regex("""[()"]"""), "")
|
216
|
-
formattedUrls = formattedUrls.trim()
|
217
|
-
return formattedUrls.split(',')
|
218
|
-
}
|
219
|
-
|
220
|
-
fun setBlacklistUrls(urlList: String) {
|
221
|
-
val urlArray = toFormattedUrlArray(urlList)
|
222
|
-
NetworkIdlingResource.setURLBlacklist(urlArray);
|
225
|
+
formattedUrls = formattedUrls.replace(Regex("""[()"]"""), "")
|
226
|
+
formattedUrls = formattedUrls.trim()
|
227
|
+
return formattedUrls.split(',')
|
223
228
|
}
|
224
229
|
}
|
package/index.d.ts
CHANGED
@@ -353,12 +353,21 @@ declare global {
|
|
353
353
|
readonly startSection: (name: string) => void;
|
354
354
|
/** @deprecated */
|
355
355
|
readonly endSection: (name: string) => void;
|
356
|
+
/** @private */
|
357
|
+
readonly invocationCall: (...args: unknown[]) => unknown;
|
356
358
|
};
|
357
359
|
|
358
360
|
/**
|
361
|
+
* Trace a single call, with a given name and arguments.
|
362
|
+
*
|
359
363
|
* @deprecated
|
364
|
+
* @param sectionName The name of the section to trace.
|
365
|
+
* @param promiseOrFunction Promise or a function that provides a promise.
|
366
|
+
* @param args Optional arguments to pass to the trace.
|
367
|
+
* @returns The returned value of the traced call.
|
368
|
+
* @see https://wix.github.io/Detox/docs/next/api/detox-object-api/#detoxtracecall.
|
360
369
|
*/
|
361
|
-
readonly traceCall: <T>(event: string, action: () => Promise<T>) => Promise<T>;
|
370
|
+
readonly traceCall: <T>(event: string, action: () => Promise<T>, args?: Record<string, unknown>) => Promise<T>;
|
362
371
|
}
|
363
372
|
|
364
373
|
interface Logger {
|
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.0.
|
4
|
+
"version": "20.0.7-prerelease.0",
|
5
5
|
"bin": {
|
6
6
|
"detox": "local-cli/cli.js"
|
7
7
|
},
|
@@ -184,5 +184,5 @@
|
|
184
184
|
}
|
185
185
|
}
|
186
186
|
},
|
187
|
-
"gitHead": "
|
187
|
+
"gitHead": "4b75f39310b93707f01e2bb38a4fba4d385e8acd"
|
188
188
|
}
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
const maybeNodeEnvironment = require('jest-environment-node');
|
1
|
+
const resolveFrom = require('resolve-from');
|
2
|
+
const maybeNodeEnvironment = require(resolveFrom(process.cwd(), 'jest-environment-node'));
|
3
|
+
// @ts-ignore
|
3
4
|
const NodeEnvironment = maybeNodeEnvironment.default || maybeNodeEnvironment;
|
4
5
|
|
5
6
|
const detox = require('../../../internals');
|
package/src/DetoxWorker.js
CHANGED
@@ -195,7 +195,6 @@ class DetoxWorker {
|
|
195
195
|
onTestStart = async (testSummary) => {
|
196
196
|
if (this._isCleaningUp) return;
|
197
197
|
this._validateTestSummary('beforeEach', testSummary);
|
198
|
-
this._logTestRunCheckpoint('DETOX_BEFORE_EACH', testSummary);
|
199
198
|
|
200
199
|
if (this._isCleaningUp) return;
|
201
200
|
await this._dumpUnhandledErrorsIfAny({
|
@@ -215,7 +214,6 @@ class DetoxWorker {
|
|
215
214
|
onTestDone = async (testSummary) => {
|
216
215
|
if (this._isCleaningUp) return;
|
217
216
|
this._validateTestSummary('afterEach', testSummary);
|
218
|
-
this._logTestRunCheckpoint('DETOX_AFTER_EACH', testSummary);
|
219
217
|
|
220
218
|
if (this._isCleaningUp) return;
|
221
219
|
await this._artifactsManager.onTestDone(testSummary);
|
@@ -251,10 +249,6 @@ class DetoxWorker {
|
|
251
249
|
}
|
252
250
|
}
|
253
251
|
|
254
|
-
_logTestRunCheckpoint(event, { status, fullName }) {
|
255
|
-
this.log.trace({ event, status }, `${status} test: ${JSON.stringify(fullName)}`);
|
256
|
-
}
|
257
|
-
|
258
252
|
_validateTestSummary(methodName, testSummary) {
|
259
253
|
if (!_.isPlainObject(testSummary)) {
|
260
254
|
throw this._runtimeErrorComposer.invalidTestSummary(methodName, testSummary);
|
@@ -5,6 +5,7 @@ const tempfile = require('tempfile');
|
|
5
5
|
|
6
6
|
const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
|
7
7
|
const invoke = require('../../invoke');
|
8
|
+
const { actionDescription } = require('../../utils/invocationTraceDescriptions');
|
8
9
|
const actions = require('../actions/native');
|
9
10
|
const DetoxMatcherApi = require('../espressoapi/DetoxMatcher');
|
10
11
|
const { ActionInteraction } = require('../interactions/native');
|
@@ -18,12 +19,11 @@ class NativeElement {
|
|
18
19
|
}
|
19
20
|
|
20
21
|
_selectElementWithMatcher(matcher) {
|
21
|
-
// if (!(matcher instanceof NativeMatcher)) throw new DetoxRuntimeError(`Element _selectElementWithMatcher argument must be a valid NativeMatcher, got ${typeof matcher}`);
|
22
22
|
this._call = invoke.call(invoke.Espresso, 'onView', matcher._call);
|
23
23
|
}
|
24
24
|
|
25
25
|
atIndex(index) {
|
26
|
-
if (typeof index !== 'number') throw new DetoxRuntimeError(`Element atIndex argument must be a number, got ${typeof index}`);
|
26
|
+
if (typeof index !== 'number') throw new DetoxRuntimeError({ message: `Element atIndex argument must be a number, got ${typeof index}` });
|
27
27
|
const matcher = this._originalMatcher;
|
28
28
|
this._originalMatcher._call = invoke.callDirectly(DetoxMatcherApi.matcherForAtIndex(index, matcher._call.value));
|
29
29
|
|
@@ -32,56 +32,84 @@ class NativeElement {
|
|
32
32
|
}
|
33
33
|
|
34
34
|
async tap(value) {
|
35
|
-
|
35
|
+
const action = new actions.TapAction(value);
|
36
|
+
const traceDescription = actionDescription.tapAtPoint(value);
|
37
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
36
38
|
}
|
37
39
|
|
38
40
|
async tapAtPoint(value) {
|
39
|
-
|
41
|
+
const action = new actions.TapAtPointAction(value);
|
42
|
+
const traceDescription = actionDescription.tapAtPoint(value);
|
43
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
40
44
|
}
|
41
45
|
|
42
46
|
async longPress() {
|
43
|
-
|
47
|
+
const action = new actions.LongPressAction();
|
48
|
+
const traceDescription = actionDescription.longPress();
|
49
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
44
50
|
}
|
45
51
|
|
46
52
|
async multiTap(times) {
|
47
|
-
|
53
|
+
if (typeof times !== 'number') throw new Error('times should be a number, but got ' + (times + (' (' + (typeof times + ')'))));
|
54
|
+
if (times < 1) throw new Error('times should be greater than 0, but got ' + times);
|
55
|
+
|
56
|
+
const action = new actions.MultiClickAction(times);
|
57
|
+
const traceDescription = actionDescription.multiTap(times);
|
58
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
48
59
|
}
|
49
60
|
|
50
61
|
async tapBackspaceKey() {
|
51
|
-
|
62
|
+
const action = new actions.PressKeyAction(67);
|
63
|
+
const traceDescription = actionDescription.tapBackspaceKey();
|
64
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
52
65
|
}
|
53
66
|
|
54
67
|
async tapReturnKey() {
|
55
|
-
|
68
|
+
const action = new actions.TypeTextAction('\n');
|
69
|
+
const traceDescription = actionDescription.tapReturnKey();
|
70
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
56
71
|
}
|
57
72
|
|
58
73
|
async typeText(value) {
|
59
|
-
|
74
|
+
const action = new actions.TypeTextAction(value);
|
75
|
+
const traceDescription = actionDescription.typeText(value);
|
76
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
60
77
|
}
|
61
78
|
|
62
79
|
async replaceText(value) {
|
63
|
-
|
80
|
+
const action = new actions.ReplaceTextAction(value);
|
81
|
+
const traceDescription = actionDescription.replaceText(value);
|
82
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
64
83
|
}
|
65
84
|
|
66
85
|
async clearText() {
|
67
|
-
|
86
|
+
const action = new actions.ClearTextAction();
|
87
|
+
const traceDescription = actionDescription.clearText();
|
88
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
68
89
|
}
|
69
90
|
|
70
91
|
async scroll(amount, direction = 'down', startPositionX, startPositionY) {
|
71
|
-
|
72
|
-
|
73
|
-
return await new ActionInteraction(this._invocationManager, this,
|
92
|
+
const action = new actions.ScrollAmountAction(direction, amount, startPositionX, startPositionY);
|
93
|
+
const traceDescription = actionDescription.scroll(amount, direction, startPositionX, startPositionY);
|
94
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
74
95
|
}
|
75
96
|
|
76
97
|
async scrollTo(edge) {
|
77
98
|
// override the user's element selection with an extended matcher that looks for UIScrollView children
|
78
99
|
this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
|
79
|
-
|
100
|
+
|
101
|
+
const action = new actions.ScrollEdgeAction(edge);
|
102
|
+
const traceDescription = actionDescription.scrollTo(edge);
|
103
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
80
104
|
}
|
81
105
|
|
82
106
|
async scrollToIndex(index) {
|
107
|
+
// override the user's element selection with an extended matcher that looks for UIScrollView children
|
83
108
|
this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
|
84
|
-
|
109
|
+
|
110
|
+
const action = new actions.ScrollToIndex(index);
|
111
|
+
const traceDescription = actionDescription.scrollToIndex(index);
|
112
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
85
113
|
}
|
86
114
|
|
87
115
|
/**
|
@@ -96,13 +124,17 @@ class NativeElement {
|
|
96
124
|
|
97
125
|
// override the user's element selection with an extended matcher that avoids RN issues with RCTScrollView
|
98
126
|
this._selectElementWithMatcher(this._originalMatcher._avoidProblematicReactNativeElements());
|
127
|
+
|
99
128
|
const action = new actions.SwipeAction(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
|
100
|
-
|
129
|
+
const traceDescription = actionDescription.swipe(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
|
130
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
101
131
|
}
|
102
132
|
|
103
133
|
async takeScreenshot(screenshotName) {
|
104
134
|
// TODO this should be moved to a lower-layer handler of this use-case
|
105
|
-
const
|
135
|
+
const action = new actions.TakeElementScreenshot();
|
136
|
+
const traceDescription = actionDescription.takeScreenshot(screenshotName);
|
137
|
+
const resultBase64 = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
106
138
|
const filePath = tempfile('detox.element-screenshot.png');
|
107
139
|
await fs.writeFile(filePath, resultBase64, 'base64');
|
108
140
|
|
@@ -115,12 +147,16 @@ class NativeElement {
|
|
115
147
|
}
|
116
148
|
|
117
149
|
async getAttributes() {
|
118
|
-
const
|
150
|
+
const action = new actions.GetAttributes();
|
151
|
+
const traceDescription = actionDescription.getAttributes();
|
152
|
+
const result = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
119
153
|
return JSON.parse(result);
|
120
154
|
}
|
121
155
|
|
122
156
|
async adjustSliderToPosition(newPosition) {
|
123
|
-
|
157
|
+
const action = new actions.AdjustSliderToPosition(newPosition);
|
158
|
+
const traceDescription = actionDescription.adjustSliderToPosition(newPosition);
|
159
|
+
return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
|
124
160
|
}
|
125
161
|
}
|
126
162
|
|