detox 20.14.4-smoke.0 → 20.14.5
Sign up to get free protection for your applications and to get access to all the features.
- package/Detox-android/com/wix/detox/{20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar → 20.14.5/detox-20.14.5-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar → 20.14.5/detox-20.14.5-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.aar +0 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.14.4-smoke.0/detox-20.14.4-smoke.0.pom → 20.14.5/detox-20.14.5.pom} +1 -1
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.5/detox-20.14.5.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/src/full/java/com/wix/detox/ActivityLaunchHelper.kt +78 -0
- package/android/detox/src/full/java/com/wix/detox/Detox.java +8 -70
- package/android/detox/src/full/java/com/wix/detox/DetoxMain.kt +69 -44
- package/android/detox/src/full/java/com/wix/detox/LaunchIntentsFactory.kt +1 -1
- package/android/detox/src/full/java/com/wix/detox/NotificationDataParser.kt +1 -1
- package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionHandlers.kt +0 -4
- package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionsDispatcher.kt +16 -6
- package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxServerAdapter.kt +0 -2
- package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxServerInfo.kt +4 -2
- package/android/detox/src/full/java/com/wix/detox/reactnative/ReactMarkersLogger.kt +44 -0
- package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +25 -32
- package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -3
- package/android/detox/src/testFull/java/com/wix/detox/ActivityLaunchHelperTest.kt +111 -0
- package/android/detox/src/testFull/java/com/wix/detox/espresso/matcher/RegexMatcherTest.kt +0 -3
- package/package.json +2 -2
- package/src/android/espressoapi/Detox.js +0 -11
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0.pom.sha512 +0 -1
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
9452502e485f0c19f6431080657c1af6
|
@@ -0,0 +1 @@
|
|
1
|
+
d324cf797101d537d40f9422ab2b0f163379fe75
|
@@ -0,0 +1 @@
|
|
1
|
+
d8141a3643a29682690d3257f0f5e811e5fa0b22aead686f0fea8c2972156c18
|
@@ -0,0 +1 @@
|
|
1
|
+
f26a08a896ef35d2069791f08befbfd865cc4610d5a3264b83bbb34a9c952f046f92767703b91eab575e45e3bb1728134f4bd6dbdd7367e7e0036173a0445b90
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
b356bf18b2b37c77db5dd233ca785842
|
@@ -0,0 +1 @@
|
|
1
|
+
a7a84377ebebbdeb54e6bbf30e8bae594621203f
|
@@ -0,0 +1 @@
|
|
1
|
+
7609141047f1b998e32fd6989e1e5b6afd75690a95960823deaf29e98b6505db
|
@@ -0,0 +1 @@
|
|
1
|
+
f740dc4eefc2cfec141723687fa4d3acfa5207ce127b461125b7b4fd04ebfa45af4918a489070ea89d144b1df25355311ae1f92b8c17bb3b0edcae84d48762bd
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
c27920150917efb5b25878186e904fe0
|
@@ -0,0 +1 @@
|
|
1
|
+
ad9e12738ca3c82606a58bacea6d50b51687aee9
|
@@ -0,0 +1 @@
|
|
1
|
+
ab07c0011f9cee612e5b56ea42618978b75a5cfff9841766fc3f796e730c3571
|
@@ -0,0 +1 @@
|
|
1
|
+
a26f964a1ef775262740a23fbbeca9e5754a5da7896bcab22a476f684d40168b67ad4a97087a1f6fe484343e70eb32063adfeac3a2879f887e8d7fc616e6eacc
|
@@ -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.14.
|
6
|
+
<version>20.14.5</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
|
+
05628b1955b9d2e1e5c173f0accda092
|
@@ -0,0 +1 @@
|
|
1
|
+
a6b46ecde38a5029dae5de5391aed0f49f16691d
|
@@ -0,0 +1 @@
|
|
1
|
+
82757e7e370b217bed5afc7cec09b3b717ea3b308ba25cd60d035cbd82711a18
|
@@ -0,0 +1 @@
|
|
1
|
+
5a680241676911e186fb41e4ce30d779be5cfa00e91e5c618ae3c9f713906b6add4334b8ca311a46613fa6063ea394f6eac48665d4c7882da42021f3ebf72fdc
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<groupId>com.wix</groupId>
|
4
4
|
<artifactId>detox</artifactId>
|
5
5
|
<versioning>
|
6
|
-
<latest>20.14.
|
7
|
-
<release>20.14.
|
6
|
+
<latest>20.14.5</latest>
|
7
|
+
<release>20.14.5</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.14.
|
9
|
+
<version>20.14.5</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20231224164415</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
74cdf7b5ef32bcc52364e12cbdac9ecb
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
f27b95426e12342add47387c1bee2b2d18b8c861
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
126b5c81bef151395b59d09c0e656d55fa2a35202bcaae4805464f8bb61be58d
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
689b5dedc7e658990cd8985b88b6a85c9cfcb4b7caf1d2691acbf44fe309f44e4c79cc00558c10af83aa1a05186fd6e4ac88d7d3051a0705932a330b519b7e80
|
package/Detox-ios-src.tbz
CHANGED
Binary file
|
package/Detox-ios.tbz
CHANGED
Binary file
|
@@ -0,0 +1,78 @@
|
|
1
|
+
package com.wix.detox
|
2
|
+
|
3
|
+
import android.app.Instrumentation.ActivityMonitor
|
4
|
+
import android.content.Context
|
5
|
+
import android.content.Intent
|
6
|
+
import androidx.test.platform.app.InstrumentationRegistry
|
7
|
+
import androidx.test.rule.ActivityTestRule
|
8
|
+
|
9
|
+
class ActivityLaunchHelper
|
10
|
+
@JvmOverloads constructor(
|
11
|
+
private val activityTestRule: ActivityTestRule<*>,
|
12
|
+
private val launchArgs: LaunchArgs = LaunchArgs(),
|
13
|
+
private val intentsFactory: LaunchIntentsFactory = LaunchIntentsFactory(),
|
14
|
+
private val notificationDataParserGen: (String) -> NotificationDataParser = { path -> NotificationDataParser(path) }
|
15
|
+
) {
|
16
|
+
fun launchActivityUnderTest() {
|
17
|
+
val intent = extractInitialIntent()
|
18
|
+
activityTestRule.launchActivity(intent)
|
19
|
+
}
|
20
|
+
|
21
|
+
fun launchMainActivity() {
|
22
|
+
val activity = activityTestRule.activity
|
23
|
+
launchActivitySync(intentsFactory.activityLaunchIntent(activity))
|
24
|
+
}
|
25
|
+
|
26
|
+
fun startActivityFromUrl(url: String) {
|
27
|
+
launchActivitySync(intentsFactory.intentWithUrl(url, false))
|
28
|
+
}
|
29
|
+
|
30
|
+
fun startActivityFromNotification(dataFilePath: String) {
|
31
|
+
val notificationData = notificationDataParserGen(dataFilePath).toBundle()
|
32
|
+
val intent = intentsFactory.intentWithNotificationData(appContext, notificationData, false)
|
33
|
+
launchActivitySync(intent)
|
34
|
+
}
|
35
|
+
|
36
|
+
private fun extractInitialIntent(): Intent =
|
37
|
+
(if (launchArgs.hasUrlOverride()) {
|
38
|
+
intentsFactory.intentWithUrl(launchArgs.urlOverride, true)
|
39
|
+
} else if (launchArgs.hasNotificationPath()) {
|
40
|
+
val notificationData = notificationDataParserGen(launchArgs.notificationPath).toBundle()
|
41
|
+
intentsFactory.intentWithNotificationData(appContext, notificationData, true)
|
42
|
+
} else {
|
43
|
+
intentsFactory.cleanIntent()
|
44
|
+
}).also {
|
45
|
+
it.putExtra(INTENT_LAUNCH_ARGS_KEY, launchArgs.asIntentBundle())
|
46
|
+
}
|
47
|
+
|
48
|
+
private fun launchActivitySync(intent: Intent) {
|
49
|
+
// Ideally, we would just call sActivityTestRule.launchActivity(intent) and get it over with.
|
50
|
+
// BUT!!! as it turns out, Espresso has an issue where doing this for an activity running in the background
|
51
|
+
// would have Espresso set up an ActivityMonitor which will spend its time waiting for the activity to load, *without
|
52
|
+
// ever being released*. It will finally fail after a 45 seconds timeout.
|
53
|
+
// Without going into full details, it seems that activity test rules were not meant to be used this way. However,
|
54
|
+
// the all-new ActivityScenario implementation introduced in androidx could probably support this (e.g. by using
|
55
|
+
// dedicated methods such as moveToState(), which give better control over the lifecycle).
|
56
|
+
// In any case, this is the core reason for this issue: https://github.com/wix/Detox/issues/1125
|
57
|
+
// What it forces us to do, then, is this -
|
58
|
+
// 1. Launch the activity by "ourselves" from the OS (i.e. using context.startActivity()).
|
59
|
+
// 2. Set up an activity monitor by ourselves -- such that it would block until the activity is ready.
|
60
|
+
// ^ Hence the code below.
|
61
|
+
val activity = activityTestRule.activity
|
62
|
+
val activityMonitor = ActivityMonitor(activity.javaClass.name, null, true)
|
63
|
+
activity.startActivity(intent)
|
64
|
+
|
65
|
+
InstrumentationRegistry.getInstrumentation().run {
|
66
|
+
addMonitor(activityMonitor)
|
67
|
+
waitForMonitorWithTimeout(activityMonitor, ACTIVITY_LAUNCH_TIMEOUT)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
private val appContext: Context
|
72
|
+
get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
|
73
|
+
|
74
|
+
companion object {
|
75
|
+
private const val INTENT_LAUNCH_ARGS_KEY = "launchArgs"
|
76
|
+
private const val ACTIVITY_LAUNCH_TIMEOUT = 10000L
|
77
|
+
}
|
78
|
+
}
|
@@ -1,18 +1,13 @@
|
|
1
1
|
package com.wix.detox;
|
2
2
|
|
3
|
-
import android.app.Activity;
|
4
|
-
import android.app.Instrumentation;
|
5
3
|
import android.content.Context;
|
6
|
-
import android.content.Intent;
|
7
|
-
import android.os.Bundle;
|
8
|
-
|
9
|
-
import com.wix.detox.config.DetoxConfig;
|
10
|
-
import com.wix.detox.espresso.UiControllerSpy;
|
11
4
|
|
12
5
|
import androidx.annotation.NonNull;
|
13
6
|
import androidx.test.platform.app.InstrumentationRegistry;
|
14
7
|
import androidx.test.rule.ActivityTestRule;
|
15
8
|
|
9
|
+
import com.wix.detox.config.DetoxConfig;
|
10
|
+
|
16
11
|
/**
|
17
12
|
* <p>Static class.</p>
|
18
13
|
*
|
@@ -67,12 +62,7 @@ import androidx.test.rule.ActivityTestRule;
|
|
67
62
|
* <p>If not set, then Detox tests are no ops. So it's safe to mix it with other tests.</p>
|
68
63
|
*/
|
69
64
|
public final class Detox {
|
70
|
-
private static
|
71
|
-
private static final long ACTIVITY_LAUNCH_TIMEOUT = 10000L;
|
72
|
-
|
73
|
-
private static final LaunchArgs sLaunchArgs = new LaunchArgs();
|
74
|
-
private static final LaunchIntentsFactory sIntentsFactory = new LaunchIntentsFactory();
|
75
|
-
private static ActivityTestRule sActivityTestRule;
|
65
|
+
private static ActivityLaunchHelper sActivityLaunchHelper;
|
76
66
|
|
77
67
|
private Detox() {
|
78
68
|
}
|
@@ -132,72 +122,20 @@ public final class Detox {
|
|
132
122
|
DetoxConfig.CONFIG = detoxConfig;
|
133
123
|
DetoxConfig.CONFIG.apply();
|
134
124
|
|
135
|
-
|
136
|
-
|
137
|
-
UiControllerSpy.attachThroughProxy();
|
138
|
-
|
139
|
-
Intent intent = extractInitialIntent();
|
140
|
-
sActivityTestRule.launchActivity(intent);
|
141
|
-
|
142
|
-
try {
|
143
|
-
DetoxMain.run(context);
|
144
|
-
} catch (Exception e) {
|
145
|
-
Thread.currentThread().interrupt();
|
146
|
-
throw new RuntimeException("Detox got interrupted prematurely", e);
|
147
|
-
}
|
125
|
+
sActivityLaunchHelper = new ActivityLaunchHelper(activityTestRule);
|
126
|
+
DetoxMain.run(context, sActivityLaunchHelper);
|
148
127
|
}
|
149
128
|
|
150
129
|
public static void launchMainActivity() {
|
151
|
-
|
152
|
-
launchActivitySync(sIntentsFactory.activityLaunchIntent(activity));
|
130
|
+
sActivityLaunchHelper.launchMainActivity();
|
153
131
|
}
|
154
132
|
|
155
133
|
public static void startActivityFromUrl(String url) {
|
156
|
-
|
134
|
+
sActivityLaunchHelper.startActivityFromUrl(url);
|
157
135
|
}
|
158
136
|
|
159
137
|
public static void startActivityFromNotification(String dataFilePath) {
|
160
|
-
|
161
|
-
Intent intent = sIntentsFactory.intentWithNotificationData(getAppContext(), notificationData, false);
|
162
|
-
launchActivitySync(intent);
|
163
|
-
}
|
164
|
-
|
165
|
-
private static Intent extractInitialIntent() {
|
166
|
-
Intent intent;
|
167
|
-
|
168
|
-
if (sLaunchArgs.hasUrlOverride()) {
|
169
|
-
intent = sIntentsFactory.intentWithUrl(sLaunchArgs.getUrlOverride(), true);
|
170
|
-
} else if (sLaunchArgs.hasNotificationPath()) {
|
171
|
-
Bundle notificationData = new NotificationDataParser(sLaunchArgs.getNotificationPath()).toBundle();
|
172
|
-
intent = sIntentsFactory.intentWithNotificationData(getAppContext(), notificationData, true);
|
173
|
-
} else {
|
174
|
-
intent = sIntentsFactory.cleanIntent();
|
175
|
-
}
|
176
|
-
intent.putExtra(INTENT_LAUNCH_ARGS_KEY, sLaunchArgs.asIntentBundle());
|
177
|
-
return intent;
|
178
|
-
}
|
179
|
-
|
180
|
-
private static void launchActivitySync(Intent intent) {
|
181
|
-
// Ideally, we would just call sActivityTestRule.launchActivity(intent) and get it over with.
|
182
|
-
// BUT!!! as it turns out, Espresso has an issue where doing this for an activity running in the background
|
183
|
-
// would have Espresso set up an ActivityMonitor which will spend its time waiting for the activity to load, *without
|
184
|
-
// ever being released*. It will finally fail after a 45 seconds timeout.
|
185
|
-
// Without going into full details, it seems that activity test rules were not meant to be used this way. However,
|
186
|
-
// the all-new ActivityScenario implementation introduced in androidx could probably support this (e.g. by using
|
187
|
-
// dedicated methods such as moveToState(), which give better control over the lifecycle).
|
188
|
-
// In any case, this is the core reason for this issue: https://github.com/wix/Detox/issues/1125
|
189
|
-
// What it forces us to do, then, is this -
|
190
|
-
// 1. Launch the activity by "ourselves" from the OS (i.e. using context.startActivity()).
|
191
|
-
// 2. Set up an activity monitor by ourselves -- such that it would block until the activity is ready.
|
192
|
-
// ^ Hence the code below.
|
193
|
-
|
194
|
-
final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
|
195
|
-
final Activity activity = sActivityTestRule.getActivity();
|
196
|
-
final Instrumentation.ActivityMonitor activityMonitor = new Instrumentation.ActivityMonitor(activity.getClass().getName(), null, true);
|
197
|
-
|
198
|
-
activity.startActivity(intent);
|
199
|
-
instrumentation.addMonitor(activityMonitor);
|
200
|
-
instrumentation.waitForMonitorWithTimeout(activityMonitor, ACTIVITY_LAUNCH_TIMEOUT);
|
138
|
+
sActivityLaunchHelper.startActivityFromNotification(dataFilePath);
|
201
139
|
}
|
202
140
|
|
203
141
|
private static Context getAppContext() {
|
@@ -3,35 +3,62 @@ package com.wix.detox
|
|
3
3
|
import android.content.Context
|
4
4
|
import android.util.Log
|
5
5
|
import com.wix.detox.adapters.server.*
|
6
|
-
import com.wix.detox.common.DetoxLog
|
6
|
+
import com.wix.detox.common.DetoxLog
|
7
|
+
import com.wix.detox.espresso.UiControllerSpy
|
7
8
|
import com.wix.detox.instruments.DetoxInstrumentsManager
|
8
9
|
import com.wix.detox.reactnative.ReactNativeExtension
|
9
10
|
import com.wix.invoke.MethodInvocation
|
11
|
+
import java.util.concurrent.CountDownLatch
|
10
12
|
|
11
|
-
private const val INIT_ACTION = "_init"
|
12
|
-
private const val IS_READY_ACTION = "isReady"
|
13
13
|
private const val TERMINATION_ACTION = "_terminate"
|
14
14
|
|
15
15
|
object DetoxMain {
|
16
|
+
private val handshakeLock = CountDownLatch(1)
|
17
|
+
|
16
18
|
@JvmStatic
|
17
|
-
fun run(rnHostHolder: Context) {
|
19
|
+
fun run(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
|
18
20
|
val detoxServerInfo = DetoxServerInfo()
|
19
|
-
Log.i(LOG_TAG, "Detox server connection details: $detoxServerInfo")
|
20
|
-
|
21
21
|
val testEngineFacade = TestEngineFacade()
|
22
22
|
val actionsDispatcher = DetoxActionsDispatcher()
|
23
|
-
val
|
24
|
-
|
25
|
-
|
23
|
+
val serverAdapter = DetoxServerAdapter(actionsDispatcher, detoxServerInfo, TERMINATION_ACTION)
|
24
|
+
|
25
|
+
initCrashHandler(serverAdapter)
|
26
|
+
initANRListener(serverAdapter)
|
27
|
+
initEspresso()
|
28
|
+
initReactNative()
|
29
|
+
|
30
|
+
setupActionHandlers(actionsDispatcher, serverAdapter, testEngineFacade, rnHostHolder)
|
31
|
+
serverAdapter.connect()
|
32
|
+
|
33
|
+
launchActivityOnCue(rnHostHolder, activityLaunchHelper)
|
26
34
|
actionsDispatcher.join()
|
27
35
|
}
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
/**
|
38
|
+
* Launch the tested activity "on cue", namely, right after a connection is established and the handshake
|
39
|
+
* completes successfully.
|
40
|
+
*
|
41
|
+
* This has to be synchronized so that an `isReady` isn't handled *before* the activity is launched (albeit not fully
|
42
|
+
* initialized - all native modules and everything) and a react context is available.
|
43
|
+
*
|
44
|
+
* As a better alternative, it would make sense to execute this as a simple action from within the actions
|
45
|
+
* dispatcher (i.e. handler of `loginSuccess`), in which case, no inter-thread locking would be required
|
46
|
+
* thanks to the usage of Handlers. However, in this type of a solution, errors / crashes would be reported
|
47
|
+
* not by instrumentation itself, but based on the `AppWillTerminateWithError` message; In it's own, it is a good
|
48
|
+
* thing, but for a reason we're not sure of yet, it is ignored by the test runner at this point in the flow.
|
49
|
+
*/
|
50
|
+
@Synchronized
|
51
|
+
private fun launchActivityOnCue(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
|
52
|
+
awaitHandshake()
|
53
|
+
launchActivity(rnHostHolder, activityLaunchHelper)
|
54
|
+
}
|
55
|
+
|
56
|
+
private fun awaitHandshake() {
|
57
|
+
handshakeLock.await()
|
58
|
+
}
|
31
59
|
|
32
|
-
|
33
|
-
|
34
|
-
initReactNativeIfNeeded(rnHostHolder)
|
60
|
+
private fun onLoginSuccess() {
|
61
|
+
handshakeLock.countDown()
|
35
62
|
}
|
36
63
|
|
37
64
|
private fun doTeardown(serverAdapter: DetoxServerAdapter, actionsDispatcher: DetoxActionsDispatcher, testEngineFacade: TestEngineFacade) {
|
@@ -41,35 +68,28 @@ object DetoxMain {
|
|
41
68
|
actionsDispatcher.teardown()
|
42
69
|
}
|
43
70
|
|
44
|
-
private fun
|
71
|
+
private fun setupActionHandlers(actionsDispatcher: DetoxActionsDispatcher, serverAdapter: DetoxServerAdapter, testEngineFacade: TestEngineFacade, rnHostHolder: Context) {
|
72
|
+
class SynchronizedActionHandler(private val actionHandler: DetoxActionHandler): DetoxActionHandler {
|
73
|
+
override fun handle(params: String, messageId: Long) {
|
74
|
+
synchronized(this@DetoxMain) {
|
75
|
+
actionHandler.handle(params, messageId)
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
45
80
|
// Primary actions
|
46
81
|
with(actionsDispatcher) {
|
47
|
-
val
|
82
|
+
val readyHandler = SynchronizedActionHandler( ReadyActionHandler(serverAdapter, testEngineFacade) )
|
83
|
+
val rnReloadHandler = SynchronizedActionHandler( ReactNativeReloadActionHandler(rnHostHolder, serverAdapter, testEngineFacade) )
|
48
84
|
|
49
|
-
associateActionHandler(
|
50
|
-
|
51
|
-
|
52
|
-
this@DetoxMain.doInit(serverAdapter, rnHostHolder)
|
53
|
-
}
|
54
|
-
})
|
55
|
-
associateActionHandler(IS_READY_ACTION, ReadyActionHandler(serverAdapter, testEngineFacade))
|
56
|
-
|
57
|
-
associateActionHandler("loginSuccess", ScarceActionHandler())
|
58
|
-
associateActionHandler("reactNativeReload", object: DetoxActionHandler {
|
59
|
-
override fun handle(params: String, messageId: Long) =
|
60
|
-
synchronized(this@DetoxMain) {
|
61
|
-
rnReloadHandler.handle(params, messageId)
|
62
|
-
}
|
63
|
-
})
|
85
|
+
associateActionHandler("loginSuccess", ::onLoginSuccess)
|
86
|
+
associateActionHandler("isReady", readyHandler)
|
87
|
+
associateActionHandler("reactNativeReload", rnReloadHandler)
|
64
88
|
associateActionHandler("invoke", InvokeActionHandler(MethodInvocation(), serverAdapter))
|
65
89
|
associateActionHandler("cleanup", CleanupActionHandler(serverAdapter, testEngineFacade) {
|
66
90
|
dispatchAction(TERMINATION_ACTION, "", 0)
|
67
91
|
})
|
68
|
-
associateActionHandler(TERMINATION_ACTION,
|
69
|
-
override fun handle(params: String, messageId: Long) {
|
70
|
-
this@DetoxMain.doTeardown(serverAdapter, actionsDispatcher, testEngineFacade)
|
71
|
-
}
|
72
|
-
})
|
92
|
+
associateActionHandler(TERMINATION_ACTION) { -> doTeardown(serverAdapter, actionsDispatcher, testEngineFacade) }
|
73
93
|
|
74
94
|
if (DetoxInstrumentsManager.supports()) {
|
75
95
|
val instrumentsManager = DetoxInstrumentsManager(rnHostHolder)
|
@@ -80,13 +100,8 @@ object DetoxMain {
|
|
80
100
|
|
81
101
|
// Secondary actions
|
82
102
|
with(actionsDispatcher) {
|
83
|
-
val queryStatusHandler = QueryStatusActionHandler(serverAdapter, testEngineFacade)
|
84
|
-
|
85
|
-
override fun handle(params: String, messageId: Long) =
|
86
|
-
synchronized(this@DetoxMain) {
|
87
|
-
queryStatusHandler.handle(params, messageId)
|
88
|
-
}
|
89
|
-
}, false)
|
103
|
+
val queryStatusHandler = SynchronizedActionHandler( QueryStatusActionHandler(serverAdapter, testEngineFacade) )
|
104
|
+
associateSecondaryActionHandler("currentStatus", queryStatusHandler)
|
90
105
|
}
|
91
106
|
}
|
92
107
|
|
@@ -98,7 +113,17 @@ object DetoxMain {
|
|
98
113
|
DetoxANRHandler(outboundServerAdapter).attach()
|
99
114
|
}
|
100
115
|
|
101
|
-
private fun
|
116
|
+
private fun initEspresso() {
|
117
|
+
UiControllerSpy.attachThroughProxy()
|
118
|
+
}
|
119
|
+
|
120
|
+
private fun initReactNative() {
|
121
|
+
ReactNativeExtension.initIfNeeded()
|
122
|
+
}
|
123
|
+
|
124
|
+
private fun launchActivity(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
|
125
|
+
Log.i(DetoxLog.LOG_TAG, "Launching the tested activity!")
|
126
|
+
activityLaunchHelper.launchActivityUnderTest()
|
102
127
|
ReactNativeExtension.waitForRNBootstrap(rnHostHolder)
|
103
128
|
}
|
104
129
|
}
|
@@ -5,7 +5,7 @@ import com.wix.detox.common.JsonConverter
|
|
5
5
|
import com.wix.detox.common.TextFileReader
|
6
6
|
import org.json.JSONObject
|
7
7
|
|
8
|
-
|
8
|
+
class NotificationDataParser(private val notificationPath: String) {
|
9
9
|
fun toBundle(): Bundle {
|
10
10
|
val rawData = readNotificationFromFile()
|
11
11
|
val json = JSONObject(rawData)
|
@@ -11,11 +11,18 @@ class DetoxActionsDispatcher {
|
|
11
11
|
private val primaryExec = ActionsExecutor("detox.primary")
|
12
12
|
private val secondaryExec = ActionsExecutor("detox.secondary")
|
13
13
|
|
14
|
-
fun associateActionHandler(type: String, actionHandler: DetoxActionHandler
|
15
|
-
|
16
|
-
|
14
|
+
fun associateActionHandler(type: String, actionHandler: DetoxActionHandler) =
|
15
|
+
associateActionHandler(type, actionHandler, true)
|
16
|
+
|
17
|
+
fun associateActionHandler(type: String, handlerFunc: () -> Unit) {
|
18
|
+
associateActionHandler(type, object: DetoxActionHandler {
|
19
|
+
override fun handle(params: String, messageId: Long) = handlerFunc()
|
20
|
+
})
|
17
21
|
}
|
18
22
|
|
23
|
+
fun associateSecondaryActionHandler(type: String, actionHandler: DetoxActionHandler) =
|
24
|
+
associateActionHandler(type, actionHandler, false)
|
25
|
+
|
19
26
|
fun dispatchAction(type: String, params: String, messageId: Long) {
|
20
27
|
(primaryExec.executeAction(type, params, messageId) ||
|
21
28
|
secondaryExec.executeAction(type, params, messageId))
|
@@ -33,6 +40,11 @@ class DetoxActionsDispatcher {
|
|
33
40
|
primaryExec.join()
|
34
41
|
secondaryExec.join()
|
35
42
|
}
|
43
|
+
|
44
|
+
private fun associateActionHandler(type: String, actionHandler: DetoxActionHandler, isPrimary: Boolean = true) {
|
45
|
+
val actionsExecutor = (if (isPrimary) primaryExec else secondaryExec)
|
46
|
+
actionsExecutor.associateHandler(type, actionHandler)
|
47
|
+
}
|
36
48
|
}
|
37
49
|
|
38
50
|
private class ActionsExecutor(name: String) {
|
@@ -74,7 +86,5 @@ private class ActionsExecutor(name: String) {
|
|
74
86
|
handler.looper.quit()
|
75
87
|
}
|
76
88
|
|
77
|
-
fun join()
|
78
|
-
thread.join()
|
79
|
-
}
|
89
|
+
fun join() = thread.join()
|
80
90
|
}
|
@@ -10,7 +10,6 @@ interface OutboundServerAdapter {
|
|
10
10
|
class DetoxServerAdapter(
|
11
11
|
private val actionsDispatcher: DetoxActionsDispatcher,
|
12
12
|
private val detoxServerInfo: DetoxServerInfo,
|
13
|
-
private val readyActionType: String,
|
14
13
|
private val terminationActionType: String)
|
15
14
|
: WebSocketClient.WSEventsHandler, OutboundServerAdapter {
|
16
15
|
|
@@ -27,7 +26,6 @@ class DetoxServerAdapter(
|
|
27
26
|
|
28
27
|
override fun onConnect() {
|
29
28
|
Log.i(DetoxLog.LOG_TAG, "Connected to server!")
|
30
|
-
actionsDispatcher.dispatchAction(readyActionType, "", -1000L)
|
31
29
|
}
|
32
30
|
|
33
31
|
override fun onClosed() {
|
@@ -1,7 +1,9 @@
|
|
1
1
|
package com.wix.detox.adapters.server
|
2
2
|
|
3
|
+
import android.util.Log
|
3
4
|
import androidx.test.platform.app.InstrumentationRegistry
|
4
5
|
import com.wix.detox.LaunchArgs
|
6
|
+
import com.wix.detox.common.DetoxLog
|
5
7
|
|
6
8
|
private const val DEFAULT_URL = "ws://localhost:8099"
|
7
9
|
|
@@ -9,7 +11,7 @@ class DetoxServerInfo internal constructor(launchArgs: LaunchArgs = LaunchArgs()
|
|
9
11
|
val serverUrl: String = launchArgs.detoxServerUrl ?: DEFAULT_URL
|
10
12
|
val sessionId: String = launchArgs.detoxSessionId ?: InstrumentationRegistry.getInstrumentation().targetContext.applicationInfo.packageName
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
init {
|
15
|
+
Log.i(DetoxLog.LOG_TAG, "Detox server connection details: url=$serverUrl, sessionId=$sessionId")
|
14
16
|
}
|
15
17
|
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
package com.wix.detox.reactnative
|
2
|
+
|
3
|
+
import android.util.Log
|
4
|
+
import com.facebook.react.bridge.ReactMarker
|
5
|
+
import com.facebook.react.bridge.ReactMarkerConstants
|
6
|
+
import com.facebook.react.bridge.ReactMarkerConstants.*
|
7
|
+
|
8
|
+
object ReactMarkersLogger : ReactMarker.MarkerListener {
|
9
|
+
|
10
|
+
fun attach() {
|
11
|
+
ReactMarker.addListener(this)
|
12
|
+
}
|
13
|
+
|
14
|
+
override fun logMarker(marker: ReactMarkerConstants, p1: String?, p2: Int) {
|
15
|
+
when {
|
16
|
+
marker == DOWNLOAD_START ||
|
17
|
+
marker == DOWNLOAD_END ||
|
18
|
+
marker == BUILD_REACT_INSTANCE_MANAGER_START ||
|
19
|
+
marker == BUILD_REACT_INSTANCE_MANAGER_END ||
|
20
|
+
marker == REACT_BRIDGE_LOADING_START ||
|
21
|
+
marker == REACT_BRIDGE_LOADING_END ||
|
22
|
+
marker == REACT_BRIDGELESS_LOADING_START ||
|
23
|
+
marker == REACT_BRIDGELESS_LOADING_END ||
|
24
|
+
marker == CREATE_MODULE_START ||
|
25
|
+
marker == CREATE_MODULE_END ||
|
26
|
+
marker == NATIVE_MODULE_SETUP_START ||
|
27
|
+
marker == NATIVE_MODULE_SETUP_END ||
|
28
|
+
marker == PRE_RUN_JS_BUNDLE_START ||
|
29
|
+
marker == RUN_JS_BUNDLE_START ||
|
30
|
+
marker == RUN_JS_BUNDLE_END ||
|
31
|
+
marker == CONTENT_APPEARED ||
|
32
|
+
marker == CREATE_CATALYST_INSTANCE_START ||
|
33
|
+
marker == CREATE_CATALYST_INSTANCE_END ||
|
34
|
+
marker == DESTROY_CATALYST_INSTANCE_START ||
|
35
|
+
marker == DESTROY_CATALYST_INSTANCE_END ||
|
36
|
+
marker == CREATE_REACT_CONTEXT_START ||
|
37
|
+
marker == CREATE_REACT_CONTEXT_END ||
|
38
|
+
marker == PROCESS_PACKAGES_START ||
|
39
|
+
marker == PROCESS_PACKAGES_END ||
|
40
|
+
false ->
|
41
|
+
Log.d("Detox.RNMarker", "$marker ($p1)")
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -14,6 +14,31 @@ private const val LOG_TAG = "DetoxRNExt"
|
|
14
14
|
object ReactNativeExtension {
|
15
15
|
private var rnIdlingResources: ReactNativeIdlingResources? = null
|
16
16
|
|
17
|
+
fun initIfNeeded() {
|
18
|
+
if (!ReactNativeInfo.isReactNativeApp()) {
|
19
|
+
return
|
20
|
+
}
|
21
|
+
|
22
|
+
ReactMarkersLogger.attach()
|
23
|
+
}
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Wait for React-Native to finish loading (i.e. make RN context available).
|
27
|
+
*
|
28
|
+
* @param applicationContext The app context, implicitly assumed to be a [ReactApplication] instance.
|
29
|
+
*/
|
30
|
+
fun waitForRNBootstrap(applicationContext: Context) {
|
31
|
+
if (!ReactNativeInfo.isReactNativeApp()) {
|
32
|
+
return
|
33
|
+
}
|
34
|
+
|
35
|
+
(applicationContext as ReactApplication).let {
|
36
|
+
val reactContext = awaitNewReactNativeContext(it, null)
|
37
|
+
|
38
|
+
enableOrDisableSynchronization(reactContext)
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
17
42
|
/**
|
18
43
|
* Reloads the React Native context and thus all javascript code.
|
19
44
|
*
|
@@ -40,26 +65,6 @@ object ReactNativeExtension {
|
|
40
65
|
val reactContext = awaitNewReactNativeContext(it, previousReactContext)
|
41
66
|
|
42
67
|
enableOrDisableSynchronization(reactContext, networkSyncEnabled)
|
43
|
-
hackRN50OrHigherWaitForReady()
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
/**
|
48
|
-
* Wait for React-Native to finish loading (i.e. make RN context available).
|
49
|
-
*
|
50
|
-
* @param applicationContext The app context, implicitly assumed to be a [ReactApplication] instance.
|
51
|
-
*/
|
52
|
-
@JvmStatic
|
53
|
-
fun waitForRNBootstrap(applicationContext: Context) {
|
54
|
-
if (!ReactNativeInfo.isReactNativeApp()) {
|
55
|
-
return
|
56
|
-
}
|
57
|
-
|
58
|
-
(applicationContext as ReactApplication).let {
|
59
|
-
val reactContext = awaitNewReactNativeContext(it, null)
|
60
|
-
|
61
|
-
enableOrDisableSynchronization(reactContext)
|
62
|
-
hackRN50OrHigherWaitForReady()
|
63
68
|
}
|
64
69
|
}
|
65
70
|
|
@@ -145,18 +150,6 @@ object ReactNativeExtension {
|
|
145
150
|
}
|
146
151
|
}
|
147
152
|
|
148
|
-
private fun hackRN50OrHigherWaitForReady() {
|
149
|
-
if (ReactNativeInfo.rnVersion().minor in 50..62) {
|
150
|
-
try {
|
151
|
-
//TODO- Temp hack to make Detox usable for RN>=50 till we find a better sync solution.
|
152
|
-
Thread.sleep(1000)
|
153
|
-
} catch (e: InterruptedException) {
|
154
|
-
e.printStackTrace()
|
155
|
-
}
|
156
|
-
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
153
|
private fun clearIdlingResources() {
|
161
154
|
rnIdlingResources?.unregisterAll()
|
162
155
|
rnIdlingResources = null
|
@@ -11,11 +11,8 @@ class UiControllerSpy: MethodsSpy("uiController") {
|
|
11
11
|
fun eventInjectionsIterator(): Iterator<CallInfo?> = historyOf("injectMotionEvent").iterator()
|
12
12
|
|
13
13
|
companion object {
|
14
|
-
@JvmStatic
|
15
14
|
val instance = UiControllerSpy()
|
16
15
|
|
17
|
-
@JvmStatic
|
18
|
-
@JvmOverloads
|
19
16
|
fun attachThroughProxy(spy: UiControllerSpy = instance) {
|
20
17
|
val eventsInjectorReflected = EventsInjectorReflected(getUiController())
|
21
18
|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
package com.wix.detox
|
2
|
+
|
3
|
+
import android.app.Activity
|
4
|
+
import android.content.Intent
|
5
|
+
import android.os.Bundle
|
6
|
+
import org.mockito.kotlin.*
|
7
|
+
import androidx.test.rule.ActivityTestRule
|
8
|
+
import org.junit.runner.RunWith
|
9
|
+
import org.assertj.core.api.Assertions.assertThat
|
10
|
+
import org.junit.Before
|
11
|
+
import org.junit.Test
|
12
|
+
import org.mockito.ArgumentMatchers.anyBoolean
|
13
|
+
import org.mockito.ArgumentMatchers.anyString
|
14
|
+
import org.robolectric.RobolectricTestRunner
|
15
|
+
|
16
|
+
@RunWith(RobolectricTestRunner::class)
|
17
|
+
class ActivityLaunchHelperTest {
|
18
|
+
|
19
|
+
private val initialURL = "detox://unit-test"
|
20
|
+
private val bundleExtraLaunchArgs = "launchArgs"
|
21
|
+
private val notificationPath = "path/to/notification.data"
|
22
|
+
|
23
|
+
private lateinit var intent: Intent
|
24
|
+
private lateinit var launchArgsAsBundle: Bundle
|
25
|
+
private lateinit var notificationDataAsBundle: Bundle
|
26
|
+
private lateinit var testRule: ActivityTestRule<Activity>
|
27
|
+
private lateinit var launchArgs: LaunchArgs
|
28
|
+
private lateinit var intentsFactory: LaunchIntentsFactory
|
29
|
+
private lateinit var notificationDataParser: NotificationDataParser
|
30
|
+
|
31
|
+
private fun uut() = ActivityLaunchHelper(testRule, launchArgs, intentsFactory, { notificationDataParser })
|
32
|
+
|
33
|
+
@Before
|
34
|
+
fun setup() {
|
35
|
+
intent = Intent()
|
36
|
+
launchArgsAsBundle = mock()
|
37
|
+
notificationDataAsBundle = mock()
|
38
|
+
|
39
|
+
testRule = mock()
|
40
|
+
launchArgs = mock() {
|
41
|
+
on { asIntentBundle() }.thenReturn(launchArgsAsBundle)
|
42
|
+
}
|
43
|
+
intentsFactory = mock()
|
44
|
+
notificationDataParser = mock() {
|
45
|
+
on { toBundle() }.thenReturn(notificationDataAsBundle)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
@Test
|
50
|
+
fun `default-activity -- should launch using test rule, with a clean intent`() {
|
51
|
+
givenCleanLaunch()
|
52
|
+
uut().launchActivityUnderTest()
|
53
|
+
verify(testRule).launchActivity(eq(intent))
|
54
|
+
}
|
55
|
+
|
56
|
+
@Test
|
57
|
+
fun `default-activity -- should apply launch args to intent`() {
|
58
|
+
givenCleanLaunch()
|
59
|
+
uut().launchActivityUnderTest()
|
60
|
+
assertIntentHasLaunchArgs()
|
61
|
+
}
|
62
|
+
|
63
|
+
@Test
|
64
|
+
fun `default activity, with a url -- should launch based on the url`() {
|
65
|
+
givenLaunchWithInitialURL()
|
66
|
+
uut().launchActivityUnderTest()
|
67
|
+
verify(testRule).launchActivity(eq(intent))
|
68
|
+
verify(intentsFactory).intentWithUrl(initialURL, true)
|
69
|
+
}
|
70
|
+
|
71
|
+
@Test
|
72
|
+
fun `default activity, with a url -- should apply launch args to intent`() {
|
73
|
+
givenLaunchWithInitialURL()
|
74
|
+
uut().launchActivityUnderTest()
|
75
|
+
assertIntentHasLaunchArgs()
|
76
|
+
}
|
77
|
+
|
78
|
+
@Test
|
79
|
+
fun `default activity, with notification data -- should launch with the data as bundle`() {
|
80
|
+
givenLaunchWithNotificationData()
|
81
|
+
uut().launchActivityUnderTest()
|
82
|
+
verify(testRule).launchActivity(eq(intent))
|
83
|
+
verify(intentsFactory).intentWithNotificationData(any(), eq(notificationDataAsBundle), eq(true))
|
84
|
+
}
|
85
|
+
|
86
|
+
@Test
|
87
|
+
fun `default activity, with notification data -- should apply launch args to intent`() {
|
88
|
+
givenLaunchWithNotificationData()
|
89
|
+
uut().launchActivityUnderTest()
|
90
|
+
assertIntentHasLaunchArgs()
|
91
|
+
}
|
92
|
+
|
93
|
+
private fun givenCleanLaunch() {
|
94
|
+
whenever(intentsFactory.cleanIntent()).thenReturn(intent)
|
95
|
+
}
|
96
|
+
private fun givenLaunchWithInitialURL() {
|
97
|
+
whenever(launchArgs.hasUrlOverride()).thenReturn(true)
|
98
|
+
whenever(launchArgs.urlOverride).thenReturn(initialURL)
|
99
|
+
whenever(intentsFactory.intentWithUrl(anyString(), anyBoolean())).thenReturn(intent)
|
100
|
+
}
|
101
|
+
private fun givenLaunchWithNotificationData() {
|
102
|
+
whenever(launchArgs.hasNotificationPath()).thenReturn(true)
|
103
|
+
whenever(launchArgs.notificationPath).thenReturn(notificationPath)
|
104
|
+
whenever(intentsFactory.intentWithNotificationData(any(), any(), anyBoolean()))
|
105
|
+
.thenReturn(intent)
|
106
|
+
}
|
107
|
+
private fun assertIntentHasLaunchArgs() {
|
108
|
+
assertThat(intent.hasExtra(bundleExtraLaunchArgs)).isTrue
|
109
|
+
assertThat(intent.getBundleExtra(bundleExtraLaunchArgs)).isEqualTo(launchArgsAsBundle)
|
110
|
+
}
|
111
|
+
}
|
@@ -3,10 +3,7 @@ package com.wix.detox.espresso.matcher
|
|
3
3
|
import org.junit.Test
|
4
4
|
import kotlin.test.assertFalse
|
5
5
|
import kotlin.test.assertTrue
|
6
|
-
import org.junit.runner.RunWith
|
7
|
-
import org.robolectric.RobolectricTestRunner
|
8
6
|
|
9
|
-
@RunWith(RobolectricTestRunner::class)
|
10
7
|
class RegexMatcherTest {
|
11
8
|
@Test
|
12
9
|
fun `should work with string matching regex`() {
|
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.14.
|
4
|
+
"version": "20.14.5",
|
5
5
|
"bin": {
|
6
6
|
"detox": "local-cli/cli.js"
|
7
7
|
},
|
@@ -109,5 +109,5 @@
|
|
109
109
|
"browserslist": [
|
110
110
|
"node 14"
|
111
111
|
],
|
112
|
-
"gitHead": "
|
112
|
+
"gitHead": "826ba256c4a629c12497396c612cdff98794efc8"
|
113
113
|
}
|
@@ -58,17 +58,6 @@ class Detox {
|
|
58
58
|
};
|
59
59
|
}
|
60
60
|
|
61
|
-
static extractInitialIntent() {
|
62
|
-
return {
|
63
|
-
target: {
|
64
|
-
type: "Class",
|
65
|
-
value: "com.wix.detox.Detox"
|
66
|
-
},
|
67
|
-
method: "extractInitialIntent",
|
68
|
-
args: []
|
69
|
-
};
|
70
|
-
}
|
71
|
-
|
72
61
|
static getAppContext() {
|
73
62
|
return {
|
74
63
|
target: {
|
@@ -1 +0,0 @@
|
|
1
|
-
3d0b64bdd6e7a436ee911d1418503a6d
|
@@ -1 +0,0 @@
|
|
1
|
-
6635f90d741216b5aa76b5032514ba9784e4c671
|
package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.sha256
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
b4b6831643b10e07a874aa90546f704478697908361c10679b4fb03f070ea287
|
package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-javadoc.jar.sha512
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
335d6a60ba8ac361a6404f631e0a2b1ba07a1e823dfe606fc35d28100516bd2a0eb727097d9c648b801192d6f5a0fcc61c6435a8e459ba0c7d83de435af4b255
|
@@ -1 +0,0 @@
|
|
1
|
-
f5c0348c6cf33679d63e5f79a4cb7be9
|
@@ -1 +0,0 @@
|
|
1
|
-
4289a96b2a89d2d1ac3299142c65d7cbe7f7126d
|
package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.sha256
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
e8f3230b45eb8950baa3400408ef9e21a5d0d61275fb63bffdfa11f97298a68f
|
package/Detox-android/com/wix/detox/20.14.4-smoke.0/detox-20.14.4-smoke.0-sources.jar.sha512
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
f3420efb7574cee763513971f8a6753d72ad2aa47a479a825f321ae8c3bf98680b42bf5d9c1c37edcf6aa8528581a65ac8ee2ea0ef0f04682a5c693d2397eb62
|
Binary file
|
@@ -1 +0,0 @@
|
|
1
|
-
070f7c4048400fe1d6b1599414f5c7f1
|
@@ -1 +0,0 @@
|
|
1
|
-
52ebf8f7cd97ab4d28216ce8504635be1f74b57c
|
@@ -1 +0,0 @@
|
|
1
|
-
42299d1835b5db9fe3b7523d2d656a8834fff583ae82521ff69b9e050814ce3a
|
@@ -1 +0,0 @@
|
|
1
|
-
aeecbc2448822395dc7d9674c0a30f5cffd9cacd8361bd55a1a4f0bb8cafe82cb812fbe1da890395cfcc65439dcb4666e119a356a054c582cb7dfe225fb9d858
|
@@ -1 +0,0 @@
|
|
1
|
-
0fc89c4edda6315cb57a7cf8e97f90dc
|
@@ -1 +0,0 @@
|
|
1
|
-
f3fe5b9e1063318f207d7c185d19ecbe21a84f6d
|
@@ -1 +0,0 @@
|
|
1
|
-
ba3399fb186167a3d399cb00c12f39db8597fc00c5ca269e6ae98fd8af8dd4eb
|
@@ -1 +0,0 @@
|
|
1
|
-
34e9d1dc0267749af9e4cba6899b3c75e0275f16edca353e9d52fbc07a8f1582aeebead081595c7794fd8bbb37680870e7281a9f4d249be3de73dec508a41ce8
|