diff --git a/.travis.yml b/.travis.yml index 1a56b84280..97cb617942 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,12 +28,13 @@ matrix: - REACT_NATIVE_VERSION=0.49.3 android: components: - - build-tools-25.0.3 - - android-25 + - build-tools-27.0.2 + - build-tools-26.0.2 + - android-27 - extra-android-m2repository - extra-google-google_play_services - extra-google-m2repository - - sys-img-armeabi-v7a-android-26 + - sys-img-armeabi-v7a-android-27 install: - ./scripts/install.android.sh script: diff --git a/detox/android/build.gradle b/detox/android/build.gradle index 3d7ff75dad..046b3d1425 100644 --- a/detox/android/build.gradle +++ b/detox/android/build.gradle @@ -1,10 +1,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.palantir:jacoco-coverage:0.4.0' + classpath 'com.android.tools.build:gradle:3.0.1' } } @@ -12,8 +12,6 @@ allprojects { repositories { mavenLocal() jcenter() - maven { - url "https://maven.google.com" - } + google() } } diff --git a/detox/android/detox/build.gradle b/detox/android/detox/build.gradle index bdc6bf09dc..bf7a18319b 100644 --- a/detox/android/detox/build.gradle +++ b/detox/android/detox/build.gradle @@ -1,10 +1,8 @@ apply plugin: 'com.android.library' -apply plugin: 'com.palantir.jacoco-coverage' -apply plugin: 'com.palantir.jacoco-full-report' android { compileSdkVersion 25 - buildToolsVersion '25.0.3' + buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 18 targetSdkVersion 25 @@ -12,25 +10,19 @@ android { versionName "1.0" } - publishNonDefault true - productFlavors { - oldOkhttp { + flavorDimensions "minReactNative" + minReactNative44 { + dimension "minReactNative" } - newOkhttp { - + minReactNative46 { + dimension "minReactNative" } } testOptions { unitTests.returnDefaultValues = true - unitTests.all { - jacoco { - includeNoLocationClasses = true - } - } - unitTests.all { t -> reports { @@ -65,27 +57,21 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - + minReactNative44Implementation 'com.squareup.okhttp3:okhttp:3.4.1' + minReactNative44Implementation 'com.squareup.okhttp3:okhttp-ws:3.4.1' - oldOkhttpCompile 'com.squareup.okhttp3:okhttp:3.4.1' - oldOkhttpCompile 'com.squareup.okhttp3:okhttp-ws:3.4.1' + minReactNative46Implementation 'com.squareup.okhttp3:okhttp:3.6.0' + minReactNative46Implementation 'com.squareup.okio:okio:1.13.0' - newOkhttpCompile 'com.squareup.okhttp3:okhttp:3.6.0' - newOkhttpCompile 'com.squareup.okio:okio:1.13.0' - - compile('com.android.support.test.espresso:espresso-core:3.0.0', { + implementation('com.android.support.test.espresso:espresso-core:3.0.0', { exclude group: 'com.google.code.findbugs' }) - compile 'org.apache.commons:commons-lang3:3.4' - - compile 'com.android.support.test:runner:1.0' - compile 'com.android.support.test:rules:1.0' - compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' + implementation 'org.apache.commons:commons-lang3:3.4' + implementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3' - testCompile 'org.json:json:20140107' - testCompile 'junit:junit:4.12' - testCompile 'org.assertj:assertj-core:3.5.2' - testCompile 'org.apache.commons:commons-io:1.3.2' + testImplementation 'org.json:json:20140107' + testImplementation 'junit:junit:4.12' + testImplementation 'org.assertj:assertj-core:3.5.2' + testImplementation 'org.apache.commons:commons-io:1.3.2' } 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 1b45298d5d..7060b1d045 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 @@ -1,12 +1,10 @@ package com.wix.detox.espresso; -import android.app.UiAutomation; 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.support.test.uiautomator.InstrumentationUiAutomatorBridge; import android.util.DisplayMetrics; import android.util.Log; import android.view.Choreographer; @@ -26,9 +24,6 @@ public class UiAutomatorHelper { private static final String LOG_TAG = "detox"; - private static final String CLASS_INTERACTION_CONTROLLER = - "android.support.test.uiautomator.InteractionController"; - private static final String FIELD_UI_CONTROLLER = "uiController"; private static final String METHOD_LOOP_UNTIL_IDLE = "loopMainThreadUntilIdle"; @@ -76,31 +71,6 @@ public void run() { }); } - private static Object interactionController = null; - - public static Object getInteractionController() { - if (interactionController != null) { - return interactionController; - } - UiAutomation uiAutomation; - if (android.os.Build.VERSION.SDK_INT >= 24) { - uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); - } else { - uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - } - Context ctx = InstrumentationRegistry.getContext(); - InstrumentationUiAutomatorBridge bridge = new InstrumentationUiAutomatorBridge(ctx, uiAutomation); - Class interActionControllerClass; - try { - interActionControllerClass = Class.forName(CLASS_INTERACTION_CONTROLLER); - } catch (ClassNotFoundException e) { - Log.e(LOG_TAG, "Can't find InteractionController class. UiAutomator is not on classpath?", e); - throw new RuntimeException(e); - } - interactionController = Reflect.on(interActionControllerClass).create(bridge).get(); - return interactionController; - } - public static float getDensity() { Context context = InstrumentationRegistry.getTargetContext().getApplicationContext(); return context.getResources().getDisplayMetrics().density; diff --git a/detox/android/detox/src/oldOkhttp/java/com/wix/detox/WebSocketClient.java b/detox/android/detox/src/minReactNative44/java/com/wix/detox/WebSocketClient.java similarity index 100% rename from detox/android/detox/src/oldOkhttp/java/com/wix/detox/WebSocketClient.java rename to detox/android/detox/src/minReactNative44/java/com/wix/detox/WebSocketClient.java diff --git a/detox/android/detox/src/newOkhttp/java/com/wix/detox/WebSocketClient.java b/detox/android/detox/src/minReactNative46/java/com/wix/detox/WebSocketClient.java similarity index 100% rename from detox/android/detox/src/newOkhttp/java/com/wix/detox/WebSocketClient.java rename to detox/android/detox/src/minReactNative46/java/com/wix/detox/WebSocketClient.java diff --git a/detox/android/gradle/wrapper/gradle-wrapper.properties b/detox/android/gradle/wrapper/gradle-wrapper.properties index 873ba02e5c..9a8318f160 100644 --- a/detox/android/gradle/wrapper/gradle-wrapper.properties +++ b/detox/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jun 25 19:58:35 IDT 2017 +#Wed Dec 20 14:09:27 IST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/detox/src/devices/AndroidDriver.js b/detox/src/devices/AndroidDriver.js index fda0d6aed8..b5e7ddb461 100644 --- a/detox/src/devices/AndroidDriver.js +++ b/detox/src/devices/AndroidDriver.js @@ -1,4 +1,6 @@ const {spawn} = require('child_process'); +const path = require('path'); +const fs = require('fs'); const _ = require('lodash'); const log = require('npmlog'); const invoke = require('../invoke'); @@ -27,8 +29,20 @@ class AndroidDriver extends DeviceDriverBase { async installApp(deviceId, binaryPath) { await this.adb.install(deviceId, binaryPath); - const testApkPath = binaryPath.split('.apk')[0] + '-androidTest.apk'; - await this.adb.install(deviceId, testApkPath); + await this.adb.install(deviceId, this.getTestApkPath(binaryPath)); + } + + getTestApkPath(originalApkPath) { + const originalApkPathObj = path.parse(originalApkPath); + let splitPath = originalApkPathObj.dir.split(path.sep); + splitPath.splice(splitPath.length-1 , 0, 'androidTest'); + const testApkPath = path.join(splitPath.join(path.sep), `${originalApkPathObj.name}-androidTest${originalApkPathObj.ext}`); + + if (!fs.existsSync(testApkPath)) { + throw new Error(`'${testApkPath}' could not be found, did you run './gradlew assembleAndroidTest' ?`); + } + + return testApkPath; } async uninstallApp(deviceId, bundleId) { diff --git a/detox/src/devices/android/Emulator.js b/detox/src/devices/android/Emulator.js index d34fb9ef7e..a065ab7e98 100644 --- a/detox/src/devices/android/Emulator.js +++ b/detox/src/devices/android/Emulator.js @@ -56,7 +56,7 @@ class Emulator { tail.unwatch(); fs.closeSync(stdout); fs.closeSync(stderr); - fs.unlink(tempLog); + fs.unlink(tempLog, () => {}); promise._cpResolve(); } diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index 5d803872a2..30858e59d7 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -3,13 +3,13 @@ apply plugin: "com.android.application" apply from: "../../node_modules/react-native/react.gradle" android { - compileSdkVersion 25 - buildToolsVersion '25.0.3' + compileSdkVersion 27 + buildToolsVersion '27.0.2' defaultConfig { applicationId "com.wix.detox.test" minSdkVersion 18 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 1 versionName "1.0" ndk { @@ -17,6 +17,7 @@ android { } testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + missingDimensionStrategy "minReactNative", "minReactNative46" /* testInstrumentationRunnerArguments = [ 'detoxServer': 'ws://localhost:8099', @@ -25,9 +26,6 @@ android { */ } - //unremark to generate app-release-androidTest.apk for release tests - //testBuildType "release" - signingConfigs { release { storeFile file("keystore.jks") @@ -52,15 +50,13 @@ android { } dependencies { - compile fileTree(dir: "libs", include: ["*.jar"]) - compile "com.android.support:appcompat-v7:25.3.1" - compile "com.facebook.react:react-native:+" // From node_modules - - testCompile 'junit:junit:4.12' + implementation "com.android.support:appcompat-v7:27.0.2" + implementation "com.facebook.react:react-native:+" // From node_modules - androidTestCompile(project(path: ":detox", configuration: "newOkhttpDebug"), { - exclude group: 'com.android.support', module: 'support-annotations' - }) + 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' } // Run this once to be able to run the application with BUCK diff --git a/detox/test/android/build.gradle b/detox/test/android/build.gradle index 2b7df2c496..8f3a5f42a7 100644 --- a/detox/test/android/build.gradle +++ b/detox/test/android/build.gradle @@ -1,10 +1,10 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.palantir:jacoco-coverage:0.4.0' + classpath 'com.android.tools.build:gradle:3.0.1' } } @@ -12,9 +12,7 @@ allprojects { repositories { mavenLocal() jcenter() - maven { - url "https://maven.google.com" - } + google() maven { url "$projectDir/../../node_modules/react-native/android" } diff --git a/detox/test/android/gradle.properties b/detox/test/android/gradle.properties index 21edee9d37..935168d5f5 100644 --- a/detox/test/android/gradle.properties +++ b/detox/test/android/gradle.properties @@ -18,3 +18,4 @@ # org.gradle.parallel=true android.useDeprecatedNdk=true +android.enableAapt2=false \ No newline at end of file diff --git a/detox/test/android/gradle/wrapper/gradle-wrapper.properties b/detox/test/android/gradle/wrapper/gradle-wrapper.properties index c6cbefef30..749eaf0e74 100644 --- a/detox/test/android/gradle/wrapper/gradle-wrapper.properties +++ b/detox/test/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/detox/test/package.json b/detox/test/package.json index ab8842aa19..95bed81220 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -50,13 +50,13 @@ } }, "android.emu.debug": { - "binaryPath": "android/app/build/outputs/apk/app-debug.apk", + "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", "type": "android.emulator", "name": "Nexus_5X_API_24" }, "android.emu.release": { - "binaryPath": "android/app/build/outputs/apk/app-release.apk", + "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", "build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", "type": "android.emulator", "name": "Nexus_5X_API_26" diff --git a/docs/Introduction.Android.md b/docs/Introduction.Android.md index f9fd18509b..691fa9eda2 100644 --- a/docs/Introduction.Android.md +++ b/docs/Introduction.Android.md @@ -1,85 +1,103 @@ -# Adding Android +# Detox for Android ## Setup +Detox 7 was updated to support Android gradle plugin 3.0.0. This is a breaking change that makes it impossible to support previous Android gradle plugin versions. + +https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html + +For older Android gradle plugin support use `detox@6.x.x` instead ([previous setup guide here](https://github.com/wix/detox/blob/97654071573053def90e8207be8eba011408f977/docs/Introduction.Android.md)).
+**Detox 6 will not continue to be updated, to continue getting updates and features, update your Android gradle config and migrate to Detox 7.** ### 1. Do the initial setup described in the Getting Started Guide - [Getting Started](Introduction.GettingStarted.md) -### 2. Add the detox Android project as an androidTestCompile dependency +### 2. Add Detox dependency to an Android project + +In `android/settings.gradle` add: -You need to add this into your `android/settings.gradle`: ```gradle include ':detox' project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') ``` -> In case your project’s RN version is at least 0.46.0 change the oldOkhttp configuration string to newOkhttp, in the `app/build.gradle` here. - -In the `android/app/build.gradle` you need to add this into your dependencies section: +In `android/app/build.gradle` add this to `defaultConfig` section: ```gradle -androidTestCompile(project(path: ":detox", configuration: "newOkhttpDebug"), { - exclude group: 'com.android.support', module: 'support-annotations' -}) + defaultConfig { + ... + 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" + ... + } ``` - Please be aware that the `minSdkVersion` needs to be at least 18. -### 3. Add `jacoco-coverage` as dependency in the buildscript +> ###### Choosing the right build type (in missingDimensionStrategy) +>Detox runs on multiple React Native versions, choose the correct build type to support the version you use.
+>**Available versions:** +> +>* `minReactNative44`: Support for React Native 0.44-0.45 +>* `minReactNative46`: Support for React Native 0.46+ -You need to add this to `android/build.gradle` into `buildscript > dependencies`: -```gradle -classpath 'com.palantir:jacoco-coverage:0.4.0' -``` +In `android/app/build.gradle` add this in `dependencies` section: -And in the same file you need to add this under `allprojects > repositories`: ```gradle -maven { - url "https://maven.google.com" +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' + ... } ``` -### 4. Introduce [Espresso](https://developer.android.com/training/testing/espresso/index.html) test runner +In `android/build.gradle` add this to`buildscript > dependencies`: -Detox Android is a standard Android integration test. Although, it is completely asynchronous. +```gradle +classpath 'com.palantir:jacoco-coverage:0.4.0' +``` -It uses Espresso internally, therefore you have to use an AndroidJUnitRunner as your test runner (or a subclass of it). -For this you need to modify your `android/app/build.gradle`: +And in the same file you need to add this under `allprojects > repositories`: -```gradle -android { - defaultConfig { - testBuildType System.getProperty('testBuildType', 'debug') //this will later be used to control the test apk build type - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" +```gradle +buildscript { + repositories { + ... + google() + ... } } ``` -### 5. Create Android Test class +### 3. Create Android Test class You need to add the file `android/app/src/androidTest/java/com/[your.package]/DetoxTest.java` and fill it like [this](../detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java), expect that you need to change the package to your projects name. -### 6. Add Android configuration +### 4. Add Android configuration Add this part to your `package.json`: ```json -"detox": { +"detox" : { "configurations": { "android.emu.debug": { - "binaryPath": "android/app/build/outputs/apk/app-debug.apk", - "build": "pushd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && popd", + "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", + "build": + "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", "type": "android.emulator", - "name": "Nexus_5X_API_25" + "name": "Nexus_5X_API_24" }, "android.emu.release": { - "binaryPath": "android/app/build/outputs/apk/app-debug.apk", - "build": "pushd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && popd", - "type": "android.emulator", - "name": "Nexus_5X_API_25" - } + "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", + "build": + "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", + "type": "android.emulator", + "name": "Nexus_5X_API_26" + } } } ``` @@ -93,7 +111,7 @@ Following device types could be used to control Android devices: `android.attached`. Connect to already-attached android device. The device should be listed in the output of `adb devices` command under provided `name`. Use this type to connect to Genymotion emulator. -### 7. Run the tests +### 5. Run the tests Using the `android.emu.debug` configuration from above, you can invoke it in the standard way. diff --git a/scripts/testProjRN49to44.diff b/scripts/testProjRN49to44.diff index acb32c97d6..eb1a25e610 100644 --- a/scripts/testProjRN49to44.diff +++ b/scripts/testProjRN49to44.diff @@ -1,16 +1,16 @@ diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle -index 5d80387..dceb441 100644 +index 30858e5..1a62967 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle -@@ -58,7 +58,7 @@ dependencies { - - testCompile 'junit:junit:4.12' - -- androidTestCompile(project(path: ":detox", configuration: "newOkhttpDebug"), { -+ androidTestCompile(project(path: ":detox", configuration: "oldOkhttpDebug"), { - exclude group: 'com.android.support', module: 'support-annotations' - }) - } +@@ -17,7 +17,7 @@ android { + } + testBuildType System.getProperty('testBuildType', 'debug') + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" +- missingDimensionStrategy "minReactNative", "minReactNative46" ++ missingDimensionStrategy "minReactNative", "minReactNative44" + /* + testInstrumentationRunnerArguments = [ + 'detoxServer': 'ws://localhost:8099', diff --git a/detox/test/android/app/src/main/java/com/example/NativeModulePackage.java b/detox/test/android/app/src/main/java/com/example/NativeModulePackage.java index 83bc447..410b8fc 100644 --- a/detox/test/android/app/src/main/java/com/example/NativeModulePackage.java