detox 20.13.5 → 20.14.0-prerelease.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. package/Detox-android/com/wix/detox/{20.13.5/detox-20.13.5-javadoc.jar → 20.14.0-prerelease.0/detox-20.14.0-prerelease.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.13.5/detox-20.13.5-sources.jar → 20.14.0-prerelease.0/detox-20.14.0-prerelease.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.13.5/detox-20.13.5.pom → 20.14.0-prerelease.0/detox-20.14.0-prerelease.0.pom} +1 -1
  17. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.14.0-prerelease.0/detox-20.14.0-prerelease.0.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/android/detox/src/full/java/com/wix/detox/ActivityLaunchHelper.kt +76 -0
  29. package/android/detox/src/full/java/com/wix/detox/Detox.java +8 -64
  30. package/android/detox/src/full/java/com/wix/detox/DetoxMain.kt +53 -33
  31. package/android/detox/src/full/java/com/wix/detox/LaunchIntentsFactory.kt +1 -1
  32. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionHandlers.kt +0 -4
  33. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionsDispatcher.kt +7 -3
  34. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxServerAdapter.kt +0 -2
  35. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxServerInfo.kt +4 -2
  36. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactMarkersLogger.kt +44 -0
  37. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +28 -22
  38. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -3
  39. package/detox.d.ts +7 -0
  40. package/internals.d.ts +2 -1
  41. package/local-cli/testCommand/TestRunnerCommand.js +26 -3
  42. package/local-cli/utils/interruptListeners.js +15 -0
  43. package/package.json +3 -3
  44. package/runners/jest/testEnvironment/index.js +7 -1
  45. package/src/android/espressoapi/Detox.js +0 -11
  46. package/src/configuration/composeRunnerConfig.js +3 -1
  47. package/src/ipc/IPCClient.js +2 -2
  48. package/src/ipc/IPCServer.js +5 -3
  49. package/src/realms/DetoxContext.js +1 -1
  50. package/src/realms/DetoxPrimaryContext.js +2 -2
  51. package/src/realms/DetoxSecondaryContext.js +2 -2
  52. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-javadoc.jar.md5 +0 -1
  53. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-javadoc.jar.sha1 +0 -1
  54. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-javadoc.jar.sha256 +0 -1
  55. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-javadoc.jar.sha512 +0 -1
  56. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-sources.jar.md5 +0 -1
  57. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-sources.jar.sha1 +0 -1
  58. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-sources.jar.sha256 +0 -1
  59. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5-sources.jar.sha512 +0 -1
  60. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.aar +0 -0
  61. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.aar.md5 +0 -1
  62. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.aar.sha1 +0 -1
  63. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.aar.sha256 +0 -1
  64. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.aar.sha512 +0 -1
  65. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.pom.md5 +0 -1
  66. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.pom.sha1 +0 -1
  67. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.pom.sha256 +0 -1
  68. package/Detox-android/com/wix/detox/20.13.5/detox-20.13.5.pom.sha512 +0 -1
@@ -0,0 +1 @@
1
+ 3530c43ea00d627580747ee9f0d5863ca9813f37
@@ -0,0 +1 @@
1
+ 8e1b2ec062f53625f04682a7680f945a735f5ce1398779fc75053e06552d1df5
@@ -0,0 +1 @@
1
+ 609e6c6a9432b4e1ef6a4e0cce31001a69ea5fb95ea2396be34732e5e1cc80accb647c5c9003827cf69754918a3a814deb24d27f14047a3aa6297c92b764ef03
@@ -0,0 +1 @@
1
+ c2dffdb56581b4c26ed98b6775e222e1a4486c5e
@@ -0,0 +1 @@
1
+ c9a52d8a32ecbc37230bcdbb9a4aa67411ca950311e5de327ec44694d77c8872
@@ -0,0 +1 @@
1
+ 402fd90cfcfc8ee4f7faa04e7915ab6f24580ef704dbe0b835bae434abe4bf749987cb7fcc52b6a1f7557275a3ca5e0205438aef2934966948dfdaa66335a162
@@ -0,0 +1 @@
1
+ e4d79ca2a269e97059c4321c69b89508
@@ -0,0 +1 @@
1
+ a5f8cbcf67d3d87d5036eb6f48372962c64dd12b
@@ -0,0 +1 @@
1
+ b2459b4c1286baf4f608be3ec55a46688c92ab1a95d840769a3519b4f75c2ea4
@@ -0,0 +1 @@
1
+ 60375b1df9ce89baea8fb435985d83d2fde2a8013f3b12fb1d3e3391ef7ac14e98d10eff9b27fd44acc753c7764244fcb0d9934ce97c4beb534102247a9962f0
@@ -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.13.5</version>
6
+ <version>20.14.0-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
+ 1e365cca25c5a49f1bf610fd76df8ff0
@@ -0,0 +1 @@
1
+ 6f1a93a3247a829d64f63a67830adc742dfef0b9
@@ -0,0 +1 @@
1
+ c2745e1391bb64bed726bf43a1f624f79d13f0a2c7e4ccd9838b64df40d1e3ee
@@ -0,0 +1 @@
1
+ ca4428ae0cdffbf5bb7967d24f29486735a29ee89bad794bfa451f12467744f48bab8a7adac1fdb73426951aec461ccf3bae0396994c6e4711d1ff347e85369b
@@ -3,11 +3,11 @@
3
3
  <groupId>com.wix</groupId>
