From cd511d0e3d439d94f9db8eb2f79c85bf803702cb Mon Sep 17 00:00:00 2001 From: Amit Davidi Date: Wed, 23 Jan 2019 18:15:23 +0200 Subject: [PATCH] (Android) Migrate instrumentation support lib to androidx libs --- detox/android/detox/build.gradle | 9 +- .../wix/detox/ExampleInstrumentedTest.java | 7 +- .../src/main/java/com/wix/detox/Detox.java | 13 +-- .../java/com/wix/detox/DetoxActionHandlers.kt | 2 +- .../main/java/com/wix/detox/DetoxManager.java | 3 +- .../com/wix/detox/ReactNativeSupport.java | 9 +- .../java/com/wix/detox/TestEngineFacade.kt | 4 +- .../AnimatedModuleIdlingResource.java | 3 +- .../com/wix/detox/espresso/DetoxAction.java | 33 ++++---- .../wix/detox/espresso/DetoxAssertion.java | 17 ++-- .../com/wix/detox/espresso/DetoxMatcher.java | 21 ++--- .../wix/detox/espresso/DetoxViewActions.java | 7 +- .../com/wix/detox/espresso/EspressoDetox.java | 20 ++--- .../java/com/wix/detox/espresso/MultiTap.java | 11 +-- .../espresso/ReactBridgeIdlingResource.java | 5 +- .../ReactNativeNetworkIdlingResource.java | 8 +- .../ReactNativeTimersIdlingResource.kt | 2 +- .../ReactNativeUIModuleIdlingResource.java | 5 +- .../com/wix/detox/espresso/ScrollHelper.java | 5 +- .../wix/detox/espresso/UiAutomatorHelper.java | 13 +-- .../wix/detox/uiautomator/UiAutomator.java | 3 +- .../com/wix/detox/DetoxActionHandlersTest.kt | 2 +- .../ReactNativeTimersIdlingResourceTest.kt | 2 +- detox/src/android/espressoapi/Detox.js | 25 +++++- .../src/android/espressoapi/EspressoDetox.js | 27 ++++++ detox/src/android/espressoapi/ViewActions.js | 82 +++++++++++++------ detox/src/invoke/Espresso.js | 2 +- detox/test/android/app/build.gradle | 5 +- .../java/com/example/DetoxTest.java | 9 +- docs/Guide.Migration.md | 30 +++++++ docs/Introduction.Android.md | 10 ++- docs/Introduction.GettingStarted.md | 7 ++ .../android/app/build.gradle | 4 +- .../java/com/example/DetoxTest.java | 10 +-- generation/core/generator.js | 2 + generation/index.js | 69 ++++++++-------- .../utils/__tests__/downloadEspresso.js | 30 ------- generation/utils/__tests__/downloadFile.js | 47 +++++++++++ generation/utils/downloadEspresso.js | 4 +- generation/utils/downloadFile.js | 8 +- 40 files changed, 365 insertions(+), 210 deletions(-) delete mode 100644 generation/utils/__tests__/downloadEspresso.js create mode 100644 generation/utils/__tests__/downloadFile.js diff --git a/detox/android/detox/build.gradle b/detox/android/detox/build.gradle index 53ad2fa814..332e81c9b9 100644 --- a/detox/android/detox/build.gradle +++ b/detox/android/detox/build.gradle @@ -75,11 +75,10 @@ dependencies { minReactNative46Implementation 'com.squareup.okhttp3:okhttp:3.6.0' minReactNative46Implementation 'com.squareup.okio:okio:1.13.0' - implementation('com.android.support.test.espresso:espresso-core:3.0.2', { - exclude group: 'com.google.code.findbugs' - }) - implementation 'com.android.support.test:runner:1.0.2' - implementation 'com.android.support.test:rules:1.0.2' + api 'androidx.test.espresso:espresso-core:3.1.1' + api 'androidx.test:runner:1.1.1' + api 'androidx.test:rules:1.1.1' + api 'androidx.test.ext:junit:1.1.0' // noinspection GradleDynamicVersion compileOnly "com.facebook.react:react-native:+" diff --git a/detox/android/detox/src/androidTest/java/com/wix/detox/ExampleInstrumentedTest.java b/detox/android/detox/src/androidTest/java/com/wix/detox/ExampleInstrumentedTest.java index 1826ab01e7..c5b8ff1cbc 100644 --- a/detox/android/detox/src/androidTest/java/com/wix/detox/ExampleInstrumentedTest.java +++ b/detox/android/detox/src/androidTest/java/com/wix/detox/ExampleInstrumentedTest.java @@ -1,12 +1,13 @@ package com.wix.detox; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import static org.junit.Assert.*; /** @@ -19,7 +20,7 @@ public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); assertEquals("com.wix.detox", appContext.getPackageName()); } diff --git a/detox/android/detox/src/main/java/com/wix/detox/Detox.java b/detox/android/detox/src/main/java/com/wix/detox/Detox.java index 9d0e79fd77..7b8651d83d 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/Detox.java +++ b/detox/android/detox/src/main/java/com/wix/detox/Detox.java @@ -9,12 +9,13 @@ import android.os.Looper; import android.os.RemoteException; import android.support.annotation.NonNull; -import android.support.test.InstrumentationRegistry; -import android.support.test.rule.ActivityTestRule; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; import android.support.test.uiautomator.UiSelector; +import androidx.test.platform.app.InstrumentationRegistry; + +import androidx.test.rule.ActivityTestRule; /** *

Static class.

@@ -85,12 +86,12 @@ private Detox() { * *

* In case you have a non-standard React Native application, consider using - * {@link Detox#runTests(ActivityTestRule, Object)}}. + * {@link #runTests(ActivityTestRule, Context)}}. *

* @param activityTestRule the activityTestRule */ public static void runTests(ActivityTestRule activityTestRule) { - Context appContext = InstrumentationRegistry.getTargetContext().getApplicationContext(); + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); runTests(activityTestRule, appContext); } @@ -109,7 +110,7 @@ public static void runTests(ActivityTestRule activityTestRule) { *

* * @param activityTestRule the activityTestRule - * @param Context an object that has a {@code getReactNativeHost()} method + * @param context an object that has a {@code getReactNativeHost()} method */ public static void runTests(ActivityTestRule activityTestRule, @NonNull final Context context) { sActivityTestRule = activityTestRule; @@ -173,7 +174,7 @@ public static void startActivityFromUrl(String url) { // TODO: Can't get to launch the app back to previous instance using only intents from inside instrumentation (not sure why). // this is a (hopefully) temp solution. Should use intents instead. public static void launchMainActivity() throws RemoteException, UiObjectNotFoundException { - final Context targetContext = InstrumentationRegistry.getTargetContext(); + final Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); // Intent intent = targetContext.getPackageManager().getLaunchIntentForPackage(targetContext.getPackageName()); // intent.setPackage(null); diff --git a/detox/android/detox/src/main/java/com/wix/detox/DetoxActionHandlers.kt b/detox/android/detox/src/main/java/com/wix/detox/DetoxActionHandlers.kt index 868616d28d..d51386ff03 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/DetoxActionHandlers.kt +++ b/detox/android/detox/src/main/java/com/wix/detox/DetoxActionHandlers.kt @@ -1,8 +1,8 @@ package com.wix.detox import android.content.Context -import android.support.test.espresso.IdlingResource import android.util.Log +import androidx.test.espresso.IdlingResource import com.wix.invoke.MethodInvocation import org.json.JSONArray import org.json.JSONException diff --git a/detox/android/detox/src/main/java/com/wix/detox/DetoxManager.java b/detox/android/detox/src/main/java/com/wix/detox/DetoxManager.java index 2e60f9aeb8..b5b4e228d7 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/DetoxManager.java +++ b/detox/android/detox/src/main/java/com/wix/detox/DetoxManager.java @@ -5,7 +5,6 @@ import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; -import android.support.test.InstrumentationRegistry; import android.util.Log; import com.wix.detox.systeminfo.Environment; @@ -14,10 +13,10 @@ import java.util.HashMap; import java.util.Map; +import androidx.test.platform.app.InstrumentationRegistry; import kotlin.Unit; import kotlin.jvm.functions.Function0; - /** * Created by rotemm on 04/01/2017. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/ReactNativeSupport.java b/detox/android/detox/src/main/java/com/wix/detox/ReactNativeSupport.java index 5a482ad114..92100bedd2 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/ReactNativeSupport.java +++ b/detox/android/detox/src/main/java/com/wix/detox/ReactNativeSupport.java @@ -3,9 +3,6 @@ import android.content.Context; import android.os.Looper; import android.support.annotation.NonNull; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.IdlingRegistry; -import android.support.test.espresso.base.IdlingResourceRegistry; import android.util.Log; import com.facebook.react.ReactApplication; @@ -22,6 +19,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; + +import androidx.test.espresso.IdlingRegistry; +import androidx.test.espresso.base.IdlingResourceRegistry; +import androidx.test.platform.app.InstrumentationRegistry; import okhttp3.OkHttpClient; @@ -207,7 +208,7 @@ private static void setupReactNativeQueueInterrogators(@NonNull Object reactCont IdlingRegistry.getInstance().registerLooperAsIdlingResource(JSMessageQueue); IdlingRegistry.getInstance().registerLooperAsIdlingResource(JMativeModulesMessageQueue); - IdlingResourceRegistry irr = Reflect.on("android.support.test.espresso.Espresso").field("baseRegistry").get(); + IdlingResourceRegistry irr = Reflect.on(androidx.test.espresso.Espresso.class).field("baseRegistry").get(); irr.sync(IdlingRegistry.getInstance().getResources(), IdlingRegistry.getInstance().getLoopers()); } diff --git a/detox/android/detox/src/main/java/com/wix/detox/TestEngineFacade.kt b/detox/android/detox/src/main/java/com/wix/detox/TestEngineFacade.kt index 42983f7268..c14c346798 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/TestEngineFacade.kt +++ b/detox/android/detox/src/main/java/com/wix/detox/TestEngineFacade.kt @@ -1,8 +1,8 @@ package com.wix.detox import android.content.Context -import android.support.test.espresso.Espresso -import android.support.test.espresso.IdlingResource +import androidx.test.espresso.Espresso +import androidx.test.espresso.IdlingResource import com.wix.detox.espresso.EspressoDetox import com.wix.detox.espresso.UiAutomatorHelper diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/AnimatedModuleIdlingResource.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/AnimatedModuleIdlingResource.java index c26208f63c..6cfb784b65 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/AnimatedModuleIdlingResource.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/AnimatedModuleIdlingResource.java @@ -1,7 +1,6 @@ package com.wix.detox.espresso; import android.support.annotation.NonNull; -import android.support.test.espresso.IdlingResource; import android.util.Log; import android.view.Choreographer; @@ -10,6 +9,8 @@ import org.joor.Reflect; import org.joor.ReflectException; +import androidx.test.espresso.IdlingResource; + /** * Created by simonracz on 25/08/2017. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java index 7bd710c9ee..e7299900df 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java @@ -1,14 +1,5 @@ package com.wix.detox.espresso; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.action.CoordinatesProvider; -import android.support.test.espresso.action.GeneralClickAction; -import android.support.test.espresso.action.GeneralLocation; -import android.support.test.espresso.action.GeneralSwipeAction; -import android.support.test.espresso.action.Press; -import android.support.test.espresso.action.Swipe; -import android.support.test.espresso.action.Tap; import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; @@ -18,13 +9,23 @@ import org.hamcrest.Matcher; -import static android.support.test.espresso.action.ViewActions.actionWithAssertions; -import static android.support.test.espresso.action.ViewActions.swipeDown; -import static android.support.test.espresso.action.ViewActions.swipeLeft; -import static android.support.test.espresso.action.ViewActions.swipeRight; -import static android.support.test.espresso.action.ViewActions.swipeUp; -import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.action.CoordinatesProvider; +import androidx.test.espresso.action.GeneralClickAction; +import androidx.test.espresso.action.GeneralLocation; +import androidx.test.espresso.action.GeneralSwipeAction; +import androidx.test.espresso.action.Press; +import androidx.test.espresso.action.Swipe; +import androidx.test.espresso.action.Tap; + +import static androidx.test.espresso.action.ViewActions.actionWithAssertions; +import static androidx.test.espresso.action.ViewActions.swipeDown; +import static androidx.test.espresso.action.ViewActions.swipeLeft; +import static androidx.test.espresso.action.ViewActions.swipeRight; +import static androidx.test.espresso.action.ViewActions.swipeUp; +import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static org.hamcrest.Matchers.allOf; diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAssertion.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAssertion.java index d987b309e7..ef8f7d152a 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAssertion.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAssertion.java @@ -1,20 +1,19 @@ package com.wix.detox.espresso; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.EspressoException; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.ViewInteraction; import android.view.View; import junit.framework.AssertionFailedError; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import androidx.test.espresso.EspressoException; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.ViewInteraction; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static org.hamcrest.Matchers.not; /** diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java index e00e627b39..39e116f926 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java @@ -1,21 +1,22 @@ package com.wix.detox.espresso; -import android.support.test.espresso.matcher.ViewMatchers; import android.view.View; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; -import static android.support.test.espresso.matcher.ViewMatchers.Visibility; -import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; -import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; -import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast; -import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; -import static android.support.test.espresso.matcher.ViewMatchers.withTagValue; -import static android.support.test.espresso.matcher.ViewMatchers.withText; +import androidx.test.espresso.matcher.ViewMatchers; +import androidx.test.espresso.matcher.ViewMatchers.Visibility; + +import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant; +import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast; +import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; +import static androidx.test.espresso.matcher.ViewMatchers.withTagValue; +import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.is; diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java index d19f402443..3ab4ee5f29 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java @@ -1,14 +1,15 @@ package com.wix.detox.espresso; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.action.ViewActions; import android.view.View; import com.wix.detox.ReactNativeSupport; import org.hamcrest.Matcher; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.action.ViewActions; + /** * An alternative to {@link ViewActions} - providing alternative implementations, where needed. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java index ee030f0605..3971d7edc2 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java @@ -5,12 +5,6 @@ import android.content.ContextWrapper; import android.content.pm.ActivityInfo; import android.os.Handler; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.IdlingResource; -import android.support.test.espresso.UiController; -import android.support.test.espresso.ViewAction; -import android.support.test.espresso.ViewInteraction; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -23,13 +17,19 @@ import java.util.ArrayList; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.IdlingResource; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; +import androidx.test.espresso.ViewInteraction; +import androidx.test.platform.app.InstrumentationRegistry; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.matcher.ViewMatchers.isRoot; /** * Created by rotemm on 26/12/2016. */ - public class EspressoDetox { private static final String LOG_TAG = "detox"; @@ -121,7 +121,7 @@ public static ArrayList getBusyEspressoResources() { // 1. we want to use postAtFrontOfQueue() // 2. we want it to be synchronous final ArrayList busyResources = new ArrayList<>(); - final Handler handler = new Handler(InstrumentationRegistry.getTargetContext().getMainLooper()); + final Handler handler = new Handler(InstrumentationRegistry.getInstrumentation().getTargetContext().getMainLooper()); final SyncRunnable sr = new SyncRunnable(new Runnable() { @Override public void run() { diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/MultiTap.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/MultiTap.java index 33a08f1ecc..94d675873b 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/MultiTap.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/MultiTap.java @@ -1,17 +1,18 @@ package com.wix.detox.espresso; import android.os.Build; -import android.support.test.espresso.UiController; -import android.support.test.espresso.action.MotionEvents; -import android.support.test.espresso.action.MotionEvents.DownResultHolder; -import android.support.test.espresso.action.Tapper; import android.util.Log; import android.view.ViewConfiguration; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import static android.support.test.espresso.core.internal.deps.guava.base.Preconditions.checkNotNull; +import androidx.test.espresso.UiController; +import androidx.test.espresso.action.MotionEvents; +import androidx.test.espresso.action.MotionEvents.DownResultHolder; +import androidx.test.espresso.action.Tapper; + +import static androidx.test.espresso.core.internal.deps.guava.base.Preconditions.checkNotNull; public class MultiTap implements Tapper { diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactBridgeIdlingResource.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactBridgeIdlingResource.java index 7a0a3f52b4..51d4f1b3a0 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactBridgeIdlingResource.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactBridgeIdlingResource.java @@ -1,6 +1,5 @@ package com.wix.detox.espresso; -import android.support.test.espresso.IdlingResource; import android.util.Log; import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener; @@ -8,6 +7,10 @@ import java.util.concurrent.atomic.AtomicBoolean; +import androidx.test.espresso.IdlingResource; + +import static androidx.test.espresso.IdlingResource.ResourceCallback; + /** * Created by simonracz on 01/06/2017. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeNetworkIdlingResource.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeNetworkIdlingResource.java index 414694e5ae..827555649e 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeNetworkIdlingResource.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeNetworkIdlingResource.java @@ -1,7 +1,6 @@ package com.wix.detox.espresso; import android.support.annotation.NonNull; -import android.support.test.espresso.IdlingResource; import android.util.Log; import android.view.Choreographer; @@ -11,6 +10,9 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import androidx.test.espresso.IdlingResource; +import static androidx.test.espresso.IdlingResource.ResourceCallback; + import okhttp3.Call; import okhttp3.Dispatcher; @@ -113,7 +115,3 @@ public void stop() { } } - - - - diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeTimersIdlingResource.kt b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeTimersIdlingResource.kt index bb82256f03..558b11a7fc 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeTimersIdlingResource.kt +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeTimersIdlingResource.kt @@ -1,7 +1,7 @@ package com.wix.detox.espresso -import android.support.test.espresso.IdlingResource import android.view.Choreographer +import androidx.test.espresso.IdlingResource import com.facebook.react.bridge.ReactContext import com.facebook.react.modules.core.Timing import org.joor.Reflect diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeUIModuleIdlingResource.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeUIModuleIdlingResource.java index 3eeb63bb86..a33e61a89b 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeUIModuleIdlingResource.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/ReactNativeUIModuleIdlingResource.java @@ -1,13 +1,16 @@ package com.wix.detox.espresso; import android.support.annotation.NonNull; -import android.support.test.espresso.IdlingResource; import android.util.Log; import android.view.Choreographer; import org.joor.Reflect; import org.joor.ReflectException; +import androidx.test.espresso.IdlingResource; + +import static androidx.test.espresso.IdlingResource.ResourceCallback; + /** * Created by simonracz on 26/07/2017. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/ScrollHelper.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/ScrollHelper.java index 516bbf1926..ffe56a70cd 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/ScrollHelper.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/ScrollHelper.java @@ -1,12 +1,13 @@ package com.wix.detox.espresso; import android.os.SystemClock; -import android.support.test.espresso.UiController; -import android.support.test.espresso.action.MotionEvents; import android.util.Log; import android.view.MotionEvent; import android.view.View; +import androidx.test.espresso.UiController; +import androidx.test.espresso.action.MotionEvents; + /** * Created by simonracz on 09/08/2017. */ diff --git a/detox/android/detox/src/main/java/com/wix/detox/espresso/UiAutomatorHelper.java b/detox/android/detox/src/main/java/com/wix/detox/espresso/UiAutomatorHelper.java index 7060b1d045..fe4a5b100b 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/espresso/UiAutomatorHelper.java +++ b/detox/android/detox/src/main/java/com/wix/detox/espresso/UiAutomatorHelper.java @@ -2,9 +2,6 @@ import android.content.Context; import android.os.Handler; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.ViewInteraction; import android.util.DisplayMetrics; import android.util.Log; import android.view.Choreographer; @@ -17,6 +14,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import androidx.test.espresso.Espresso; +import androidx.test.espresso.ViewInteraction; +import androidx.test.platform.app.InstrumentationRegistry; + /** * Created by simonracz on 19/07/2017. */ @@ -72,7 +73,7 @@ public void run() { } public static float getDensity() { - Context context = InstrumentationRegistry.getTargetContext().getApplicationContext(); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); return context.getResources().getDisplayMetrics().density; } @@ -85,7 +86,7 @@ public static int convertPixtoDip(int pixel) { } public static float[] getScreenSizeInPX() { - DisplayMetrics metrics = InstrumentationRegistry.getTargetContext() + DisplayMetrics metrics = InstrumentationRegistry.getInstrumentation().getTargetContext() .getApplicationContext().getResources().getDisplayMetrics(); return new float[]{metrics.widthPixels, metrics.heightPixels}; } @@ -105,7 +106,7 @@ public static float[] getScreenSizeInPX() { private static void waitForChoreographer() { final int waitFrameCount = 2; final CountDownLatch latch = new CountDownLatch(1); - Handler handler = new Handler(InstrumentationRegistry.getTargetContext().getMainLooper()); + Handler handler = new Handler(InstrumentationRegistry.getInstrumentation().getTargetContext().getMainLooper()); handler.post( new Runnable() { @Override diff --git a/detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java b/detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java index 9b47253b3a..247c15a84c 100644 --- a/detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java +++ b/detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java @@ -1,8 +1,9 @@ package com.wix.detox.uiautomator; -import android.support.test.InstrumentationRegistry; import android.support.test.uiautomator.UiDevice; +import androidx.test.platform.app.InstrumentationRegistry; + /** * Created by rotemm on 30/08/2017. */ diff --git a/detox/android/detox/src/test/java/com/wix/detox/DetoxActionHandlersTest.kt b/detox/android/detox/src/test/java/com/wix/detox/DetoxActionHandlersTest.kt index ea0e62d398..1e6ee44606 100644 --- a/detox/android/detox/src/test/java/com/wix/detox/DetoxActionHandlersTest.kt +++ b/detox/android/detox/src/test/java/com/wix/detox/DetoxActionHandlersTest.kt @@ -1,6 +1,6 @@ package com.wix.detox -import android.support.test.espresso.IdlingResource +import androidx.test.espresso.IdlingResource import com.facebook.react.bridge.ReactContext import com.nhaarman.mockito_kotlin.* import com.wix.detox.UTHelpers.yieldToOtherThreads diff --git a/detox/android/detox/src/test/java/com/wix/detox/espresso/ReactNativeTimersIdlingResourceTest.kt b/detox/android/detox/src/test/java/com/wix/detox/espresso/ReactNativeTimersIdlingResourceTest.kt index 2fe0e8e5d3..f0905d4ffd 100644 --- a/detox/android/detox/src/test/java/com/wix/detox/espresso/ReactNativeTimersIdlingResourceTest.kt +++ b/detox/android/detox/src/test/java/com/wix/detox/espresso/ReactNativeTimersIdlingResourceTest.kt @@ -1,7 +1,7 @@ package com.wix.detox.espresso -import android.support.test.espresso.IdlingResource.ResourceCallback import android.view.Choreographer +import androidx.test.espresso.IdlingResource.ResourceCallback import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.modules.core.Timing import com.nhaarman.mockito_kotlin.* diff --git a/detox/src/android/espressoapi/Detox.js b/detox/src/android/espressoapi/Detox.js index 7f554a9957..4547bf1cc4 100644 --- a/detox/src/android/espressoapi/Detox.js +++ b/detox/src/android/espressoapi/Detox.js @@ -46,6 +46,29 @@ class Detox { }; } + static extractInitialIntent() { + return { + target: { + type: "Class", + value: "com.wix.detox.Detox" + }, + method: "extractInitialIntent", + args: [] + }; + } + + static intentWithUrl(url) { + if (typeof url !== "string") throw new Error("url should be a string, but got " + (url + (" (" + (typeof url + ")")))); + return { + target: { + type: "Class", + value: "com.wix.detox.Detox" + }, + method: "intentWithUrl", + args: [url] + }; + } + } -module.exports = Detox; +module.exports = Detox; \ No newline at end of file diff --git a/detox/src/android/espressoapi/EspressoDetox.js b/detox/src/android/espressoapi/EspressoDetox.js index 05ffa4791b..256ef4fd5d 100644 --- a/detox/src/android/espressoapi/EspressoDetox.js +++ b/detox/src/android/espressoapi/EspressoDetox.js @@ -66,6 +66,33 @@ class EspressoDetox { }; } + static getBusyEspressoResources() { + return { + target: { + type: "Class", + value: "com.wix.detox.espresso.EspressoDetox" + }, + method: "getBusyEspressoResources", + args: [] + }; + } + + static run(element) { + return { + target: element, + method: "run", + args: [] + }; + } + + static waitForComplete(element) { + return { + target: element, + method: "waitForComplete", + args: [] + }; + } + } module.exports = EspressoDetox; \ No newline at end of file diff --git a/detox/src/android/espressoapi/ViewActions.js b/detox/src/android/espressoapi/ViewActions.js index b73915c8b6..0db9e24b96 100644 --- a/detox/src/android/espressoapi/ViewActions.js +++ b/detox/src/android/espressoapi/ViewActions.js @@ -18,7 +18,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "clearGlobalAssertions", args: [] @@ -29,7 +29,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "actionWithAssertions", args: [viewAction] @@ -40,19 +40,38 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "clearText", args: [] }; } - static click() { + static click(inputDevice, buttonState) { + function click2(inputDevice, buttonState) { + if (typeof inputDevice !== "number") throw new Error("inputDevice should be a number, but got " + (inputDevice + (" (" + (typeof inputDevice + ")")))); + if (typeof buttonState !== "number") throw new Error("buttonState should be a number, but got " + (buttonState + (" (" + (typeof buttonState + ")")))); + return { + target: { + type: "Class", + value: "androidx.test.espresso.action.ViewActions" + }, + method: "click", + args: [{ + type: "Integer", + value: inputDevice + }, { + type: "Integer", + value: buttonState + }] + }; + } + function click0() { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "click", args: [] @@ -63,13 +82,17 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "click", args: [rollbackAction] }; } + if (arguments.length === 2) { + return click2.apply(null, arguments); + } + if (arguments.length === 0) { return click0.apply(null, arguments); } @@ -83,7 +106,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "swipeLeft", args: [] @@ -94,7 +117,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "swipeRight", args: [] @@ -105,7 +128,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "swipeDown", args: [] @@ -116,7 +139,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "swipeUp", args: [] @@ -127,7 +150,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "closeSoftKeyboard", args: [] @@ -138,7 +161,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "pressImeActionButton", args: [] @@ -149,18 +172,29 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "pressBack", args: [] }; } + static pressBackUnconditionally() { + return { + target: { + type: "Class", + value: "androidx.test.espresso.action.ViewActions" + }, + method: "pressBackUnconditionally", + args: [] + }; + } + static pressMenuKey() { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "pressMenuKey", args: [] @@ -172,7 +206,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "pressKey", args: [{ @@ -186,7 +220,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "doubleClick", args: [] @@ -197,7 +231,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "longClick", args: [] @@ -208,7 +242,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "scrollTo", args: [] @@ -220,7 +254,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "typeTextIntoFocusedView", args: [stringToBeTyped] @@ -232,7 +266,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "typeText", args: [stringToBeTyped] @@ -244,7 +278,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "replaceText", args: [stringToBeSet] @@ -256,7 +290,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "openLinkWithText", args: [linkText] @@ -268,7 +302,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "openLinkWithUri", args: [uri] @@ -280,7 +314,7 @@ class ViewActions { return { target: { type: "Class", - value: "android.support.test.espresso.action.ViewActions" + value: "androidx.test.espresso.action.ViewActions" }, method: "repeatedlyUntil", args: [action, { diff --git a/detox/src/invoke/Espresso.js b/detox/src/invoke/Espresso.js index 4232e5183e..5ec0d189cd 100644 --- a/detox/src/invoke/Espresso.js +++ b/detox/src/invoke/Espresso.js @@ -1,6 +1,6 @@ const target = { type: 'Class', - value: 'android.support.test.espresso.Espresso' + value: 'androidx.test.espresso.Espresso' }; module.exports = { diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index a7e9ab61d2..e3f75ba795 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -15,7 +15,7 @@ android { abiFilters "armeabi-v7a", "x86" } testBuildType System.getProperty('testBuildType', 'debug') - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" missingDimensionStrategy "minReactNative", "minReactNative46" /* testInstrumentationRunnerArguments = [ @@ -56,6 +56,7 @@ android { exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' } + } dependencies { @@ -67,8 +68,6 @@ dependencies { androidTestImplementation(project(path: ":detox")) androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test:rules:1.0.2' } // Run this once to be able to run the application with BUCK diff --git a/detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java b/detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java index 5b3868f8df..4ec717274f 100644 --- a/detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java +++ b/detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java @@ -1,10 +1,11 @@ package com.example; import android.os.Bundle; -import android.support.test.filters.LargeTest; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.support.test.InstrumentationRegistry; +import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.rule.ActivityTestRule; import com.wix.detox.Detox; diff --git a/docs/Guide.Migration.md b/docs/Guide.Migration.md index f5c528ae39..0c098c9e46 100644 --- a/docs/Guide.Migration.md +++ b/docs/Guide.Migration.md @@ -5,7 +5,37 @@ title: Migration Guide We are improving detox API as we go along, sometimes these changes require us to break the API in order for it to make more sense. These migration guides refer to breaking changes. + + +## Migrating from Detox 10.x.x to 11.x.x + +#### Step 1: + +`android/app/build.gradle` + +```diff +android { + defaultConfig { + // ... +- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ++ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } +} + +dependencies { + implementation "com.facebook.react:react-native:+" // From node_modules + androidTestImplementation(project(path: ":detox")) + androidTestImplementation 'junit:junit:4.12' +- androidTestImplementation 'com.android.support.test:runner:1.0.2' +- androidTestImplementation 'com.android.support.test:rules:1.0.2' +``` + +#### Step 2: + +Rewrite your `DetoxTest.java` file according to the updated [Android setup guide](Introduction.Android.md#4-create-android-test-class) (step 4). + ## Migrating from Detox 9.x.x to 10.x.x + If your project does not already use Kotlin, add the Kotlin Gradle-plugin to your classpath in `android/build.gradle`: ```groovy diff --git a/docs/Introduction.Android.md b/docs/Introduction.Android.md index 16bd3cd05b..a9819b5821 100644 --- a/docs/Introduction.Android.md +++ b/docs/Introduction.Android.md @@ -5,6 +5,12 @@ title: Detox for Android ## Breaking Changes :warning: +> If you are installing Detox for Android for the first time, you can skip right over to the setup section. + +> Follow our [Migration Guide](Guide.Migration.md) for instructions on how to upgrade from older versions. + +* **In version 11 we switched to using Android Espresso of Android's new [androidx.\* support libraries](https://developer.android.com/jetpack/androidx/).** We did this in order to stay up to date with Google's latest features and bug fixes, in the hopes of using them to improve our own Android support (which gets better every day!). + * **In version 10, we've made [Kotlin](https://kotlinlang.org/) mandatory for integrating Detox into your Android project.** In the very least, you must include the Kotlin gradle plugin in your project, as we shall see later on. Nevertheless, this is a breaking change so bear that in mind when upgrading. In any case, worry not of the impact on your app, as - unless you effectively use Kotlin in your own native code, **there will be no impact on the final APK**, in terms of size and methods count. * **As of version 7** we require Android gradle plugin 3.0.0 or newer. This is a breaking change that makes it impossible to support previous Android gradle plugin versions. @@ -36,7 +42,7 @@ In `android/app/build.gradle` add this to `defaultConfig` section: ... testBuildType System.getProperty('testBuildType', 'debug') //this will later be used to control the test apk build type missingDimensionStrategy "minReactNative", "minReactNative46" //read note - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" ... } ``` @@ -57,8 +63,6 @@ dependencies { // ... androidTestImplementation(project(path: ":detox")) androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test:rules:1.0.1' } ``` diff --git a/docs/Introduction.GettingStarted.md b/docs/Introduction.GettingStarted.md index 11e83394f6..3796214b10 100644 --- a/docs/Introduction.GettingStarted.md +++ b/docs/Introduction.GettingStarted.md @@ -177,3 +177,10 @@ detox test That's it. Your first failing Detox test is running! Next, we'll go over usage and how to make this test [actually pass](Introduction.WritingFirstTest.md). + +
+ +## Step 5: Android Setup + +If you haven't already done so - now is the time to set Android up using the [Android guide](Introduction.Android.md). + diff --git a/examples/demo-react-native/android/app/build.gradle b/examples/demo-react-native/android/app/build.gradle index 7921735abe..aaf645c942 100644 --- a/examples/demo-react-native/android/app/build.gradle +++ b/examples/demo-react-native/android/app/build.gradle @@ -19,7 +19,7 @@ android { } testBuildType System.getProperty('testBuildType', 'debug') - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" missingDimensionStrategy "minReactNative", "minReactNative46" } splits { @@ -74,8 +74,6 @@ dependencies { androidTestImplementation(project(path: ":detox")) androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test:rules:1.0.2' } // Run this once to be able to run the application with BUCK diff --git a/examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java b/examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java index e63fdfd408..4fa1154b14 100644 --- a/examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java +++ b/examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java @@ -1,15 +1,15 @@ package com.example; -import android.support.test.filters.LargeTest; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; - import com.wix.detox.Detox; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; +import androidx.test.rule.ActivityTestRule; + @RunWith(AndroidJUnit4.class) @LargeTest public class DetoxTest { @@ -18,7 +18,7 @@ public class DetoxTest { public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); @Test - public void runDetoxTests() throws InterruptedException { + public void runDetoxTests() { Detox.runTests(mActivityRule); } } diff --git a/generation/core/generator.js b/generation/core/generator.js index 945a06abd3..5814a5bab2 100644 --- a/generation/core/generator.js +++ b/generation/core/generator.js @@ -287,6 +287,8 @@ module.exports = function getGenerator({ return function generator(files) { Object.entries(files).forEach(([inputFile, outputFile]) => { + console.log(`\n\r${inputFile} => ${outputFile}`); + globalFunctionUsage = {}; const input = fs.readFileSync(inputFile, 'utf8'); const isObjectiveC = inputFile[inputFile.length - 1] === 'h'; diff --git a/generation/index.js b/generation/index.js index d9a6c6b85d..01642098c9 100755 --- a/generation/index.js +++ b/generation/index.js @@ -16,43 +16,42 @@ const iosFiles = { '../detox/ios/EarlGrey/EarlGrey/Core/EarlGreyImpl.h': '../detox/src/ios/earlgreyapi/EarlGreyImpl.js', '../detox/ios/Detox/GREYActions+Detox.h': '../detox/src/ios/earlgreyapi/GREYActions+Detox.js' }; - generateIOSAdapters(iosFiles); -//TODO - network failing on CI, check ASAP -// const espressoFilesToDownload = { -// 'android.support.test.espresso.action.ViewActions': '../detox/src/android/espressoapi/ViewActions.js' -// }; -// const downloadedEspressoFilesMap = Object.entries(espressoFilesToDownload).reduce( -// (obj, [fullyQualifiedClass, dest]) => ({ -// ...obj, -// [downloadEspressoFileByClass(fullyQualifiedClass)]: dest -// }), -// {} -// ); +const espressoFilesToDownload = { + 'androidx.test.espresso.action.ViewActions': '../detox/src/android/espressoapi/ViewActions.js' +}; -// const externalFilesToDownload = { -// 'https://android.googlesource.com/platform/frameworks/uiautomator/+/master/src/com/android/uiautomator/core/UiDevice.java?format=TEXT': -// '../detox/src/android/espressoapi/UIDevice.js' -// }; +const downloadedEspressoFilesMap = Object + .entries(espressoFilesToDownload) + .reduce(function (obj, [fullyQualifiedClass, dest]) { + obj[downloadEspressoFileByClass(fullyQualifiedClass)] = dest; + return obj; + }, {} + ); -// const downloadedAndroidFilesMap = Object.entries(externalFilesToDownload).reduce( -// (obj, [url, dest]) => ({ -// ...obj, -// [downloadFile(url)]: dest -// }), -// {} -// ); +const externalFilesToDownload = { + 'https://android.googlesource.com/platform/frameworks/uiautomator/+/master/src/com/android/uiautomator/core/UiDevice.java?format=TEXT': + '../detox/src/android/espressoapi/UIDevice.js' +}; -// const androidFiles = { -// ...downloadedAndroidFilesMap, -// ...downloadedEspressoFilesMap, -// '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java': '../detox/src/android/espressoapi/DetoxAction.js', -// '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java': -// '../detox/src/android/espressoapi/DetoxViewActions.js', -// '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java': '../detox/src/android/espressoapi/DetoxMatcher.js', -// '../detox/android/detox/src/main/java/com/wix/detox/Detox.java': '../detox/src/android/espressoapi/Detox.js', -// '../detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java': '../detox/src/android/espressoapi/EspressoDetox.js', -// '../detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java': '../detox/src/android/espressoapi/UIAutomator.js' -// }; -// generateAndroidAdapters(androidFiles); +const downloadedAndroidFilesMap = Object + .entries(externalFilesToDownload) + .reduce(function (obj, [url, dest]) { + obj[downloadFile(url, 'base64')] = dest; + return obj; + }, {} +); + +const androidFiles = { + ...downloadedAndroidFilesMap, + ...downloadedEspressoFilesMap, + '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxAction.java': '../detox/src/android/espressoapi/DetoxAction.js', + '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxViewActions.java': + '../detox/src/android/espressoapi/DetoxViewActions.js', + '../detox/android/detox/src/main/java/com/wix/detox/espresso/DetoxMatcher.java': '../detox/src/android/espressoapi/DetoxMatcher.js', + '../detox/android/detox/src/main/java/com/wix/detox/Detox.java': '../detox/src/android/espressoapi/Detox.js', + '../detox/android/detox/src/main/java/com/wix/detox/espresso/EspressoDetox.java': '../detox/src/android/espressoapi/EspressoDetox.js', + '../detox/android/detox/src/main/java/com/wix/detox/uiautomator/UiAutomator.java': '../detox/src/android/espressoapi/UIAutomator.js' +}; +generateAndroidAdapters(androidFiles); diff --git a/generation/utils/__tests__/downloadEspresso.js b/generation/utils/__tests__/downloadEspresso.js deleted file mode 100644 index e441437b54..0000000000 --- a/generation/utils/__tests__/downloadEspresso.js +++ /dev/null @@ -1,30 +0,0 @@ -jest.mock("os", () => ({ - tmpdir: () => "/tmp/ponies" -})); -jest.mock("fs", () => ({ - writeFileSync: jest.fn() -})); - -jest.mock("download-file-sync", () => () => - "cGFja2FnZSBhbmRyb2lkLnN1cHBvcnQudGVzdC5lc3ByZXNzbzsNCmltcG9ydCBhbmRyb2lkLnZpZXcuVmlld0NvbmZpZ3VyYXRpb247DQoNCmltcG9ydCBvcmcuaGFtY3Jlc3QuTWF0Y2hlcjsNCg0KaW1wb3J0IGphdmEudXRpbC5MaXN0Ow0KDQovKioNCiAqIEVudHJ5IHBvaW50IHRvIHRoZSBFc3ByZXNzbyBmcmFtZXdvcmsuIFRlc3QgYXV0aG9ycyBjYW4gaW5pdGlhdGUgdGVzdGluZyBieSB1c2luZyBvbmUgb2YgdGhlIG9uKg0KICogbWV0aG9kcyAoZS5nLiBvblZpZXcpIG9yIHBlcmZvcm0gdG9wLWxldmVsIHVzZXIgYWN0aW9ucyAoZS5nLiBwcmVzc0JhY2spLg0KICovDQpwdWJsaWMgZmluYWwgY2xhc3MgRXNwcmVzc28gew0KDQogIHByaXZhdGUgc3RhdGljIGZpbmFsIEJhc2VMYXllckNvbXBvbmVudCBCQVNFID0gR3JhcGhIb2xkZXIuYmFzZUxheWVyKCk7DQogIHByaXZhdGUgc3RhdGljIGZpbmFsIElkbGluZ1Jlc291cmNlUmVnaXN0cnkgUkVHSVNUUlkgPSBCQVNFLmlkbGluZ1Jlc291cmNlUmVnaXN0cnkoKTsNCg0KICBwcml2YXRlIEVzcHJlc3NvKCkge30NCg0KICAvKioNCiAgICogQ3JlYXRlcyBhIHtAbGluayBWaWV3SW50ZXJhY3Rpb259IGZvciBhIGdpdmVuIHZpZXcuIE5vdGU6IHRoZSB2aWV3IGhhcw0KICAgKiB0byBiZSBwYXJ0IG9mIHRoZSAgdmlldyBoaWVyYXJjaHkuIFRoaXMgbWF5IG5vdCBiZSB0aGUgY2FzZSBpZiBpdCBpcyByZW5kZXJlZCBhcyBwYXJ0IG9mDQogICAqIGFuIEFkYXB0ZXJWaWV3IChlLmcuIExpc3RWaWV3KS4gSWYgdGhpcyBpcyB0aGUgY2FzZSwgdXNlIEVzcHJlc3NvLm9uRGF0YSB0byBsb2FkIHRoZSB2aWV3DQogICAqIGZpcnN0Lg0KICAgKg0KICAgKiBAcGFyYW0gdmlld01hdGNoZXIgdXNlZCB0byBzZWxlY3QgdGhlIHZpZXcuDQogICAqDQogICAqIEBzZWUgI29uRGF0YShvcmcuaGFtY3Jlc3QuTWF0Y2hlcikNCiAgICovDQogIC8vIFRPRE8gY2hhbmdlIHBhcmFtZXRlciB0byB0eXBlIHRvIE1hdGNoZXI8PyBleHRlbmRzIFZpZXc+IHdoaWNoIGN1cnJlbnRseSBjYXVzZXMgRGFnZ2VyIGlzc3Vlcw0KICBwdWJsaWMgc3RhdGljIFZpZXdJbnRlcmFjdGlvbiBvblZpZXcoZmluYWwgTWF0Y2hlcjxWaWV3PiB2aWV3TWF0Y2hlcikgew0KICAgIHJldHVybiBCQVNFLnBsdXMobmV3IFZpZXdJbnRlcmFjdGlvbk1vZHVsZSh2aWV3TWF0Y2hlcikpLnZpZXdJbnRlcmFjdGlvbigpOw0KICB9DQp9" -); - -const os = require("os"); -const fs = require("fs"); -const downloadEspresso = require("../downloadEspresso"); - -describe("downloadEspresso", () => { - beforeEach(() => { - downloadEspresso("foo.bar"); - }); - - it("should save the base64 decoded content to the temp dir file", () => { - expect(fs.writeFileSync).toHaveBeenCalled(); - const call = fs.writeFileSync.mock.calls[0]; - expect(call[0]).toContain("/tmp/ponies/"); - expect(call[0]).toContain(".java"); - expect(call[1]).toEqual( - expect.stringContaining("public final class Espresso {") - ); - }); -}); diff --git a/generation/utils/__tests__/downloadFile.js b/generation/utils/__tests__/downloadFile.js new file mode 100644 index 0000000000..77152438e8 --- /dev/null +++ b/generation/utils/__tests__/downloadFile.js @@ -0,0 +1,47 @@ +describe("download-file util", () => { + const OS_TMP_DIR = "/tmp/ponies"; + + let mockDownloadedContent; + let fs; + let downloadFile; + + beforeEach(() => { + jest.mock("os", () => ({ + tmpdir: jest.fn(), + })); + require("os").tmpdir.mockReturnValue(OS_TMP_DIR); + + jest.mock("fs", () => ({ + writeFileSync: jest.fn(), + })); + fs = require("fs"); + + jest.mock("download-file-sync", () => () => mockDownloadedContent); + + downloadFile = require("../downloadFile"); + }); + + it("should save content to the temp dir file", () => { + mockDownloadedContent = 'can haz teh c0dez'; + + downloadFile("foo.bar" /*, encoding = "none" */); + + expect(fs.writeFileSync).toHaveBeenCalled(); + const call = fs.writeFileSync.mock.calls[0]; + expect(call[0]).toContain(OS_TMP_DIR); + expect(call[0]).toContain(".java"); + expect(call[1]).toEqual(mockDownloadedContent); + }); + + it("should save the base64 decoded content to the temp dir file", () => { + mockDownloadedContent = "cGFja2FnZSBhbmRyb2lkLnN1cHBvcnQudGVzdC5lc3ByZXNzbzsNCmltcG9ydCBhbmRyb2lkLnZpZXcuVmlld0NvbmZpZ3VyYXRpb247DQoNCmltcG9ydCBvcmcuaGFtY3Jlc3QuTWF0Y2hlcjsNCg0KaW1wb3J0IGphdmEudXRpbC5MaXN0Ow0KDQovKioNCiAqIEVudHJ5IHBvaW50IHRvIHRoZSBFc3ByZXNzbyBmcmFtZXdvcmsuIFRlc3QgYXV0aG9ycyBjYW4gaW5pdGlhdGUgdGVzdGluZyBieSB1c2luZyBvbmUgb2YgdGhlIG9uKg0KICogbWV0aG9kcyAoZS5nLiBvblZpZXcpIG9yIHBlcmZvcm0gdG9wLWxldmVsIHVzZXIgYWN0aW9ucyAoZS5nLiBwcmVzc0JhY2spLg0KICovDQpwdWJsaWMgZmluYWwgY2xhc3MgRXNwcmVzc28gew0KDQogIHByaXZhdGUgc3RhdGljIGZpbmFsIEJhc2VMYXllckNvbXBvbmVudCBCQVNFID0gR3JhcGhIb2xkZXIuYmFzZUxheWVyKCk7DQogIHByaXZhdGUgc3RhdGljIGZpbmFsIElkbGluZ1Jlc291cmNlUmVnaXN0cnkgUkVHSVNUUlkgPSBCQVNFLmlkbGluZ1Jlc291cmNlUmVnaXN0cnkoKTsNCg0KICBwcml2YXRlIEVzcHJlc3NvKCkge30NCg0KICAvKioNCiAgICogQ3JlYXRlcyBhIHtAbGluayBWaWV3SW50ZXJhY3Rpb259IGZvciBhIGdpdmVuIHZpZXcuIE5vdGU6IHRoZSB2aWV3IGhhcw0KICAgKiB0byBiZSBwYXJ0IG9mIHRoZSAgdmlldyBoaWVyYXJjaHkuIFRoaXMgbWF5IG5vdCBiZSB0aGUgY2FzZSBpZiBpdCBpcyByZW5kZXJlZCBhcyBwYXJ0IG9mDQogICAqIGFuIEFkYXB0ZXJWaWV3IChlLmcuIExpc3RWaWV3KS4gSWYgdGhpcyBpcyB0aGUgY2FzZSwgdXNlIEVzcHJlc3NvLm9uRGF0YSB0byBsb2FkIHRoZSB2aWV3DQogICAqIGZpcnN0Lg0KICAgKg0KICAgKiBAcGFyYW0gdmlld01hdGNoZXIgdXNlZCB0byBzZWxlY3QgdGhlIHZpZXcuDQogICAqDQogICAqIEBzZWUgI29uRGF0YShvcmcuaGFtY3Jlc3QuTWF0Y2hlcikNCiAgICovDQogIC8vIFRPRE8gY2hhbmdlIHBhcmFtZXRlciB0byB0eXBlIHRvIE1hdGNoZXI8PyBleHRlbmRzIFZpZXc+IHdoaWNoIGN1cnJlbnRseSBjYXVzZXMgRGFnZ2VyIGlzc3Vlcw0KICBwdWJsaWMgc3RhdGljIFZpZXdJbnRlcmFjdGlvbiBvblZpZXcoZmluYWwgTWF0Y2hlcjxWaWV3PiB2aWV3TWF0Y2hlcikgew0KICAgIHJldHVybiBCQVNFLnBsdXMobmV3IFZpZXdJbnRlcmFjdGlvbk1vZHVsZSh2aWV3TWF0Y2hlcikpLnZpZXdJbnRlcmFjdGlvbigpOw0KICB9DQp9"; + + downloadFile("foo.bar", "base64"); + + expect(fs.writeFileSync).toHaveBeenCalled(); + const call = fs.writeFileSync.mock.calls[0]; + expect(call[1]).toEqual( + expect.stringContaining("public final class Espresso {") + ); + }); +}); diff --git a/generation/utils/downloadEspresso.js b/generation/utils/downloadEspresso.js index 8102d68427..7eec76e7a6 100644 --- a/generation/utils/downloadEspresso.js +++ b/generation/utils/downloadEspresso.js @@ -3,7 +3,5 @@ const downloadFile = require('./downloadFile'); module.exports = function downloadEspresso(fullyQualifiedClass) { const path = fullyQualifiedClass.replace(/\./g, '/'); - return downloadFile( - `http://android.googlesource.com/platform/frameworks/testing/+/android-support-test/espresso/core/src/main/java/${path}.java?format=TEXT` - ); + return downloadFile(`https://raw.githubusercontent.com/android/android-test/androidx-test-1.1.0/espresso/core/java/${path}.java`); }; diff --git a/generation/utils/downloadFile.js b/generation/utils/downloadFile.js index e3129fe769..367c528a4d 100644 --- a/generation/utils/downloadFile.js +++ b/generation/utils/downloadFile.js @@ -3,11 +3,15 @@ const fs = require('fs'); const uuidv4 = require('uuid/v4'); const downloadFileSync = require('download-file-sync'); -module.exports = function downloadJava(url) { +module.exports = function downloadJava(url, encoding = 'none') { const tmpDir = os.tmpdir(); const fileContent = downloadFileSync(url); - const result = Buffer.from(fileContent, 'base64').toString('ascii'); + let result = fileContent; + if (encoding === 'base64') { + result = Buffer.from(fileContent, 'base64').toString('ascii'); + } + const filePath = tmpDir + `/${uuidv4()}.java`; fs.writeFileSync(filePath, result); return filePath;