detox 20.12.2 → 20.14.0-smoke.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.12.2/detox-20.12.2-javadoc.jar → 20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar} +0 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.12.2/detox-20.12.2-sources.jar → 20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar} +0 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha512 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar +0 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha512 +1 -0
- package/Detox-android/com/wix/detox/{20.12.2/detox-20.12.2.pom → 20.14.0-smoke.0/detox-20.14.0-smoke.0.pom} +1 -1
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.md5 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.sha1 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.sha256 +1 -0
- package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.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/src/full/java/com/wix/detox/ActivityLaunchHelper.kt +76 -0
- package/android/detox/src/full/java/com/wix/detox/Detox.java +8 -64
- package/android/detox/src/full/java/com/wix/detox/DetoxMain.kt +58 -16
- package/android/detox/src/full/java/com/wix/detox/LaunchIntentsFactory.kt +1 -1
- package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionHandlers.kt +15 -4
- 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 +28 -21
- package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -3
- package/local-cli/reset-lock-file.js +5 -9
- package/package.json +5 -6
- package/runners/jest/testEnvironment/index.js +1 -1
- package/src/DetoxWorker.js +5 -11
- package/src/android/espressoapi/Detox.js +0 -11
- package/src/artifacts/providers/index.js +3 -3
- package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +0 -17
- package/src/configuration/composeLoggerConfig.js +1 -0
- package/src/devices/allocation/DeviceAllocator.js +66 -20
- package/src/devices/allocation/DeviceList.js +44 -0
- package/src/devices/allocation/DeviceRegistry.js +189 -0
- package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
- package/src/devices/{common/drivers/android/tools → allocation/drivers/android}/FreeDeviceFinder.js +11 -10
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +22 -17
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +97 -38
- package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +32 -45
- package/src/devices/allocation/drivers/android/emulator/FreeEmulatorFinder.js +1 -1
- package/src/devices/allocation/drivers/android/emulator/FreePortFinder.js +37 -0
- package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +3 -3
- package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +104 -32
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +40 -31
- package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +121 -0
- package/src/devices/allocation/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +24 -0
- package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
- package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyInstance.js +83 -0
- package/src/devices/allocation/drivers/android/genycloud/services/dto/GenyRecipe.js +25 -0
- package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +94 -51
- package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +11 -7
- package/src/devices/allocation/drivers/ios/SimulatorQuery.js +24 -0
- package/src/devices/allocation/factories/android.js +29 -35
- package/src/devices/allocation/factories/ios.js +7 -5
- package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
- package/src/devices/common/drivers/android/cookies.d.ts +11 -0
- package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +17 -5
- package/src/devices/common/drivers/android/exec/ADB.js +1 -0
- package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
- package/src/devices/cookies/index.js +0 -6
- package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
- package/src/devices/runtime/factories/android.js +3 -11
- package/src/devices/runtime/factories/ios.js +3 -2
- package/src/{servicelocator → devices/servicelocator}/android/emulatorServiceLocator.js +1 -1
- package/src/devices/servicelocator/android/genycloudServiceLocator.js +17 -0
- package/src/devices/servicelocator/android/index.js +23 -0
- package/src/{validation → devices/validation}/EnvironmentValidatorBase.js +1 -0
- package/src/{validation → devices/validation}/android/GenycloudEnvValidator.js +2 -2
- package/src/{validation → devices/validation}/factories/index.js +1 -1
- package/src/{validation → devices/validation}/ios/IosSimulatorEnvValidator.js +2 -2
- package/src/environmentFactory.js +1 -11
- package/src/ipc/IPCClient.js +17 -1
- package/src/ipc/IPCServer.js +27 -1
- package/src/logger/DetoxLogger.js +2 -2
- package/src/realms/DetoxContext.js +6 -0
- package/src/realms/DetoxPrimaryContext.js +42 -42
- package/src/realms/DetoxSecondaryContext.js +19 -0
- package/src/realms/symbols.js +4 -0
- package/src/utils/PIDService.js +27 -0
- package/src/utils/environment.js +8 -15
- package/src/utils/errorUtils.js +2 -2
- package/tsconfig.json +5 -3
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-javadoc.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-javadoc.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-javadoc.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-javadoc.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-sources.jar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-sources.jar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-sources.jar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2-sources.jar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.aar +0 -0
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.aar.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.aar.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.aar.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.aar.sha512 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.pom.md5 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.pom.sha1 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.pom.sha256 +0 -1
- package/Detox-android/com/wix/detox/20.12.2/detox-20.12.2.pom.sha512 +0 -1
- package/src/devices/DeviceRegistry.js +0 -176
- package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -30
- package/src/devices/allocation/drivers/android/attached/AttachedAndroidLauncher.js +0 -13
- package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +0 -72
- package/src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory.js +0 -16
- package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +0 -65
- package/src/devices/common/drivers/DeviceAllocationHelper.js +0 -20
- package/src/devices/common/drivers/DeviceLauncher.js +0 -19
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLifecycleService.js +0 -25
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceLookupService.js +0 -38
- package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +0 -14
- package/src/devices/common/drivers/android/genycloud/services/dto/GenyInstance.js +0 -66
- package/src/devices/common/drivers/android/genycloud/services/dto/GenyRecipe.js +0 -13
- package/src/devices/cookies/AndroidDeviceCookie.js +0 -13
- package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
- package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
- package/src/devices/cookies/DeviceCookie.js +0 -4
- package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -20
- package/src/devices/cookies/IosCookie.js +0 -6
- package/src/devices/cookies/IosSimulatorCookie.js +0 -10
- package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +0 -71
- package/src/devices/lifecycle/factories/GenyGlobalLifecycleHandlerFactory.js +0 -18
- package/src/servicelocator/android/genycloudServiceLocator.js +0 -21
- package/src/servicelocator/android/index.js +0 -25
- package/src/servicelocator/ios.js +0 -7
- /package/src/devices/{common → allocation}/drivers/android/genycloud/exec/GenyCloudExec.js +0 -0
- /package/src/devices/{common → allocation}/drivers/android/genycloud/services/GenyAuthService.js +0 -0
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
0c2bae26c123edf10cb62b77d5e5acdd
|
@@ -0,0 +1 @@
|
|
1
|
+
96b7351396c83931de86925d213b5bc9d12a827d
|
@@ -0,0 +1 @@
|
|
1
|
+
dbe5afc9df9a7c857a961781ebd58be8cf1d82c39771819b6c801f36b44434d4
|
@@ -0,0 +1 @@
|
|
1
|
+
8e4f2278448ac644826386e11b95b24f44037c1483f0bae0c1347dfc0a01783e058f9b229b5d9e217f8be08984ff0035a8a9a028503f672f2baff523d3dc037c
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
4db28745d12fb52a9b94eefe7aef7c6d
|
@@ -0,0 +1 @@
|
|
1
|
+
5101597e82e164ba10f7ecd0e15ee7a4316fdccc
|
@@ -0,0 +1 @@
|
|
1
|
+
e7bc12d7cbefc0831194c059a2b62166bfda3a63e9e34d212418eed88155462f
|
@@ -0,0 +1 @@
|
|
1
|
+
6cc5ce462ef6068c314ffa8d8a06d6c091b819baa7d3d1b329bd6a907e3c7909db097fac66381b3833bbfcb3bd1226f5c1e511cad080b1e2a3a914ff91af6f61
|
@@ -0,0 +1 @@
|
|
1
|
+
b8569c6d3b296face8b6d34037e27b6e
|
@@ -0,0 +1 @@
|
|
1
|
+
fe831778fa7fbeffb2ccdbb15bf3200ec0e641b2
|
@@ -0,0 +1 @@
|
|
1
|
+
305c99310501d83ad114e4357d1af6efccf8ff774ec5ad25a04f7d9921203225
|
@@ -0,0 +1 @@
|
|
1
|
+
f02ad136e06b87c385b1ec7d8d9ad27259cdd2f9eec6dae79eb79eb9e7e78614b55bbb33773da61990ea5e594b0dff92c8013f5d3687c9c04710916e95d70418
|
@@ -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.
|
6
|
+
<version>20.14.0-smoke.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
|
+
84130ea1d35084f1db1652765a011da8
|
@@ -0,0 +1 @@
|
|
1
|
+
0dc75a3ca7a62dadea9abdd8c20d8cade91ff0ad
|
@@ -0,0 +1 @@
|
|
1
|
+
cc11f65f610d8f9cc708b0295e6998ee7e819ae7dc34d9f54586790ee253d4b2
|
@@ -0,0 +1 @@
|
|
1
|
+
592a6a8c132c98bb7e7cb531ec495cb83bd4bc004fd8388f361199359c293d10169e9af1a771efd9d79db0e9e65d2dd75cb3d4aa9b32909c01dc561368165ea0
|
@@ -3,11 +3,11 @@
|
|
3
3
|
<groupId>com.wix</groupId>
|
4
4
|
<artifactId>detox</artifactId>
|
5
5
|
<versioning>
|
6
|
-
<latest>20.
|
7
|
-
<release>20.
|
6
|
+
<latest>20.14.0-smoke.0</latest>
|
7
|
+
<release>20.14.0-smoke.0</release>
|
8
8
|
<versions>
|
9
|
-
<version>20.
|
9
|
+
<version>20.14.0-smoke.0</version>
|
10
10
|
</versions>
|
11
|
-
<lastUpdated>
|
11
|
+
<lastUpdated>20231004101112</lastUpdated>
|
12
12
|
</versioning>
|
13
13
|
</metadata>
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
db9bf329cefd7a3174b46ce70f497a99
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2166ac54d8a199afca7309e193e586480014f074
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
d872213b54196e083fdfac1b0f921ba338e96aa4d21e1971ac9f8e70cd20003c
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1ca24fd031e6a4bd8ac6197a4ff263b33a25a60b075291dac8ea33c8127623a8dbf65462f9e65d77ce493f1a2f07e09fbb5e9219e52e8ed457a3c293a86b118b
|
package/Detox-ios-src.tbz
CHANGED
Binary file
|
package/Detox-ios.tbz
CHANGED
Binary file
|
@@ -0,0 +1,76 @@
|
|
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(private val activityTestRule: ActivityTestRule<*>) {
|
10
|
+
|
11
|
+
private val launchArgs = LaunchArgs()
|
12
|
+
private val intentsFactory = LaunchIntentsFactory()
|
13
|
+
|
14
|
+
fun launchActivityUnderTest() {
|
15
|
+
val intent = extractInitialIntent()
|
16
|
+
activityTestRule.launchActivity(intent)
|
17
|
+
}
|
18
|
+
|
19
|
+
fun launchMainActivity() {
|
20
|
+
val activity = activityTestRule.activity
|
21
|
+
launchActivitySync(intentsFactory.activityLaunchIntent(activity))
|
22
|
+
}
|
23
|
+
|
24
|
+
fun startActivityFromUrl(url: String) {
|
25
|
+
launchActivitySync(intentsFactory.intentWithUrl(url, false))
|
26
|
+
}
|
27
|
+
|
28
|
+
fun startActivityFromNotification(dataFilePath: String) {
|
29
|
+
val notificationData = NotificationDataParser(dataFilePath!!).toBundle()
|
30
|
+
val intent = intentsFactory.intentWithNotificationData(appContext, notificationData, false)
|
31
|
+
launchActivitySync(intent)
|
32
|
+
}
|
33
|
+
|
34
|
+
private fun extractInitialIntent(): Intent =
|
35
|
+
if (launchArgs.hasUrlOverride()) {
|
36
|
+
intentsFactory.intentWithUrl(launchArgs.urlOverride, true)
|
37
|
+
} else if (launchArgs.hasNotificationPath()) {
|
38
|
+
val notificationData = NotificationDataParser(launchArgs.notificationPath).toBundle()
|
39
|
+
intentsFactory.intentWithNotificationData(appContext, notificationData, true)
|
40
|
+
} else {
|
41
|
+
intentsFactory.cleanIntent()
|
42
|
+
}.also {
|
43
|
+
it.putExtra(INTENT_LAUNCH_ARGS_KEY, launchArgs.asIntentBundle())
|
44
|
+
}
|
45
|
+
|
46
|
+
private fun launchActivitySync(intent: Intent) {
|
47
|
+
// Ideally, we would just call sActivityTestRule.launchActivity(intent) and get it over with.
|
48
|
+
// BUT!!! as it turns out, Espresso has an issue where doing this for an activity running in the background
|
49
|
+
// would have Espresso set up an ActivityMonitor which will spend its time waiting for the activity to load, *without
|
50
|
+
// ever being released*. It will finally fail after a 45 seconds timeout.
|
51
|
+
// Without going into full details, it seems that activity test rules were not meant to be used this way. However,
|
52
|
+
// the all-new ActivityScenario implementation introduced in androidx could probably support this (e.g. by using
|
53
|
+
// dedicated methods such as moveToState(), which give better control over the lifecycle).
|
54
|
+
// In any case, this is the core reason for this issue: https://github.com/wix/Detox/issues/1125
|
55
|
+
// What it forces us to do, then, is this -
|
56
|
+
// 1. Launch the activity by "ourselves" from the OS (i.e. using context.startActivity()).
|
57
|
+
// 2. Set up an activity monitor by ourselves -- such that it would block until the activity is ready.
|
58
|
+
// ^ Hence the code below.
|
59
|
+
val activity = activityTestRule.activity
|
60
|
+
val activityMonitor = ActivityMonitor(activity.javaClass.name, null, true)
|
61
|
+
activity.startActivity(intent)
|
62
|
+
|
63
|
+
InstrumentationRegistry.getInstrumentation().run {
|
64
|
+
addMonitor(activityMonitor)
|
65
|
+
waitForMonitorWithTimeout(activityMonitor, ACTIVITY_LAUNCH_TIMEOUT)
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
private val appContext: Context
|
70
|
+
get() = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
|
71
|
+
|
72
|
+
companion object {
|
73
|
+
private const val INTENT_LAUNCH_ARGS_KEY = "launchArgs"
|
74
|
+
private const val ACTIVITY_LAUNCH_TIMEOUT = 10000L
|
75
|
+
}
|
76
|
+
}
|
@@ -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,15 +122,10 @@ 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);
|
125
|
+
sActivityLaunchHelper = new ActivityLaunchHelper(activityTestRule);
|
141
126
|
|
142
127
|
try {
|
143
|
-
DetoxMain.run(context);
|
128
|
+
DetoxMain.run(context, sActivityLaunchHelper);
|
144
129
|
} catch (Exception e) {
|
145
130
|
Thread.currentThread().interrupt();
|
146
131
|
throw new RuntimeException("Detox got interrupted prematurely", e);
|
@@ -148,56 +133,15 @@ public final class Detox {
|
|
148
133
|
}
|
149
134
|
|
150
135
|
public static void launchMainActivity() {
|
151
|
-
|
152
|
-
launchActivitySync(sIntentsFactory.activityLaunchIntent(activity));
|
136
|
+
sActivityLaunchHelper.launchMainActivity();
|
153
137
|
}
|
154
138
|
|
155
139
|
public static void startActivityFromUrl(String url) {
|
156
|
-
|
140
|
+
sActivityLaunchHelper.startActivityFromUrl(url);
|
157
141
|
}
|
158
142
|
|
159
143
|
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);
|
144
|
+
sActivityLaunchHelper.startActivityFromNotification(dataFilePath);
|
201
145
|
}
|
202
146
|
|
203
147
|
private static Context getAppContext() {
|
@@ -2,8 +2,21 @@ package com.wix.detox
|
|
2
2
|
|
3
3
|
import android.content.Context
|
4
4
|
import android.util.Log
|
5
|
-
import com.wix.detox.adapters.server
|
6
|
-
import com.wix.detox.
|
5
|
+
import com.wix.detox.adapters.server.CleanupActionHandler
|
6
|
+
import com.wix.detox.adapters.server.DetoxActionHandler
|
7
|
+
import com.wix.detox.adapters.server.DetoxActionsDispatcher
|
8
|
+
import com.wix.detox.adapters.server.DetoxServerAdapter
|
9
|
+
import com.wix.detox.adapters.server.DetoxServerInfo
|
10
|
+
import com.wix.detox.adapters.server.InstrumentsEventsActionsHandler
|
11
|
+
import com.wix.detox.adapters.server.InstrumentsRecordingStateActionHandler
|
12
|
+
import com.wix.detox.adapters.server.InvokeActionHandler
|
13
|
+
import com.wix.detox.adapters.server.OutboundServerAdapter
|
14
|
+
import com.wix.detox.adapters.server.PrematureReadyHandler
|
15
|
+
import com.wix.detox.adapters.server.QueryStatusActionHandler
|
16
|
+
import com.wix.detox.adapters.server.ReactNativeReloadActionHandler
|
17
|
+
import com.wix.detox.adapters.server.ReadyActionHandler
|
18
|
+
import com.wix.detox.common.DetoxLog
|
19
|
+
import com.wix.detox.espresso.UiControllerSpy
|
7
20
|
import com.wix.detox.instruments.DetoxInstrumentsManager
|
8
21
|
import com.wix.detox.reactnative.ReactNativeExtension
|
9
22
|
import com.wix.invoke.MethodInvocation
|
@@ -14,24 +27,28 @@ private const val TERMINATION_ACTION = "_terminate"
|
|
14
27
|
|
15
28
|
object DetoxMain {
|
16
29
|
@JvmStatic
|
17
|
-
fun run(rnHostHolder: Context) {
|
30
|
+
fun run(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
|
18
31
|
val detoxServerInfo = DetoxServerInfo()
|
19
|
-
Log.i(LOG_TAG, "Detox server connection details: $detoxServerInfo")
|
20
|
-
|
21
32
|
val testEngineFacade = TestEngineFacade()
|
22
33
|
val actionsDispatcher = DetoxActionsDispatcher()
|
23
34
|
val externalAdapter = DetoxServerAdapter(actionsDispatcher, detoxServerInfo, IS_READY_ACTION, TERMINATION_ACTION)
|
24
|
-
|
35
|
+
|
36
|
+
initActionHandlers(activityLaunchHelper, actionsDispatcher, externalAdapter, testEngineFacade, rnHostHolder)
|
25
37
|
actionsDispatcher.dispatchAction(INIT_ACTION, "", 0)
|
26
38
|
actionsDispatcher.join()
|
27
39
|
}
|
28
40
|
|
29
|
-
private fun doInit(externalAdapter: DetoxServerAdapter
|
30
|
-
externalAdapter.connect()
|
31
|
-
|
41
|
+
private fun doInit(externalAdapter: DetoxServerAdapter) {
|
32
42
|
initCrashHandler(externalAdapter)
|
33
43
|
initANRListener(externalAdapter)
|
34
|
-
|
44
|
+
initEspresso()
|
45
|
+
initReactNative()
|
46
|
+
|
47
|
+
externalAdapter.connect()
|
48
|
+
}
|
49
|
+
|
50
|
+
private fun onConnected(activityLaunchHelper: ActivityLaunchHelper, rnHostHolder: Context) {
|
51
|
+
launchApp(rnHostHolder, activityLaunchHelper)
|
35
52
|
}
|
36
53
|
|
37
54
|
private fun doTeardown(serverAdapter: DetoxServerAdapter, actionsDispatcher: DetoxActionsDispatcher, testEngineFacade: TestEngineFacade) {
|
@@ -41,20 +58,35 @@ object DetoxMain {
|
|
41
58
|
actionsDispatcher.teardown()
|
42
59
|
}
|
43
60
|
|
44
|
-
private fun initActionHandlers(actionsDispatcher: DetoxActionsDispatcher, serverAdapter: DetoxServerAdapter, testEngineFacade: TestEngineFacade, rnHostHolder: Context) {
|
61
|
+
private fun initActionHandlers(activityLaunchHelper: ActivityLaunchHelper, actionsDispatcher: DetoxActionsDispatcher, serverAdapter: DetoxServerAdapter, testEngineFacade: TestEngineFacade, rnHostHolder: Context) {
|
45
62
|
// Primary actions
|
46
63
|
with(actionsDispatcher) {
|
64
|
+
var prematureIsReadyHandler: PrematureReadyHandler? = PrematureReadyHandler()
|
47
65
|
val rnReloadHandler = ReactNativeReloadActionHandler(rnHostHolder, serverAdapter, testEngineFacade)
|
48
66
|
|
49
|
-
associateActionHandler(INIT_ACTION, object
|
67
|
+
associateActionHandler(INIT_ACTION, object: DetoxActionHandler {
|
50
68
|
override fun handle(params: String, messageId: Long) =
|
51
69
|
synchronized(this@DetoxMain) {
|
52
|
-
this@DetoxMain.doInit(serverAdapter
|
70
|
+
this@DetoxMain.doInit(serverAdapter)
|
53
71
|
}
|
54
72
|
})
|
55
|
-
associateActionHandler(IS_READY_ACTION,
|
73
|
+
associateActionHandler(IS_READY_ACTION, prematureIsReadyHandler!!)
|
56
74
|
|
57
|
-
associateActionHandler("loginSuccess",
|
75
|
+
associateActionHandler("loginSuccess", object: DetoxActionHandler {
|
76
|
+
override fun handle(params: String, messageId: Long) {
|
77
|
+
synchronized(this@DetoxMain) {
|
78
|
+
this@DetoxMain.onConnected(activityLaunchHelper, rnHostHolder)
|
79
|
+
associateActionHandler(IS_READY_ACTION, ReadyActionHandler(serverAdapter, testEngineFacade))
|
80
|
+
|
81
|
+
prematureIsReadyHandler?.let {
|
82
|
+
if (it.isActionPending) {
|
83
|
+
actionsDispatcher.dispatchAction(IS_READY_ACTION, it.params!!, it.messageId!!)
|
84
|
+
}
|
85
|
+
prematureIsReadyHandler = null
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
})
|
58
90
|
associateActionHandler("reactNativeReload", object: DetoxActionHandler {
|
59
91
|
override fun handle(params: String, messageId: Long) =
|
60
92
|
synchronized(this@DetoxMain) {
|
@@ -98,7 +130,17 @@ object DetoxMain {
|
|
98
130
|
DetoxANRHandler(outboundServerAdapter).attach()
|
99
131
|
}
|
100
132
|
|
101
|
-
private fun
|
133
|
+
private fun initEspresso() {
|
134
|
+
UiControllerSpy.attachThroughProxy()
|
135
|
+
}
|
136
|
+
|
137
|
+
private fun initReactNative() {
|
138
|
+
ReactNativeExtension.initIfNeeded()
|
139
|
+
}
|
140
|
+
|
141
|
+
private fun launchApp(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
|
142
|
+
Log.i(DetoxLog.LOG_TAG, "Launching the tested activity!")
|
143
|
+
activityLaunchHelper.launchActivityUnderTest()
|
102
144
|
ReactNativeExtension.waitForRNBootstrap(rnHostHolder)
|
103
145
|
}
|
104
146
|
}
|
@@ -3,6 +3,7 @@ package com.wix.detox.adapters.server
|
|
3
3
|
import android.content.Context
|
4
4
|
import android.util.Log
|
5
5
|
import com.wix.detox.TestEngineFacade
|
6
|
+
import com.wix.detox.common.DetoxLog
|
6
7
|
import com.wix.detox.common.extractRootCause
|
7
8
|
import com.wix.detox.instruments.DetoxInstrumentsException
|
8
9
|
import com.wix.detox.instruments.DetoxInstrumentsManager
|
@@ -27,6 +28,20 @@ class ReadyActionHandler(
|
|
27
28
|
}
|
28
29
|
}
|
29
30
|
|
31
|
+
class PrematureReadyHandler(): DetoxActionHandler {
|
32
|
+
var isActionPending = false
|
33
|
+
var params: String? = null
|
34
|
+
var messageId: Long? = null
|
35
|
+
|
36
|
+
override fun handle(params: String, messageId: Long) {
|
37
|
+
Log.i(DetoxLog.LOG_TAG, "Got a premature ready action, saving for later...")
|
38
|
+
|
39
|
+
this.isActionPending = true
|
40
|
+
this.params = params
|
41
|
+
this.messageId = messageId
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
30
45
|
open class ReactNativeReloadActionHandler(
|
31
46
|
private val appContext: Context,
|
32
47
|
private val outboundServerAdapter: OutboundServerAdapter,
|
@@ -152,7 +167,3 @@ class InstrumentsEventsActionsHandler(
|
|
152
167
|
outboundServerAdapter.sendMessage("eventDone", emptyMap<String, Any>(), messageId)
|
153
168
|
}
|
154
169
|
}
|
155
|
-
|
156
|
-
class ScarceActionHandler: DetoxActionHandler {
|
157
|
-
override fun handle(params: String, messageId: Long) {}
|
158
|
-
}
|
@@ -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,32 @@ 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
|
+
hackRN50WaitForReady()
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
17
43
|
/**
|
18
44
|
* Reloads the React Native context and thus all javascript code.
|
19
45
|
*
|
@@ -40,26 +66,7 @@ object ReactNativeExtension {
|
|
40
66
|
val reactContext = awaitNewReactNativeContext(it, previousReactContext)
|
41
67
|
|
42
68
|
enableOrDisableSynchronization(reactContext, networkSyncEnabled)
|
43
|
-
|
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()
|
69
|
+
hackRN50WaitForReady()
|
63
70
|
}
|
64
71
|
}
|
65
72
|
|
@@ -145,7 +152,7 @@ object ReactNativeExtension {
|
|
145
152
|
}
|
146
153
|
}
|
147
154
|
|
148
|
-
private fun
|
155
|
+
private fun hackRN50WaitForReady() {
|
149
156
|
if (ReactNativeInfo.rnVersion().minor in 50..62) {
|
150
157
|
try {
|
151
158
|
//TODO- Temp hack to make Detox usable for RN>=50 till we find a better sync solution.
|
@@ -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
|
|
@@ -1,16 +1,12 @@
|
|
1
1
|
const { log } = require('../internals');
|
2
|
-
const DeviceRegistry = require('../src/devices/DeviceRegistry');
|
3
|
-
const { getDetoxLibraryRootPath } = require('../src/utils/environment');
|
4
|
-
|
2
|
+
const DeviceRegistry = require('../src/devices/allocation/DeviceRegistry');
|
5
3
|
|
6
4
|
module.exports.command = 'reset-lock-file';
|
7
|
-
module.exports.desc = 'Resets
|
5
|
+
module.exports.desc = 'Resets Detox lock file completely - all devices are marked as available after that.';
|
8
6
|
|
9
7
|
module.exports.handler = async function resetLockFile() {
|
10
|
-
|
11
|
-
|
12
|
-
DeviceRegistry.forAndroid().reset(),
|
13
|
-
]);
|
8
|
+
const registry = new DeviceRegistry();
|
9
|
+
await registry.reset();
|
14
10
|
|
15
|
-
log.info(`Cleaned lock
|
11
|
+
log.info(`Cleaned lock file at: ${registry.lockFilePath}`);
|
16
12
|
};
|