4
4
  <artifactId>detox</artifactId>
5
5
  <versioning>
6
- <latest>20.13.5</latest>
7
- <release>20.13.5</release>
6
+ <latest>20.14.0-prerelease.0</latest>
7
+ <release>20.14.0-prerelease.0</release>
8
8
  <versions>
9
- <version>20.13.5</version>
9
+ <version>20.14.0-prerelease.0</version>
10
10
  </versions>
11
- <lastUpdated>20231031123136</lastUpdated>
11
+ <lastUpdated>20231206150336</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 8e252c6a41f82c0f28319398cbe2271b
1
+ 374b144f9306034184388c9579fcda60
@@ -1 +1 @@
1
- 3cabac25c64bf47e471ec9f665e64b864120fd95
1
+ aeb72dae3a76fd71e383c8b1bbc7871bf39b5424
@@ -1 +1 @@
1
- 759c7898b0ee76e88b9a3ef8ef5de8554fbf03d353fe056655cdb78349ebc820
1
+ 94e4275040ab622783723cea7783afc664a6b9759ea43e8d3c57b48e1eb34290
@@ -1 +1 @@
1
- 823153db733db6842218f0694b986684eaa0c78d8866eadb09f047b3f201a6dbf52d0c9f3a58d159e1511f34e46c19fa14538bf4679eae61dc9137e00b416311
1
+ 8ed181a738180833c36cf5066afb55082d4067c3924e5f240deef147ee818058a09ad14f3a2800cb46538e67872fd79b8437561b37eadd9e2f9f7d38b5454285
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 final String INTENT_LAUNCH_ARGS_KEY = "launchArgs";
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
- sActivityTestRule = activityTestRule;
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
- final Activity activity = sActivityTestRule.getActivity();
152
- launchActivitySync(sIntentsFactory.activityLaunchIntent(activity));
136
+ sActivityLaunchHelper.launchMainActivity();
153
137
  }
154
138
 
155
139
  public static void startActivityFromUrl(String url) {
156
- launchActivitySync(sIntentsFactory.intentWithUrl(url, false));
140
+ sActivityLaunchHelper.startActivityFromUrl(url);
157
141
  }
158
142
 
