diff --git a/.travis.yml b/.travis.yml index 8c0af5731..8754b0e89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,12 @@ language: android +addons: + apt: + packages: + - w3m +env: + global: + - ANDROID_TARGET=android-22 + - ANDROID_ABI=armeabi-v7a android: components: - platform-tools @@ -6,8 +14,20 @@ android: - build-tools-25.0.1 - extra-google-m2repository - extra-android-m2repository + - extra-google-google_play_services + - extra-android-support + - ${ANDROID_TARGET} - android-25 - - sys-img-x86-android-18 + - sys-img-${ANDROID_ABI}-${ANDROID_TARGET} +before_script: + - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI + - emulator -avd test -no-audio -no-window & + - android-wait-for-emulator + - adb shell input keyevent 82 & +script: + - ./gradlew test connectedAndroidTest -stacktrace +after_failure: + - w3m -dump ${TRAVIS_BUILD_DIR}/app/build/reports/androidTests/connected/*Test.html jdk: # - openjdk8 # not yet available - oraclejdk8 diff --git a/app/build.gradle b/app/build.gradle index fb42cd2a9..4500d9cf5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,11 +13,14 @@ dependencies { compile "com.android.support:support-v4:${project.supportLibVersion}" compile "com.android.support:appcompat-v7:${project.supportLibVersion}" compile "com.android.support:design:${project.supportLibVersion}" + compile "com.android.support:support-annotations:${project.supportLibVersion}" compile 'com.google.code.gson:gson:2.7' compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION" annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION" testCompile 'junit:junit:4.12' + androidTestCompile "com.android.support:support-annotations:${project.supportLibVersion}" + androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' } android { @@ -32,6 +35,7 @@ android { versionName '2.2' minSdkVersion project.minSdkVersion targetSdkVersion project.targetSdkVersion + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/androidTest/java/fr/free/nrw/commons/SettingsActivityTest.java b/app/src/androidTest/java/fr/free/nrw/commons/SettingsActivityTest.java new file mode 100644 index 000000000..dc7ead0ab --- /dev/null +++ b/app/src/androidTest/java/fr/free/nrw/commons/SettingsActivityTest.java @@ -0,0 +1,117 @@ +package fr.free.nrw.commons; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anyOf; +import static org.hamcrest.Matchers.anything; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.support.test.espresso.Espresso; +import android.support.test.espresso.action.ViewActions; +import android.support.test.espresso.assertion.ViewAssertions; +import android.support.test.espresso.matcher.ViewMatchers; +import android.support.test.filters.LargeTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; + +import fr.free.nrw.commons.settings.SettingsActivity; + +import java.util.Map; + +import org.hamcrest.Matcher; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class SettingsActivityTest { + private SharedPreferences prefs; + private Map prefValues; + + @Rule + public ActivityTestRule activityRule = + new ActivityTestRule(SettingsActivity.class, + false /* Initial touch mode */, true /* launch activity */) { + + @Override + protected void afterActivityLaunched() { + // save preferences + prefs = PreferenceManager.getDefaultSharedPreferences(this.getActivity()); + prefValues = prefs.getAll(); + } + + @Override + protected void afterActivityFinished() { + // restore preferences + SharedPreferences.Editor editor = prefs.edit(); + for (Map.Entry entry: prefValues.entrySet()) { + String key = entry.getKey(); + Object val = entry.getValue(); + if (val instanceof String) { + editor.putString(key, (String)val); + } else if (val instanceof Boolean) { + editor.putBoolean(key, (Boolean)val); + } else if (val instanceof Integer) { + editor.putInt(key, (Integer)val); + } else { + throw new RuntimeException("type not implemented: " + entry); + } + } + editor.apply(); + } + }; + + @Test + public void oneLicenseIsChecked() { + // click "License" (the first item) + Espresso.onData(anything()) + .inAdapterView(findPreferenceList()) + .atPosition(0) + .perform(ViewActions.click()); + + // test the selected item + Espresso.onView(ViewMatchers.isChecked()) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())); + } + + @Test + public void afterClickingCcby4ItWillStay() { + // click "License" (the first item) + Espresso.onData(anything()) + .inAdapterView(findPreferenceList()) + .atPosition(0) + .perform(ViewActions.click()); + + // click "CC BY-4.0" + Espresso.onView( + // FIXME: just R.string.license_name_cc_by_four should be fine but fails on Travis + textAnyOf(R.string.license_name_cc_by_four, R.string.license_name_cc_by_4_0) + ).perform(ViewActions.click()); + + // click "License" (the first item) + Espresso.onData(anything()) + .inAdapterView(findPreferenceList()) + .atPosition(0) + .perform(ViewActions.click()); + + // test the value remains "CC BY-4.0" + Espresso.onView(ViewMatchers.isChecked()) + .check(ViewAssertions.matches( + textAnyOf(R.string.license_name_cc_by_four, R.string.license_name_cc_by_4_0) + )); + } + + private Matcher textAnyOf(int id1, int id2) { + return anyOf(ViewMatchers.withText(id1), ViewMatchers.withText(id2)); + } + + private static Matcher findPreferenceList() { + return allOf( + ViewMatchers.isDescendantOfA(ViewMatchers.withId(android.R.id.content)), + ViewMatchers.withId(android.R.id.list), + ViewMatchers.hasFocus() + ); + } +} diff --git a/script/style/checkstyle.xml b/script/style/checkstyle.xml index 339d9131f..a9e48a4fe 100644 --- a/script/style/checkstyle.xml +++ b/script/style/checkstyle.xml @@ -80,7 +80,8 @@ - + +