159
143
  public static void startActivityFromNotification(String dataFilePath) {
160
- Bundle notificationData = new NotificationDataParser(dataFilePath).toBundle();
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() {
@@ -3,35 +3,50 @@ 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.Companion.LOG_TAG
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 loginMonitor = 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 externalAdapter = DetoxServerAdapter(actionsDispatcher, detoxServerInfo, IS_READY_ACTION, TERMINATION_ACTION)
23
+ val externalAdapter = DetoxServerAdapter(actionsDispatcher, detoxServerInfo, TERMINATION_ACTION)
24
+
24
25
  initActionHandlers(actionsDispatcher, externalAdapter, testEngineFacade, rnHostHolder)
25
- actionsDispatcher.dispatchAction(INIT_ACTION, "", 0)
26
+ // actionsDispatcher.dispatchAction(INIT_ACTION, "", 0)
27
+ init(externalAdapter)
28
+ synchronized(this) {
29
+ awaitHandshake()
30
+ launchApp(rnHostHolder, activityLaunchHelper)
31
+ }
26
32
  actionsDispatcher.join()
27
33
  }
28
34
 
29
- private fun doInit(externalAdapter: DetoxServerAdapter, rnHostHolder: Context) {
30
- externalAdapter.connect()
31
-
35
+ private fun init(externalAdapter: DetoxServerAdapter) {
32
36
  initCrashHandler(externalAdapter)
33
37
  initANRListener(externalAdapter)
34
- initReactNativeIfNeeded(rnHostHolder)
38
+ initEspresso()
39
+ initReactNative()
40
+
41
+ externalAdapter.connect()
42
+ }
43
+
44
+ private fun awaitHandshake() {
45
+ loginMonitor.await()
46
+ }
47
+
48
+ private fun onLoginSuccess() {
49
+ loginMonitor.countDown()
35
50
  }
36
51
 
37
52
  private fun doTeardown(serverAdapter: DetoxServerAdapter, actionsDispatcher: DetoxActionsDispatcher, testEngineFacade: TestEngineFacade) {
@@ -44,32 +59,27 @@ object DetoxMain {
44
59
  private fun initActionHandlers(actionsDispatcher: DetoxActionsDispatcher, serverAdapter: DetoxServerAdapter, testEngineFacade: TestEngineFacade, rnHostHolder: Context) {
45
60
  // Primary actions
46
61
  with(actionsDispatcher) {
62
+ val readyHandler = ReadyActionHandler(serverAdapter, testEngineFacade)
47
63
  val rnReloadHandler = ReactNativeReloadActionHandler(rnHostHolder, serverAdapter, testEngineFacade)
48
64
 
49
- associateActionHandler(INIT_ACTION, object : DetoxActionHandler {
50
- override fun handle(params: String, messageId: Long) =
51
- synchronized(this@DetoxMain) {
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
- })
65
+ associateActionHandler("isReady") { params, messageId ->
66
+ synchronized(this@DetoxMain) {
67
+ readyHandler.handle(params, messageId)
68
+ }
69
+ }
70
+ associateActionHandler("loginSuccess") { _, _ -> this@DetoxMain.onLoginSuccess() }
71
+ associateActionHandler("reactNativeReload") { params, messageId ->
72
+ synchronized(this@DetoxMain) {
73
+ rnReloadHandler.handle(params, messageId)
74
+ }
75
+ }
64
76
  associateActionHandler("invoke", InvokeActionHandler(MethodInvocation(), serverAdapter))
65
77
  associateActionHandler("cleanup", CleanupActionHandler(serverAdapter, testEngineFacade) {
66
78
  dispatchAction(TERMINATION_ACTION, "", 0)
67
79
  })
68
- associateActionHandler(TERMINATION_ACTION, object: DetoxActionHandler {
69
- override fun handle(params: String, messageId: Long) {
70
- this@DetoxMain.doTeardown(serverAdapter, actionsDispatcher, testEngineFacade)
71
- }
72
- })
80
+ associateActionHandler(TERMINATION_ACTION) { _, _ ->
81
+ this@DetoxMain.doTeardown(serverAdapter, actionsDispatcher, testEngineFacade)
82
+ }
73
83
 
74
84
  if (DetoxInstrumentsManager.supports()) {
75
85
  val instrumentsManager = DetoxInstrumentsManager(rnHostHolder)
@@ -98,7 +108,17 @@ object DetoxMain {
98
108
  DetoxANRHandler(outboundServerAdapter).attach()
99
109
  }
100
110
 
101
- private fun initReactNativeIfNeeded(rnHostHolder: Context) {
111
+ private fun initEspresso() {
112
+ UiControllerSpy.attachThroughProxy()
113
+ }
114
+
115
+ private fun initReactNative() {
116
+ ReactNativeExtension.initIfNeeded()
117
+ }
118
+
119
+ private fun launchApp(rnHostHolder: Context, activityLaunchHelper: ActivityLaunchHelper) {
120
+ Log.i(DetoxLog.LOG_TAG, "Launching the tested activity!")
121
+ activityLaunchHelper.launchActivityUnderTest()
102
122
  ReactNativeExtension.waitForRNBootstrap(rnHostHolder)
103
123
  }
104
124
  }
@@ -6,7 +6,7 @@ import android.content.Intent
6
6
  import android.net.Uri
7
7
  import android.os.Bundle
8
8
 
9
- internal class LaunchIntentsFactory {
9
+ class LaunchIntentsFactory {
10
10
 
11
11
  /**
12
12
  * Constructs an intent tightly associated with a specific activity.
@@ -152,7 +152,3 @@ class InstrumentsEventsActionsHandler(
152
152
  outboundServerAdapter.sendMessage("eventDone", emptyMap<String, Any>(), messageId)
153
153
  }
154
154
  }
155
-
156
- class ScarceActionHandler: DetoxActionHandler {
157
- override fun handle(params: String, messageId: Long) {}
158
- }
@@ -16,6 +16,12 @@ class DetoxActionsDispatcher {
16
16
  actionsExecutor.associateHandler(type, actionHandler)
17
17
  }
18
18
 
19
+ fun associateActionHandler(type: String, handlerFunc: (params: String, messageId: Long) -> Unit) {
20
+ associateActionHandler(type, object: DetoxActionHandler {
21
+ override fun handle(params: String, messageId: Long) = handlerFunc(params, messageId)
22
+ })
23
+ }
24
+
19
25
  fun dispatchAction(type: String, params: String, messageId: Long) {
20
26
  (primaryExec.executeAction(type, params, messageId) ||
21
27
  secondaryExec.executeAction(type, params, messageId))
@@ -74,7 +80,5 @@ private class ActionsExecutor(name: String) {
74
80
  handler.looper.quit()
75
81
  }
76
82
 
77
- fun join() {
78
- thread.join()
79
- }
83
+ fun join() = thread.join()
80
84
  }
@@ -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
- override fun toString(): String {
13
- return "url=$serverUrl, sessionId=$sessionId"
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
- 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()
69
+ hackRN50WaitForReady()
63
70
  }
64
71
  }
65
72
 
@@ -145,7 +152,7 @@ object ReactNativeExtension {
145
152
  }
146
153
  }
147
154
 
148
- private fun hackRN50OrHigherWaitForReady() {
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.
@@ -153,7 +160,6 @@ object ReactNativeExtension {
153
160
  } catch (e: InterruptedException) {
154
161
  e.printStackTrace()
155
162
  }
156
-
157
163
  }
158
164
  }
159
165
 
@@ -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
 
package/detox.d.ts CHANGED
@@ -235,6 +235,13 @@ declare global {
235
235
  * @see {DetoxInternals.DetoxTestFileReport#isPermanentFailure}
236
236
  */
237
237
  bail?: boolean;
238
+ /**
239
+ * When true, tells `detox test` to spawn the test runner in a detached mode.
240
+ * This is useful in CI environments, where you want to intercept SIGINT and SIGTERM signals to gracefully shut down the test runner and the device.
241
+ * Instead of passing the kill signal to the child process (the test runner), Detox will send an emergency shutdown request to all the workers, and then it will wait for them to finish.
242
+ * @default false
243
+ */
244
+ detached?: boolean;
238
245
  /**
239
246
  * Custom handler to process --inspect-brk CLI flag.
240
247
  * Use it when you rely on another test runner than Jest to mutate the config.
package/internals.d.ts CHANGED
@@ -116,8 +116,9 @@ declare global {
116
116
  /**
117
117
  * Workaround for Jest exiting abruptly in --bail mode.
118
118
  * Makes sure that all workers and their test environments are properly torn down.
119
+ * @param [permanent] - forbids further retries
119
120
  */
120
- unsafe_conductEarlyTeardown(): Promise<void>;
121
+ unsafe_conductEarlyTeardown(permanent?: boolean): Promise<void>;
121
122
  /**
122
123
  * Reports to Detox CLI about passed and failed test files.
123
124
  * The failed test files might be re-run again if
@@ -12,6 +12,7 @@ const { escapeSpaces, useForwardSlashes } = require('../../src/utils/shellUtils'
12
12
  const sleep = require('../../src/utils/sleep');
13
13
  const AppStartCommand = require('../startCommand/AppStartCommand');
14
14
  const { markErrorAsLogged } = require('../utils/cliErrorHandling');
15
+ const interruptListeners = require('../utils/interruptListeners');
15
16
 
16
17
  const TestRunnerError = require('./TestRunnerError');
17
18
 
@@ -28,10 +29,12 @@ class TestRunnerCommand {
28
29
  const appsConfig = opts.config.apps;
29
30
 
30
31
  this._argv = runnerConfig.args;
32
+ this._detached = runnerConfig.detached;
31
33
  this._retries = runnerConfig.retries;
32
34
  this._envHint = this._buildEnvHint(opts.env);
33
35
  this._startCommands = this._prepareStartCommands(appsConfig, cliConfig);
34
36
  this._envFwd = {};
37
+ this._terminating = false;
35
38
 
36
39
  if (runnerConfig.forwardEnv) {
37
40
  this._envFwd = this._buildEnvOverride(cliConfig, deviceConfig);
@@ -59,16 +62,20 @@ class TestRunnerCommand {
59
62
  } catch (e) {
60
63
  launchError = e;
61
64
 
65
+ if (this._terminating) {
66
+ runsLeft = 0;
67
+ }
68
+
62
69
  const failedTestFiles = detox.session.testResults.filter(r => !r.success);
63
70
 
64
71
  const { bail } = detox.config.testRunner;
65
72
  if (bail && failedTestFiles.some(r => r.isPermanentFailure)) {
66
- throw e;
73
+ runsLeft = 0;
67
74
  }
68
75
 
69
76
  const testFilesToRetry = failedTestFiles.filter(r => !r.isPermanentFailure).map(r => r.testFilePath);
70
- if (_.isEmpty(testFilesToRetry)) {
71
- throw e;
77
+ if (testFilesToRetry.length === 0) {
78
+ runsLeft = 0;
72
79
  }
73
80
 
74
81
  if (--runsLeft > 0) {
@@ -143,6 +150,15 @@ class TestRunnerCommand {
143
150
  }, _.isUndefined);
144
151
  }
145
152
 
153
+ _onTerminate = () => {
154
+ if (this._terminating) {
155
+ return;
156
+ }
157
+
158
+ this._terminating = true;
159
+ return detox.unsafe_conductEarlyTeardown(true);
160
+ };
161
+
146
162
  async _spawnTestRunner() {
147
163
  const fullCommand = this._buildSpawnArguments().map(escapeSpaces);
148
164
  const fullCommandWithHint = printEnvironmentVariables(this._envHint) + fullCommand.join(' ');
@@ -153,6 +169,7 @@ class TestRunnerCommand {
153
169
  cp.spawn(fullCommand[0], fullCommand.slice(1), {
154
170
  shell: true,
155
171
  stdio: 'inherit',
172
+ detached: this._detached,
156
173
  env: _({})
157
174
  .assign(process.env)
158
175
  .assign(this._envFwd)
@@ -162,6 +179,8 @@ class TestRunnerCommand {
162
179
  })
163
180
  .on('error', /* istanbul ignore next */ (err) => reject(err))
164
181
  .on('exit', (code, signal) => {
182
+ interruptListeners.unsubscribe(this._onTerminate);
183
+
165
184
  if (code === 0) {
166
185
  log.trace.end({ success: true });
167
186
  resolve();
@@ -175,6 +194,10 @@ class TestRunnerCommand {
175
194
  reject(markErrorAsLogged(error));
176
195
  }
177
196
  });
197
+
198
+ if (this._detached) {
199
+ interruptListeners.subscribe(this._onTerminate);
200
+ }
178
201
  });
179
202
  }
180
203
 
@@ -0,0 +1,15 @@
1
+ function subscribe(listener) {
2
+ process.on('SIGINT', listener);
3
+ process.on('SIGTERM', listener);
4
+ }
5
+
6
+ function unsubscribe(listener) {
7
+ process.removeListener('SIGINT', listener);
8
+ process.removeListener('SIGTERM', listener);
9
+ }
10
+
11
+ module.exports = {
12
+ subscribe,
13
+ unsubscribe,
14
+ };
15
+
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.13.5",
4
+ "version": "20.14.0-prerelease.0",
5
5
  "bin": {
6
6
  "detox": "local-cli/cli.js"
7
7
  },
@@ -51,7 +51,7 @@
51
51
  "eslint-plugin-node": "^11.1.0",
52
52
  "eslint-plugin-unicorn": "^47.0.0",
53
53
  "jest": "^28.1.3",
54
- "jest-allure2-reporter": "2.0.0-alpha.6",
54
+ "jest-allure2-reporter": "2.0.0-alpha.11",
55
55
  "mockdate": "^2.0.1",
56
56
  "prettier": "^2.4.1",
57
57
  "react-native": "0.71.10",
@@ -109,5 +109,5 @@
109
109
  "browserslist": [
110
110
  "node 14"
111
111
  ],
112
- "gitHead": "81db382567a147b0c597d39a519c6ca32d4d97df"
112
+ "gitHead": "4eb7e6729cf5bd3d30f720c40df316fdf38300df"
113
113
  }
@@ -73,7 +73,9 @@ class DetoxCircusEnvironment extends NodeEnvironment {
73
73
  // @ts-expect-error TS2425
74
74
  async handleTestEvent(event, state) {
75
75
  if (detox.session.unsafe_earlyTeardown) {
76
- throw new Error('Detox halted test execution due to an early teardown request');
76
+ if (event.name === 'test_fn_start' || event.name === 'hook_start') {
77
+ throw new Error('Detox halted test execution due to an early teardown request');
78
+ }
77
79
  }
78
80
 
79
81
  this._timer.schedule(state.testTimeout != null ? state.testTimeout : this.setupTimeout);
@@ -107,6 +109,10 @@ class DetoxCircusEnvironment extends NodeEnvironment {
107
109
  * @protected
108
110
  */
109
111
  async initDetox() {
112
+ if (detox.session.unsafe_earlyTeardown) {
113
+ throw new Error('Detox halted test execution due to an early teardown request');
114
+ }
115
+
110
116
  const opts = {
111
117
  global: this.global,
112
118
  workerId: `w${process.env.JEST_WORKER_ID}`,
@@ -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: {
@@ -32,6 +32,7 @@ function composeRunnerConfig(opts) {
32
32
  retries: 0,
33
33
  inspectBrk: inspectBrkHookDefault,
34
34
  forwardEnv: false,
35
+ detached: false,
35
36
  bail: false,
36
37
  jest: {
37
38
  setupTimeout: 300000,
@@ -56,8 +57,9 @@ function composeRunnerConfig(opts) {
56
57
 
57
58
  if (typeof merged.inspectBrk === 'function') {
58
59
  if (cliConfig.inspectBrk) {
59
- merged.retries = 0;
60
+ merged.detached = false;
60
61
  merged.forwardEnv = true;
62
+ merged.retries = 0;
61
63
  merged.inspectBrk(merged);
62
64
  }
63
65
 
@@ -86,8 +86,8 @@ class IPCClient {
86
86
  this._sessionState.patch(sessionState);
87
87
  }
88
88
 
89
- async conductEarlyTeardown() {
90
- const sessionState = await this._emit('conductEarlyTeardown', {});
89
+ async conductEarlyTeardown({ permanent }) {
90
+ const sessionState = await this._emit('conductEarlyTeardown', { permanent });
91
91
  this._sessionState.patch(sessionState);
92
92
  }
93
93
 
@@ -73,6 +73,7 @@ class IPCServer {
73
73
  this._ipc.server.emit(socket, 'registerContextDone', {
74
74
  testResults: this._sessionState.testResults,
75
75
  testSessionIndex: this._sessionState.testSessionIndex,
76
+ unsafe_earlyTeardown: this._sessionState.unsafe_earlyTeardown,
76
77
  });
77
78
  }
78
79
 
@@ -90,10 +91,11 @@ class IPCServer {
90
91
  }
91
92
  }
92
93
 
93
- onConductEarlyTeardown(_data = null, socket = null) {
94
- // Note that we don't save `unsafe_earlyTeardown` in the primary session state
95
- // because it's transient and needed only to make the workers quit early.
94
+ onConductEarlyTeardown({ permanent }, socket = null) {
96
95
  const newState = { unsafe_earlyTeardown: true };
96
+ if (permanent) {
97
+ Object.assign(this._sessionState, newState);
98
+ }
97
99
 
98
100
  if (socket) {
99
101
  this._ipc.server.emit(socket, 'conductEarlyTeardownDone', newState);
@@ -102,7 +102,7 @@ class DetoxContext {
102
102
  /** @abstract */
103
103
  [symbols.reportTestResults](_testResults) {}
104
104
  /** @abstract */
105
- [symbols.conductEarlyTeardown]() {}
105
+ [symbols.conductEarlyTeardown](_permanent) {}
106
106
  /**
107
107
  * @abstract
108
108
  * @param {Partial<DetoxInternals.DetoxInitOptions>} _opts
@@ -51,9 +51,9 @@ class DetoxPrimaryContext extends DetoxContext {
51
51
  }
52
52
  }
53
53
 
54
- [symbols.conductEarlyTeardown] = async () => {
54
+ [symbols.conductEarlyTeardown] = async (permanent = false) => {
55
55
  if (this[_ipcServer]) {
56
- await this[_ipcServer].onConductEarlyTeardown();
56
+ await this[_ipcServer].onConductEarlyTeardown({ permanent });
57
57
  }
58
58
  };
59
59
 
@@ -33,9 +33,9 @@ class DetoxSecondaryContext extends DetoxContext {
33
33
  }
34
34
  }
35
35
 
36
- [symbols.conductEarlyTeardown] = async () => {
36
+ [symbols.conductEarlyTeardown] = async (permanent = false) => {
37
37
  if (this[_ipcClient]) {
38
- await this[_ipcClient].conductEarlyTeardown();
38
+ await this[_ipcClient].conductEarlyTeardown({ permanent });
39
39
  } else {
40
40
  throw new DetoxInternalError('Detected an attempt to report early teardown using a non-initialized context.');
41
41
  }
@@ -1 +0,0 @@
1
- faf5dc28d8239cc6da3b2bf96b1b29a5
@@ -1 +0,0 @@
1
- 66259e139e74a9129e2f568fcdabaa5385713e68
@@ -1 +0,0 @@
1
- 9150be4e9ca3b67f6ff6f6df43fcb06cd8e072077992431f578e514bbe9f778f
@@ -1 +0,0 @@
1
- 337245632beaeaf3cf9dce4ec6f98a0dee7faaf09e95fc5538781452c532ebb002bc1907b2da230ec47044cf9f31c6dba55dbb00ab16dab8c3af7b643a376974
@@ -1 +0,0 @@
1
- 364d1f43c94bb6c771f7c29321e1bc4c
@@ -1 +0,0 @@
1
- 1021db825c7835306b90ae34b8d1c294f719990e
@@ -1 +0,0 @@
1
- fb7098e8a4f09fd00b0ac9f123d104bb7298784d055fcbc1d385788c071f0983
@@ -1 +0,0 @@
1
- 19a6d854223aba1d9a037ed08f96ea5ac66d4fca81083b9e755bd0f60df0ef55e0cfee4849ed0ddb742c856b4083efeb772da1cd83771d3f56eba813b194d65f
@@ -1 +0,0 @@
1
- 5037d89ac5d98e47d69d63b8731e7e3a
@@ -1 +0,0 @@
1
- b4a0f9db575d92cb2da51c617e0ff531330cc2c6
@@ -1 +0,0 @@
1
- 1fa253115965db1c97bc6c8b0c1ab0dff9ac9f8714e063dc972332cc6798b63a
@@ -1 +0,0 @@
1
- 8174914ad6abe68c79f4812a32d292e80d922239045a30401bc39f43801f3cd2ea2807786248ffb58e84dfcdb8eddc00c7f606a874eb216def9350d325442af3
@@ -1 +0,0 @@
1
- 4ddd8a0d0201920d14cba4ec92fbbc30
@@ -1 +0,0 @@
1
- 3ba542128c404b075ca90ee6603104cc1311e0c9
@@ -1 +0,0 @@
1
- c3c239c4180d3fdcc490b06a5848308470e6cf69e23c469716f41d53bf12c32e
@@ -1 +0,0 @@
1
- 2a99293177c0028c4839b99fbc16a7afaee90cefb1fc26eb32c3960a71c1cc541b92bc06d6efe38c23932abd14d9b301a72812ce86f700069124805d1e2421c2