From d0c2c030577329cf885a21abb9a5c45a304a9061 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 24 Jul 2018 14:04:23 -0300 Subject: [PATCH 01/10] First prototype of Espresso test infrastructure with automatic screenshoting --- bramble-android/build.gradle | 6 + briar-android/build.gradle | 18 +++ briar-android/fastlane/Screengrabfile | 5 + briar-android/proguard-test.txt | 15 +++ .../briar/android/BriarTestApplication.java | 20 ++++ .../briar/android/BriarTestComponent.java | 23 ++++ .../briar/android/settings/DarkThemeTest.java | 89 +++++++++++++++ .../briar/android/test/BriarTestRunner.java | 20 ++++ .../briar/android/test/ScreenshotTest.java | 108 ++++++++++++++++++ .../briar/android/test/ViewActions.java | 104 +++++++++++++++++ .../briar/android/BriarApplicationImpl.java | 13 ++- .../briar/android/util/UiUtils.java | 2 + .../src/screenshot/AndroidManifest.xml | 16 +++ 13 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 briar-android/fastlane/Screengrabfile create mode 100644 briar-android/proguard-test.txt create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java create mode 100644 briar-android/src/screenshot/AndroidManifest.xml diff --git a/bramble-android/build.gradle b/bramble-android/build.gradle index f7c9415ed..0e6e49e17 100644 --- a/bramble-android/build.gradle +++ b/bramble-android/build.gradle @@ -15,6 +15,12 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + buildTypes { + debug + screenshot + release + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 77b2fcf6e..7d0714bb7 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -49,6 +49,14 @@ dependencies { testImplementation "org.jmock:jmock-legacy:2.8.2" testImplementation "org.hamcrest:hamcrest-library:1.3" testImplementation "org.hamcrest:hamcrest-core:1.3" + + def espressoVersion = '3.0.2' + androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion" + androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion" + androidTestImplementation "tools.fastlane:screengrab:1.1.0" + androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2" + androidTestCompileOnly 'javax.annotation:jsr250-api:1.0' + androidTestImplementation 'junit:junit:4.12' } dependencyVerification { @@ -248,6 +256,7 @@ android { def now = (long) (System.currentTimeMillis() / 1000) buildConfigField "Long", "BuildTimestamp", "${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L" + testInstrumentationRunner 'org.briarproject.briar.android.test.BriarTestRunner' } buildTypes { @@ -260,6 +269,13 @@ android { crunchPngs false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } + screenshot { + initWith debug + applicationIdSuffix ".screenshot" + resValue "string", "app_package", "org.briarproject.briar.android.screenshot" + resValue "string", "app_name", "Briar Screenshot" + testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-test.txt' + } release { shrinkResources false minifyEnabled true @@ -268,6 +284,8 @@ android { } } + testBuildType "screenshot" + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/briar-android/fastlane/Screengrabfile b/briar-android/fastlane/Screengrabfile new file mode 100644 index 000000000..690bc4cc8 --- /dev/null +++ b/briar-android/fastlane/Screengrabfile @@ -0,0 +1,5 @@ +app_package_name "org.briarproject.briar.android.screenshot" +locales ['en-US'] +app_apk_path "build/outputs/apk/screenshot/briar-android-screenshot.apk" +tests_apk_path "build/outputs/apk/androidTest/screenshot/briar-android-screenshot-androidTest.apk" +test_instrumentation_runner "org.briarproject.briar.android.test.BriarTestRunner" \ No newline at end of file diff --git a/briar-android/proguard-test.txt b/briar-android/proguard-test.txt new file mode 100644 index 000000000..7007db0c2 --- /dev/null +++ b/briar-android/proguard-test.txt @@ -0,0 +1,15 @@ +-dontwarn android.test.** +-dontwarn android.support.test.** +-dontnote android.support.test.** +-dontwarn com.googlecode.eyesfree.compat.CompatUtils + +-keep class org.xmlpull.v1.** { *; } +-dontwarn org.xmlpull.v1.** + +-keep class org.junit.** { *; } +-dontwarn org.junit.** + +-keep class junit.** { *; } +-dontwarn junit.** + +-dontwarn org.briarproject.briar.android.BriarTestApplication \ No newline at end of file diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java new file mode 100644 index 000000000..8bdd5b63a --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java @@ -0,0 +1,20 @@ +package org.briarproject.briar.android; + +import org.briarproject.bramble.BrambleCoreModule; +import org.briarproject.briar.BriarCoreModule; + +public class BriarTestApplication extends BriarApplicationImpl { + + @Override + protected AndroidComponent createApplicationComponent() { + AndroidComponent component = DaggerBriarTestComponent.builder() + .appModule(new AppModule(this)).build(); + // We need to load the eager singletons directly after making the + // dependency graphs + BrambleCoreModule.initEagerSingletons(component); + BriarCoreModule.initEagerSingletons(component); + AndroidEagerSingletons.initEagerSingletons(component); + return component; + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java new file mode 100644 index 000000000..3b1ba59fd --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java @@ -0,0 +1,23 @@ +package org.briarproject.briar.android; + +import org.briarproject.bramble.BrambleAndroidModule; +import org.briarproject.bramble.BrambleCoreModule; +import org.briarproject.briar.BriarCoreModule; +import org.briarproject.briar.android.settings.DarkThemeTest; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + AppModule.class, + BriarCoreModule.class, + BrambleAndroidModule.class, + BrambleCoreModule.class +}) +public interface BriarTestComponent extends AndroidComponent { + + void inject(DarkThemeTest test); + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java new file mode 100644 index 000000000..274c6e5c0 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java @@ -0,0 +1,89 @@ +package org.briarproject.briar.android.settings; + +import android.content.Intent; +import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.Gravity; + +import junit.framework.AssertionFailedError; + +import org.briarproject.briar.R; +import org.briarproject.briar.android.BriarTestComponent; +import org.briarproject.briar.android.navdrawer.NavDrawerActivity; +import org.briarproject.briar.android.test.ScreenshotTest; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; + +@RunWith(AndroidJUnit4.class) +public class DarkThemeTest extends ScreenshotTest { + + @Rule + public ActivityTestRule activityRule = + new ActivityTestRule<>(SettingsActivity.class); + + @Override + protected void inject(BriarTestComponent component) { + component.inject(this); + } + + @Before + public void waitForSignIn() { + onView(isRoot()) + .perform(waitForActivityToResume(activityRule.getActivity())); + } + + @Test + public void changeTheme() { + onView(withText(R.string.settings_button)) + .check(matches(isDisplayed())); + onView(withText(R.string.pref_theme_title)) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(R.string.pref_theme_light)) + .check(matches(isDisplayed())) + .perform(click()); + + screenshot("dark_theme_settings"); + + onView(withText(R.string.pref_theme_title)) + .check(matches(isDisplayed())) + .perform(click()); + onView(withText(R.string.pref_theme_dark)) + .check(matches(isDisplayed())) + .perform(click()); + + Intent i = + new Intent(activityRule.getActivity(), NavDrawerActivity.class); + activityRule.getActivity().startActivity(i); + + try { + onView(withId(R.id.expiryWarningClose)) + .check(matches(isDisplayed())); + onView(withId(R.id.expiryWarningClose)) + .perform(click()); + } catch (AssertionFailedError e){ + // TODO remove try block when starting with fresh account + // ignore since we already removed the expiry warning + } + + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + + screenshot("dark_theme_nav_drawer"); + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java new file mode 100644 index 000000000..cefb68766 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java @@ -0,0 +1,20 @@ +package org.briarproject.briar.android.test; + +import android.app.Application; +import android.content.Context; +import android.support.test.runner.AndroidJUnitRunner; + +import org.briarproject.briar.android.BriarTestApplication; + +public class BriarTestRunner extends AndroidJUnitRunner { + + @Override + public Application newApplication(ClassLoader cl, String className, + Context context) + throws InstantiationException, IllegalAccessException, + ClassNotFoundException { + return super.newApplication(cl, BriarTestApplication.class.getName(), + context); + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java new file mode 100644 index 000000000..b5a71e845 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java @@ -0,0 +1,108 @@ +package org.briarproject.briar.android.test; + +import android.support.test.InstrumentationRegistry; +import android.support.test.espresso.NoMatchingViewException; +import android.util.Log; + +import org.briarproject.briar.R; +import org.briarproject.briar.android.BriarTestApplication; +import org.briarproject.briar.android.BriarTestComponent; +import org.junit.Before; +import org.junit.ClassRule; + +import tools.fastlane.screengrab.Screengrab; +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; +import tools.fastlane.screengrab.locale.LocaleTestRule; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static tools.fastlane.screengrab.Screengrab.setDefaultScreenshotStrategy; + +public abstract class ScreenshotTest { + + @ClassRule + public static final LocaleTestRule localeTestRule = new LocaleTestRule(); + + @Before + public void setupScreenshots() { + setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); + } + + private static final String USERNAME = "test"; + private static final String PASSWORD = "123456"; + + private final BriarTestApplication app = + (BriarTestApplication) InstrumentationRegistry.getTargetContext() + .getApplicationContext(); + + protected abstract void inject(BriarTestComponent component); + + /** + * Signs the user in. + * + * Note that you need to wait for your UI to show up after this. + * See {@link ViewActions#waitForActivityToResume} for one way to do it. + */ + @Before + public void signIn() throws Exception { + inject((BriarTestComponent) app.getApplicationComponent()); + + try { + onView(withId(R.id.edit_password)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.btn_sign_in)) + .check(matches(isDisplayed())) + .perform(click()); + } catch (NoMatchingViewException e) { + // we start from a blank state and have no account, yet + createAccount(); + } + } + + private void createAccount() { + // TODO use AccountManager to start with fresh account + // TODO move this below into a dedicated test for SetupActivity + + // Enter username + onView(withText(R.string.setup_title)) + .check(matches(isDisplayed())); + onView(withId(R.id.nickname_entry)) + .check(matches(isDisplayed())) + .perform(typeText(USERNAME)); + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + + // Enter password + onView(withId(R.id.password_entry)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.password_confirm)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + onView(withId(R.id.progress)) + .check(matches(isDisplayed())); + } + + protected void screenshot(String name) { + try { + Screengrab.screenshot(name); + } catch (RuntimeException e) { + if (!e.getMessage().equals("Unable to capture screenshot.")) + throw e; + // The tests should still pass when run from AndroidStudio + // without manually granting permissions like fastlane does. + Log.w("Screengrab", "Permission to write screenshot is missing."); + } + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java new file mode 100644 index 000000000..806124d1b --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java @@ -0,0 +1,104 @@ +package org.briarproject.briar.android.test; + +import android.app.Activity; +import android.support.test.espresso.PerformException; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.runner.lifecycle.ActivityLifecycleMonitor; +import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; +import android.view.View; + +import org.hamcrest.Matcher; + +import java.util.concurrent.TimeoutException; + +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.util.HumanReadables.describe; +import static android.support.test.espresso.util.TreeIterables.breadthFirstViewTraversal; +import static android.support.test.runner.lifecycle.Stage.RESUMED; +import static java.lang.System.currentTimeMillis; +import static java.util.concurrent.TimeUnit.SECONDS; + +public class ViewActions { + + private final static long TIMEOUT_MS = SECONDS.toMillis(5); + private final static long WAIT_MS = 50; + + public static ViewAction waitUntilMatches(Matcher viewMatcher) { + return waitUntilMatches(viewMatcher, TIMEOUT_MS); + } + + private static ViewAction waitUntilMatches(Matcher viewMatcher, + long timeout) { + return new ViewAction() { + @Override + public Matcher getConstraints() { + return isRoot(); + } + + @Override + public String getDescription() { + return "Wait for view matcher " + viewMatcher + + " to match within " + timeout + " milliseconds."; + } + + @Override + public void perform(final UiController uiController, + final View view) { + uiController.loopMainThreadUntilIdle(); + long endTime = currentTimeMillis() + timeout; + + do { + for (View child : breadthFirstViewTraversal(view)) { + if (viewMatcher.matches(child)) return; + } + uiController.loopMainThreadForAtLeast(WAIT_MS); + } + while (currentTimeMillis() < endTime); + + throw new PerformException.Builder() + .withActionDescription(getDescription()) + .withViewDescription(describe(view)) + .withCause(new TimeoutException()) + .build(); + } + }; + } + + public static ViewAction waitForActivityToResume(Activity activity) { + return new ViewAction() { + @Override + public Matcher getConstraints() { + return isRoot(); + } + + @Override + public String getDescription() { + return "Wait for activity " + activity.getClass().getName() + + " to resume within " + TIMEOUT_MS + " milliseconds."; + } + + @Override + public void perform(final UiController uiController, + final View view) { + uiController.loopMainThreadUntilIdle(); + long endTime = currentTimeMillis() + TIMEOUT_MS; + ActivityLifecycleMonitor lifecycleMonitor = + ActivityLifecycleMonitorRegistry.getInstance(); + do { + if (lifecycleMonitor.getLifecycleStageOf(activity) == + RESUMED) return; + uiController.loopMainThreadForAtLeast(WAIT_MS); + } + while (currentTimeMillis() < endTime); + + throw new PerformException.Builder() + .withActionDescription(getDescription()) + .withViewDescription(describe(view)) + .withCause(new TimeoutException()) + .build(); + } + }; + } + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java index 08fc14b5d..e56adf30e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarApplicationImpl.java @@ -109,15 +109,20 @@ public class BriarApplicationImpl extends Application LOG.info("Created"); - applicationComponent = DaggerAndroidComponent.builder() + applicationComponent = createApplicationComponent(); + } + + protected AndroidComponent createApplicationComponent() { + AndroidComponent androidComponent = DaggerAndroidComponent.builder() .appModule(new AppModule(this)) .build(); // We need to load the eager singletons directly after making the // dependency graphs - BrambleCoreModule.initEagerSingletons(applicationComponent); - BriarCoreModule.initEagerSingletons(applicationComponent); - AndroidEagerSingletons.initEagerSingletons(applicationComponent); + BrambleCoreModule.initEagerSingletons(androidComponent); + BriarCoreModule.initEagerSingletons(androidComponent); + AndroidEagerSingletons.initEagerSingletons(androidComponent); + return androidComponent; } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index ee30d8d37..2485f81c9 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -55,6 +55,7 @@ import static android.text.format.DateUtils.FORMAT_SHOW_DATE; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static org.briarproject.briar.BuildConfig.APPLICATION_ID; +import static org.briarproject.briar.BuildConfig.BUILD_TYPE; import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE; @MethodsNotNullByDefault @@ -174,6 +175,7 @@ public class UiUtils { public static boolean needsDozeWhitelisting(Context ctx) { if (SDK_INT < 23) return false; + if (BUILD_TYPE.equals("screenshot")) return false; PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE); String packageName = ctx.getPackageName(); if (pm == null) throw new AssertionError(); diff --git a/briar-android/src/screenshot/AndroidManifest.xml b/briar-android/src/screenshot/AndroidManifest.xml new file mode 100644 index 000000000..266a92823 --- /dev/null +++ b/briar-android/src/screenshot/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + From be2d6951508f158f40537de5e3b4a9cd1c38f445 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 25 Jul 2018 16:29:52 -0300 Subject: [PATCH 02/10] Setup fastlane This is great for automatically uploading (localized) screenshots and app metadata to Google Play. You can even upload the signed APK releases as well. For now, this is only useful for running the screenshot Espresso tests and grabbing the screenshots from the device. --- .gitignore | 9 +++- briar-android/fastlane/Appfile | 2 + briar-android/fastlane/Fastfile | 28 ++++++++++++ briar-android/fastlane/rename_screenshots.py | 43 +++++++++++++++++++ .../briar/android/settings/DarkThemeTest.java | 4 +- 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 briar-android/fastlane/Appfile create mode 100644 briar-android/fastlane/Fastfile create mode 100755 briar-android/fastlane/rename_screenshots.py diff --git a/.gitignore b/.gitignore index b40390a31..8f2bfafc3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,5 +23,12 @@ local.properties !.idea/codeStyles .gradle build/ +captures *.iml -projectFilesBackup/ \ No newline at end of file +projectFilesBackup/ + +# Fastlane Non-Google Play Screenshots +briar-android/fastlane/metadata/android/screenshots.html +briar-android/fastlane/metadata/android/*/images/phoneScreenshots/manual_*.png +briar-android/fastlane/report.xml +briar-android/fastlane/README.md \ No newline at end of file diff --git a/briar-android/fastlane/Appfile b/briar-android/fastlane/Appfile new file mode 100644 index 000000000..05204c92c --- /dev/null +++ b/briar-android/fastlane/Appfile @@ -0,0 +1,2 @@ +json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one +package_name("org.briarproject.briar.android") diff --git a/briar-android/fastlane/Fastfile b/briar-android/fastlane/Fastfile new file mode 100644 index 000000000..3646c37a6 --- /dev/null +++ b/briar-android/fastlane/Fastfile @@ -0,0 +1,28 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:android) + +platform :android do + desc "Takes screenshots for manual and Google Play" + lane :screenshots do + gradle(project_dir: "..", task: "assembleScreenshot assembleAndroidTest") + capture_android_screenshots + system './rename_screenshots.py' + end +end + + +# vi:syntax=ruby diff --git a/briar-android/fastlane/rename_screenshots.py b/briar-android/fastlane/rename_screenshots.py new file mode 100755 index 000000000..f1f0485fa --- /dev/null +++ b/briar-android/fastlane/rename_screenshots.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# Author: Torsten Grote +# License: GPLv3 or later + +import os +import re +import glob + +METADATA_PATH = 'metadata/android' +GLOB = '/*/images/phoneScreenshots/*.png' + +REGEX = re.compile(r'(^\w+)_\d{13}\.png$') +REGEX_IN_FILE = re.compile(r'(\w+)_\d{13}\.png', re.MULTILINE) +PATH = os.path.dirname(os.path.realpath(__file__)) + + +def main(): + for path in glob.glob("%s%s" % (os.path.join(PATH, METADATA_PATH), GLOB)): + filename = os.path.basename(path) + match = REGEX.match(filename) + if match: + directory = os.path.dirname(path) + new_filename = "%s.png" % match.group(1) + new_path = os.path.join(directory, new_filename) + os.rename(path, new_path) + print("Renaming\n %s\nto\n %s\n" % (path, new_path)) + else: + print("Warning: Path did not match %s" % path) + + # rename fields also in screenshot overview file + overview = os.path.join(PATH, METADATA_PATH, 'screenshots.html') + with open(overview, 'r') as f: + file_data = f.read() + + file_data = REGEX_IN_FILE.sub(r'\1.png', file_data) + + with open(overview, 'w') as f: + f.write(file_data) + + +if __name__ == "__main__": + main() diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java index 274c6e5c0..3989d2f97 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java @@ -56,7 +56,7 @@ public class DarkThemeTest extends ScreenshotTest { .check(matches(isDisplayed())) .perform(click()); - screenshot("dark_theme_settings"); + screenshot("manual_dark_theme_settings"); onView(withText(R.string.pref_theme_title)) .check(matches(isDisplayed())) @@ -83,7 +83,7 @@ public class DarkThemeTest extends ScreenshotTest { .check(matches(isClosed(Gravity.LEFT))) .perform(DrawerActions.open()); - screenshot("dark_theme_nav_drawer"); + screenshot("manual_dark_theme_nav_drawer"); } } From daf5db470fabaac2fc939dee0d320b949861fda9 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 25 Jul 2018 16:46:23 -0300 Subject: [PATCH 03/10] Use demo mode when taking screenshots to clear status bar https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/docs/demo_mode.md --- briar-android/fastlane/Fastfile | 4 +++- briar-android/fastlane/demo-mode-activate.sh | 7 +++++++ briar-android/fastlane/demo-mode-deactivate.sh | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100755 briar-android/fastlane/demo-mode-activate.sh create mode 100755 briar-android/fastlane/demo-mode-deactivate.sh diff --git a/briar-android/fastlane/Fastfile b/briar-android/fastlane/Fastfile index 3646c37a6..01035f6ec 100644 --- a/briar-android/fastlane/Fastfile +++ b/briar-android/fastlane/Fastfile @@ -19,8 +19,10 @@ platform :android do desc "Takes screenshots for manual and Google Play" lane :screenshots do gradle(project_dir: "..", task: "assembleScreenshot assembleAndroidTest") + system './demo-mode-activate.sh' capture_android_screenshots - system './rename_screenshots.py' + system './demo-mode-deactivate.sh' + system './rename_screenshots.py' end end diff --git a/briar-android/fastlane/demo-mode-activate.sh b/briar-android/fastlane/demo-mode-activate.sh new file mode 100755 index 000000000..23001fb56 --- /dev/null +++ b/briar-android/fastlane/demo-mode-activate.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +adb shell settings put global sysui_demo_allowed 1 +adb shell am broadcast -a com.android.systemui.demo -e command enter +adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false +adb shell am broadcast -a com.android.systemui.demo -e command battery -e level 100 +adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi show +adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 1337 \ No newline at end of file diff --git a/briar-android/fastlane/demo-mode-deactivate.sh b/briar-android/fastlane/demo-mode-deactivate.sh new file mode 100755 index 000000000..c70cd5326 --- /dev/null +++ b/briar-android/fastlane/demo-mode-deactivate.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +adb shell am broadcast -a com.android.systemui.demo -e command exit \ No newline at end of file From 05fbb87c066cd77438fcc970cadd4b481e11205a Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 26 Jul 2018 12:26:36 -0300 Subject: [PATCH 04/10] Add a NavDrawerActivityTest --- briar-android/build.gradle | 1 + .../briar/android/BriarTestComponent.java | 6 +- .../navdrawer/NavDrawerActivityTest.java | 55 +++++++++++++++++++ ...emeTest.java => SettingsActivityTest.java} | 2 +- .../briar/android/test/ScreenshotTest.java | 19 +++++++ 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java rename briar-android/src/androidTest/java/org/briarproject/briar/android/settings/{DarkThemeTest.java => SettingsActivityTest.java} (97%) diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 7d0714bb7..317993ae2 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -53,6 +53,7 @@ dependencies { def espressoVersion = '3.0.2' androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion" androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion" + androidTestImplementation "com.android.support.test.espresso:espresso-intents:$espressoVersion" androidTestImplementation "tools.fastlane:screengrab:1.1.0" androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2" androidTestCompileOnly 'javax.annotation:jsr250-api:1.0' diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java index 3b1ba59fd..33166b8c4 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java @@ -3,7 +3,8 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleAndroidModule; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.briar.BriarCoreModule; -import org.briarproject.briar.android.settings.DarkThemeTest; +import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest; +import org.briarproject.briar.android.settings.SettingsActivityTest; import javax.inject.Singleton; @@ -18,6 +19,7 @@ import dagger.Component; }) public interface BriarTestComponent extends AndroidComponent { - void inject(DarkThemeTest test); + void inject(NavDrawerActivityTest test); + void inject(SettingsActivityTest test); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java new file mode 100644 index 000000000..b290b2be2 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java @@ -0,0 +1,55 @@ +package org.briarproject.briar.android.navdrawer; + +import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.espresso.intent.rule.IntentsTestRule; +import android.view.Gravity; + +import org.briarproject.briar.R; +import org.briarproject.briar.android.BriarTestComponent; +import org.briarproject.briar.android.settings.SettingsActivity; +import org.briarproject.briar.android.test.ScreenshotTest; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; + +public class NavDrawerActivityTest extends ScreenshotTest { + + @Rule + public IntentsTestRule activityRule = + new IntentsTestRule<>(NavDrawerActivity.class); + + @Override + protected void inject(BriarTestComponent component) { + component.inject(this); + } + + @Before + public void waitForSignIn() { + onView(isRoot()) + .perform(waitForActivityToResume(activityRule.getActivity())); + } + + @Test + public void openSettings() { + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + onView(withText(R.string.settings_button)) + .check(matches(isDisplayed())) + .perform(click()); + intended(hasComponent(SettingsActivity.class.getName())); + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java similarity index 97% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java index 3989d2f97..fd3dd61b7 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/DarkThemeTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java @@ -28,7 +28,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; @RunWith(AndroidJUnit4.class) -public class DarkThemeTest extends ScreenshotTest { +public class SettingsActivityTest extends ScreenshotTest { @Rule public ActivityTestRule activityRule = diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java index b5a71e845..4b73dc0cc 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java @@ -2,14 +2,19 @@ package org.briarproject.briar.android.test; import android.support.test.InstrumentationRegistry; import android.support.test.espresso.NoMatchingViewException; +import android.support.test.espresso.contrib.DrawerActions; import android.util.Log; +import android.view.Gravity; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.briar.R; import org.briarproject.briar.android.BriarTestApplication; import org.briarproject.briar.android.BriarTestComponent; import org.junit.Before; import org.junit.ClassRule; +import javax.inject.Inject; + import tools.fastlane.screengrab.Screengrab; import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; import tools.fastlane.screengrab.locale.LocaleTestRule; @@ -18,9 +23,11 @@ import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; import static tools.fastlane.screengrab.Screengrab.setDefaultScreenshotStrategy; public abstract class ScreenshotTest { @@ -39,6 +46,8 @@ public abstract class ScreenshotTest { private final BriarTestApplication app = (BriarTestApplication) InstrumentationRegistry.getTargetContext() .getApplicationContext(); + @Inject + LifecycleManager lifecycleManager; protected abstract void inject(BriarTestComponent component); @@ -51,6 +60,7 @@ public abstract class ScreenshotTest { @Before public void signIn() throws Exception { inject((BriarTestComponent) app.getApplicationComponent()); + if (lifecycleManager.getLifecycleState() == RUNNING) return; try { onView(withId(R.id.edit_password)) @@ -93,6 +103,15 @@ public abstract class ScreenshotTest { .check(matches(isDisplayed())); } + protected void signOut() { + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) + .perform(DrawerActions.open()); + onView(withText(R.string.sign_out_button)) + .check(matches(isDisplayed())) + .perform(click()); + } + protected void screenshot(String name) { try { Screengrab.screenshot(name); From 412381f37e530667f5349c50640548adc836e238 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 27 Jul 2018 12:40:53 -0300 Subject: [PATCH 05/10] Move buildType to flavor and add hashes for pinning of androidTest dependencies --- .gitignore | 8 +--- bramble-android/build.gradle | 6 --- briar-android/.gitignore | 6 +++ briar-android/build.gradle | 40 +++++++++++++++---- briar-android/fastlane/Screengrabfile | 6 +-- .../src/screenshot/AndroidManifest.xml | 1 + 6 files changed, 43 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 8f2bfafc3..21c3404ab 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,4 @@ local.properties build/ captures *.iml -projectFilesBackup/ - -# Fastlane Non-Google Play Screenshots -briar-android/fastlane/metadata/android/screenshots.html -briar-android/fastlane/metadata/android/*/images/phoneScreenshots/manual_*.png -briar-android/fastlane/report.xml -briar-android/fastlane/README.md \ No newline at end of file +projectFilesBackup/ \ No newline at end of file diff --git a/bramble-android/build.gradle b/bramble-android/build.gradle index 0e6e49e17..f7c9415ed 100644 --- a/bramble-android/build.gradle +++ b/bramble-android/build.gradle @@ -15,12 +15,6 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } - buildTypes { - debug - screenshot - release - } - compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/briar-android/.gitignore b/briar-android/.gitignore index 4d702fcd8..ab81bc92b 100644 --- a/briar-android/.gitignore +++ b/briar-android/.gitignore @@ -5,3 +5,9 @@ local.properties .settings src/main/assets/*.zip src/main/res/values-iw + +# Fastlane Screenshots +/fastlane/metadata/android/screenshots.html +/fastlane/metadata/android/*/images +/fastlane/report.xml +/fastlane/README.md \ No newline at end of file diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 317993ae2..1fe8855d9 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -55,6 +55,7 @@ dependencies { androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion" androidTestImplementation "com.android.support.test.espresso:espresso-intents:$espressoVersion" androidTestImplementation "tools.fastlane:screengrab:1.1.0" + androidTestImplementation "com.android.support.test.uiautomator:uiautomator-v18:2.1.3" androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2" androidTestCompileOnly 'javax.annotation:jsr250-api:1.0' androidTestImplementation 'junit:junit:4.12' @@ -75,6 +76,14 @@ dependencyVerification { 'com.almworks.sqlite4java:sqlite4java:0.282:sqlite4java-0.282.jar:9e1d8dd83ca6003f841e3af878ce2dc7c22497493a7bb6d1b62ec1b0d0a83c05', 'com.android.support.constraint:constraint-layout-solver:1.1.0:constraint-layout-solver-1.1.0.jar:fcb4c7d705754ca3d69b1b2c3caf445a425599fda8caabbcf855d98ea0663e4e', 'com.android.support.constraint:constraint-layout:1.1.0:constraint-layout-1.1.0.aar:d490188709b7bb2f11609beadd7e5eb7538892f308828ec3ff261a74e6ecf47e', + 'com.android.support.test.espresso:espresso-contrib:3.0.2:espresso-contrib-3.0.2.aar:eacb4a10dde5597b8a6b8668804d4b63e3ae2d46a78192068532922fec0b4a66', + 'com.android.support.test.espresso:espresso-core:3.0.2:espresso-core-3.0.2.aar:f40bf62e26e6f95a9c376c4e318415a77053b7dbb7ec12688eb6fab93dffdf73', + 'com.android.support.test.espresso:espresso-idling-resource:3.0.2:espresso-idling-resource-3.0.2.aar:c6485150f9f4aea1ce9d138f3d60d82ebed3fe35b340a8b1dc975ff01f3b17b2', + 'com.android.support.test.espresso:espresso-intents:3.0.2:espresso-intents-3.0.2.aar:556f99e8c8723a9ef313ed816fb9074d65903c6767521a66b099720d2cc21f10', + 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3:uiautomator-v18-2.1.3.aar:15e6b3c7104859630bf844e31805aa7cb2eb4b385e6119ab34132c8258eee2c4', + 'com.android.support.test:monitor:1.0.2:monitor-1.0.2.aar:38ef4fa98a32dc55550ff49bb36a583e178b3a9b830fcb8dcc27bfc4254bc2bc', + 'com.android.support.test:rules:1.0.2:rules-1.0.2.aar:7ddad387d1a16d4dbdbefacee070d34574e565b008117c1a163edac8ae02a6aa', + 'com.android.support.test:runner:1.0.2:runner-1.0.2.aar:f04b9ae342975ba1cb3e4a06e13426e3e6b8a73faa45acba604493d83c9a4f00', 'com.android.support:animated-vector-drawable:27.1.1:animated-vector-drawable-27.1.1.aar:59670473f6e98fda792f7bef25dd7292b0a3106031c7a5e30eb020bf26f077bd', 'com.android.support:appcompat-v7:27.1.1:appcompat-v7-27.1.1.aar:0c7808fbbc5838d831e32e3c0a6f84e1f2c981deb8f11e010650f2b57923a335', 'com.android.support:cardview-v7:27.1.1:cardview-v7-27.1.1.aar:8ed955dd037d82a7b4bbcaedb4f896523c3e4c1bf3ca698ce807c350767a2886', @@ -118,8 +127,10 @@ dependencyVerification { 'com.android.tools:sdk-common:26.1.3:sdk-common-26.1.3.jar:1948603ca9ff22c7ebb3178000bffa3a9dd2ca1cc5cb0c793cae08468b8fcfc1', 'com.android.tools:sdklib:26.1.3:sdklib-26.1.3.jar:4adcfaad9514607098d2c51503c39811112d3050f4d1e744c01c7f08f591032b', 'com.github.bumptech.glide:glide:3.8.0:glide-3.8.0.jar:750d9e7b940dc0ee48f8680623b55d46e14e8727acc922d7b156e57e7c549655', + 'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.0:accessibility-test-framework-2.0.jar:cdf16ef8f5b8023d003ce3cc1b0d51bda737762e2dab2fedf43d1c4292353f7f', 'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1:accessibility-test-framework-2.1.jar:7b0aa6ed7553597ce0610684a9f7eca8021eee218f2e2f427c04a7fbf5f920bd', 'com.google.code.findbugs:jsr305:1.3.9:jsr305-1.3.9.jar:905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed', + 'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7', 'com.google.code.gson:gson:2.7:gson-2.7.jar:2d43eb5ea9e133d2ee2405cc14f5ee08951b8361302fdd93494a3a997b508d32', 'com.google.dagger:dagger-compiler:2.0.2:dagger-compiler-2.0.2.jar:b74bc9de063dd4c6400b232231f2ef5056145b8fbecbf5382012007dd1c071b3', 'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b', @@ -136,6 +147,7 @@ dependencyVerification { 'com.googlecode.json-simple:json-simple:1.1:json-simple-1.1.jar:2d9484f4c649f708f47f9a479465fc729770ee65617dca3011836602264f6439', 'com.ibm.icu:icu4j:53.1:icu4j-53.1.jar:e37a4467bac5cdeb02c5c4b8e5063d2f4e67b69e3c7df6d6b610f13185572bab', 'com.jpardogo.materialtabstrip:library:1.1.0:library-1.1.0.aar:24d19232b319f8c73e25793432357919a7ed972186f57a3b2c9093ea74ad8311', + 'com.squareup:javawriter:2.1.1:javawriter-2.1.1.jar:f699823d0081f69cbb676c1845ea222e0ada79bc88a53e5d22d8bd02d328f57e', 'com.squareup:javawriter:2.5.0:javawriter-2.5.0.jar:fcfb09fb0ea0aa97d3cfe7ea792398081348e468f126b3603cb3803f240197f0', 'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce', 'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4', @@ -190,6 +202,7 @@ dependencyVerification { 'org.glassfish.jaxb:jaxb-runtime:2.2.11:jaxb-runtime-2.2.11.jar:a874f2351cfba8e2946be3002d10c18a6da8f21b52ba2acf52f2b85d5520ed70', 'org.glassfish.jaxb:txw2:2.2.11:txw2-2.2.11.jar:272a3ccad45a4511351920cd2a8633c53cab8d5220c7a92954da5526bb5eafea', 'org.hamcrest:hamcrest-core:1.3:hamcrest-core-1.3.jar:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9', + 'org.hamcrest:hamcrest-integration:1.3:hamcrest-integration-1.3.jar:70f418efbb506c5155da5f9a5a33262ea08a9e4d7fea186aa9015c41a7224ac2', 'org.hamcrest:hamcrest-library:1.3:hamcrest-library-1.3.jar:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c', 'org.jetbrains.kotlin:kotlin-reflect:1.2.0:kotlin-reflect-1.2.0.jar:4f48a872bad6e4d9c053f4ad610d11e4012ad7e58dc19a03dd5eb811f36069dd', 'org.jetbrains.kotlin:kotlin-stdlib-jre7:1.2.0:kotlin-stdlib-jre7-1.2.0.jar:c7a20fb951d437797afe8980aff6c1e5a03f310c661ba58ba1d4fa90cb0f2926', @@ -221,6 +234,7 @@ dependencyVerification { 'org.robolectric:shadows-framework:3.5.1:shadows-framework-3.5.1.jar:597b54cc1a494799d783921c6ac04352f33e94fca8e00f299d4ca192db79e3fc', 'org.robolectric:shadows-support-v4:3.0:shadows-support-v4-3.0.jar:66bcc3257b037d72998e860d67b1bc58215b7eeac8ad860fcc3e613332d88619', 'org.robolectric:utils:3.5.1:utils-3.5.1.jar:d7d77326867e6d903156ebb18c244819b26aebe3aa82a1c57081081a0b6c4f63', + 'tools.fastlane:screengrab:1.1.0:screengrab-1.1.0.aar:03ce3868ee8a0082d14e7a1de0999f91531c0cc794392688beb08ee9bc4495fd', 'uk.co.samuelwall:material-tap-target-prompt:2.8.0:material-tap-target-prompt-2.8.0.aar:ac70770c05bbc4675a1d5712c0e53d46ee4fa961b74947589fce50d8003065ec', 'xmlpull:xmlpull:1.1.3.1:xmlpull-1.1.3.1.jar:34e08ee62116071cbb69c0ed70d15a7a5b208d62798c59f2120bb8929324cb63', 'xpp3:xpp3_min:1.1.4c:xpp3_min-1.1.4c.jar:bfc90e9e32d0eab1f397fb974b5f150a815188382ac41f372a7149d5bc178008', @@ -260,6 +274,24 @@ android { testInstrumentationRunner 'org.briarproject.briar.android.test.BriarTestRunner' } + flavorDimensions "version" + productFlavors { + screenshot { + dimension "version" + minSdkVersion 18 + applicationIdSuffix ".screenshot" + resValue "string", "app_package", "org.briarproject.briar.android.screenshot.debug" + } + main { + dimension "version" + } + } + variantFilter { variant -> + if (variant.flavors*.name.contains("screenshot") && variant.buildType.name == "release") { + setIgnore(true) + } + } + buildTypes { debug { applicationIdSuffix ".debug" @@ -269,12 +301,6 @@ android { minifyEnabled true crunchPngs false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' - } - screenshot { - initWith debug - applicationIdSuffix ".screenshot" - resValue "string", "app_package", "org.briarproject.briar.android.screenshot" - resValue "string", "app_name", "Briar Screenshot" testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-test.txt' } release { @@ -285,8 +311,6 @@ android { } } - testBuildType "screenshot" - compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/briar-android/fastlane/Screengrabfile b/briar-android/fastlane/Screengrabfile index 690bc4cc8..f69c2238a 100644 --- a/briar-android/fastlane/Screengrabfile +++ b/briar-android/fastlane/Screengrabfile @@ -1,5 +1,5 @@ -app_package_name "org.briarproject.briar.android.screenshot" +app_package_name "org.briarproject.briar.android.screenshot.debug" locales ['en-US'] -app_apk_path "build/outputs/apk/screenshot/briar-android-screenshot.apk" -tests_apk_path "build/outputs/apk/androidTest/screenshot/briar-android-screenshot-androidTest.apk" +app_apk_path "build/outputs/apk/screenshot/debug/briar-android-screenshot-debug.apk" +tests_apk_path "build/outputs/apk/androidTest/screenshot/debug/briar-android-screenshot-debug-androidTest.apk" test_instrumentation_runner "org.briarproject.briar.android.test.BriarTestRunner" \ No newline at end of file diff --git a/briar-android/src/screenshot/AndroidManifest.xml b/briar-android/src/screenshot/AndroidManifest.xml index 266a92823..a35a0a5e5 100644 --- a/briar-android/src/screenshot/AndroidManifest.xml +++ b/briar-android/src/screenshot/AndroidManifest.xml @@ -2,6 +2,7 @@ + From 6f7d0c6f776ae3a782d00e16e309343ac6356e65 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 27 Jul 2018 18:21:37 -0300 Subject: [PATCH 06/10] Do proper Doze white-listing in UI tests --- briar-android/proguard-test.txt | 2 +- ...ication.java => TestBriarApplication.java} | 4 +- ...rTestComponent.java => TestComponent.java} | 2 +- .../navdrawer/NavDrawerActivityTest.java | 20 ++--- .../settings/SettingsActivityTest.java | 15 ++-- .../briar/android/test/BriarTestRunner.java | 4 +- .../briar/android/test/ScreenshotTest.java | 77 +++++++++++-------- .../briar/android/test/ViewActions.java | 2 +- .../briar/android/util/UiUtils.java | 2 - 9 files changed, 66 insertions(+), 62 deletions(-) rename briar-android/src/androidTest/java/org/briarproject/briar/android/{BriarTestApplication.java => TestBriarApplication.java} (80%) rename briar-android/src/androidTest/java/org/briarproject/briar/android/{BriarTestComponent.java => TestComponent.java} (90%) diff --git a/briar-android/proguard-test.txt b/briar-android/proguard-test.txt index 7007db0c2..652f46e58 100644 --- a/briar-android/proguard-test.txt +++ b/briar-android/proguard-test.txt @@ -12,4 +12,4 @@ -keep class junit.** { *; } -dontwarn junit.** --dontwarn org.briarproject.briar.android.BriarTestApplication \ No newline at end of file +-dontwarn org.briarproject.briar.android.TestBriarApplication \ No newline at end of file diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java similarity index 80% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java index 8bdd5b63a..eb6d86057 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestApplication.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java @@ -3,11 +3,11 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.briar.BriarCoreModule; -public class BriarTestApplication extends BriarApplicationImpl { +public class TestBriarApplication extends BriarApplicationImpl { @Override protected AndroidComponent createApplicationComponent() { - AndroidComponent component = DaggerBriarTestComponent.builder() + AndroidComponent component = DaggerTestComponent.builder() .appModule(new AppModule(this)).build(); // We need to load the eager singletons directly after making the // dependency graphs diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java similarity index 90% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java index 33166b8c4..a42980f10 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponent.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java @@ -17,7 +17,7 @@ import dagger.Component; BrambleAndroidModule.class, BrambleCoreModule.class }) -public interface BriarTestComponent extends AndroidComponent { +public interface TestComponent extends AndroidComponent { void inject(NavDrawerActivityTest test); void inject(SettingsActivityTest test); diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java index b290b2be2..4f8b03574 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java @@ -1,16 +1,18 @@ package org.briarproject.briar.android.navdrawer; +import android.app.Activity; import android.support.test.espresso.contrib.DrawerActions; import android.support.test.espresso.intent.rule.IntentsTestRule; +import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; import org.briarproject.briar.R; -import org.briarproject.briar.android.BriarTestComponent; +import org.briarproject.briar.android.TestComponent; import org.briarproject.briar.android.settings.SettingsActivity; import org.briarproject.briar.android.test.ScreenshotTest; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; @@ -19,11 +21,10 @@ import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; import static android.support.test.espresso.intent.Intents.intended; import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; +@RunWith(AndroidJUnit4.class) public class NavDrawerActivityTest extends ScreenshotTest { @Rule @@ -31,20 +32,19 @@ public class NavDrawerActivityTest extends ScreenshotTest { new IntentsTestRule<>(NavDrawerActivity.class); @Override - protected void inject(BriarTestComponent component) { + protected void inject(TestComponent component) { component.inject(this); } - @Before - public void waitForSignIn() { - onView(isRoot()) - .perform(waitForActivityToResume(activityRule.getActivity())); + @Override + protected Activity getActivity() { + return activityRule.getActivity(); } @Test public void openSettings() { onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) + .check(matches(isClosed(Gravity.START))) .perform(DrawerActions.open()); onView(withText(R.string.settings_button)) .check(matches(isDisplayed())) diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java index fd3dd61b7..5817d732f 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java @@ -1,5 +1,6 @@ package org.briarproject.briar.android.settings; +import android.app.Activity; import android.content.Intent; import android.support.test.espresso.contrib.DrawerActions; import android.support.test.rule.ActivityTestRule; @@ -9,10 +10,9 @@ import android.view.Gravity; import junit.framework.AssertionFailedError; import org.briarproject.briar.R; -import org.briarproject.briar.android.BriarTestComponent; +import org.briarproject.briar.android.TestComponent; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; import org.briarproject.briar.android.test.ScreenshotTest; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -22,10 +22,8 @@ import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; @RunWith(AndroidJUnit4.class) public class SettingsActivityTest extends ScreenshotTest { @@ -35,14 +33,13 @@ public class SettingsActivityTest extends ScreenshotTest { new ActivityTestRule<>(SettingsActivity.class); @Override - protected void inject(BriarTestComponent component) { + protected void inject(TestComponent component) { component.inject(this); } - @Before - public void waitForSignIn() { - onView(isRoot()) - .perform(waitForActivityToResume(activityRule.getActivity())); + @Override + protected Activity getActivity() { + return activityRule.getActivity(); } @Test diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java index cefb68766..655582242 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java @@ -4,7 +4,7 @@ import android.app.Application; import android.content.Context; import android.support.test.runner.AndroidJUnitRunner; -import org.briarproject.briar.android.BriarTestApplication; +import org.briarproject.briar.android.TestBriarApplication; public class BriarTestRunner extends AndroidJUnitRunner { @@ -13,7 +13,7 @@ public class BriarTestRunner extends AndroidJUnitRunner { Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { - return super.newApplication(cl, BriarTestApplication.class.getName(), + return super.newApplication(cl, TestBriarApplication.class.getName(), context); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java index 4b73dc0cc..ef11475a9 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java @@ -1,15 +1,16 @@ package org.briarproject.briar.android.test; -import android.support.test.InstrumentationRegistry; +import android.app.Activity; import android.support.test.espresso.NoMatchingViewException; -import android.support.test.espresso.contrib.DrawerActions; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; import android.util.Log; -import android.view.Gravity; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.briar.R; -import org.briarproject.briar.android.BriarTestApplication; -import org.briarproject.briar.android.BriarTestComponent; +import org.briarproject.briar.android.TestBriarApplication; +import org.briarproject.briar.android.TestComponent; import org.junit.Before; import org.junit.ClassRule; @@ -19,15 +20,19 @@ import tools.fastlane.screengrab.Screengrab; import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; import tools.fastlane.screengrab.locale.LocaleTestRule; +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.InstrumentationRegistry.getTargetContext; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.contrib.DrawerMatchers.isClosed; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; +import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; +import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; import static tools.fastlane.screengrab.Screengrab.setDefaultScreenshotStrategy; public abstract class ScreenshotTest { @@ -35,31 +40,26 @@ public abstract class ScreenshotTest { @ClassRule public static final LocaleTestRule localeTestRule = new LocaleTestRule(); + private static final String USERNAME = "test"; + private static final String PASSWORD = "123456"; + + private final TestBriarApplication app = + (TestBriarApplication) getTargetContext() + .getApplicationContext(); + @Inject + LifecycleManager lifecycleManager; + + protected abstract void inject(TestComponent component); + protected abstract Activity getActivity(); + @Before public void setupScreenshots() { setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); } - private static final String USERNAME = "test"; - private static final String PASSWORD = "123456"; - - private final BriarTestApplication app = - (BriarTestApplication) InstrumentationRegistry.getTargetContext() - .getApplicationContext(); - @Inject - LifecycleManager lifecycleManager; - - protected abstract void inject(BriarTestComponent component); - - /** - * Signs the user in. - * - * Note that you need to wait for your UI to show up after this. - * See {@link ViewActions#waitForActivityToResume} for one way to do it. - */ @Before public void signIn() throws Exception { - inject((BriarTestComponent) app.getApplicationComponent()); + inject((TestComponent) app.getApplicationComponent()); if (lifecycleManager.getLifecycleState() == RUNNING) return; try { @@ -73,9 +73,11 @@ public abstract class ScreenshotTest { // we start from a blank state and have no account, yet createAccount(); } + onView(isRoot()) + .perform(waitForActivityToResume(getActivity())); } - private void createAccount() { + private void createAccount() throws Exception { // TODO use AccountManager to start with fresh account // TODO move this below into a dedicated test for SetupActivity @@ -99,19 +101,26 @@ public abstract class ScreenshotTest { onView(withId(R.id.next)) .check(matches(isDisplayed())) .perform(click()); + + // White-list Doze if needed + if (needsDozeWhitelisting(getTargetContext())) { + onView(withText(R.string.setup_doze_button)) + .check(matches(isDisplayed())) + .perform(click()); + UiDevice device = UiDevice.getInstance(getInstrumentation()); + UiObject allowButton = device.findObject( + new UiSelector().className("android.widget.Button") + .index(1)); + allowButton.click(); + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + } + onView(withId(R.id.progress)) .check(matches(isDisplayed())); } - protected void signOut() { - onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) - .perform(DrawerActions.open()); - onView(withText(R.string.sign_out_button)) - .check(matches(isDisplayed())) - .perform(click()); - } - protected void screenshot(String name) { try { Screengrab.screenshot(name); diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java index 806124d1b..1dc07c8c7 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java @@ -21,7 +21,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; public class ViewActions { - private final static long TIMEOUT_MS = SECONDS.toMillis(5); + private final static long TIMEOUT_MS = SECONDS.toMillis(10); private final static long WAIT_MS = 50; public static ViewAction waitUntilMatches(Matcher viewMatcher) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index 2485f81c9..ee30d8d37 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -55,7 +55,6 @@ import static android.text.format.DateUtils.FORMAT_SHOW_DATE; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static org.briarproject.briar.BuildConfig.APPLICATION_ID; -import static org.briarproject.briar.BuildConfig.BUILD_TYPE; import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE; @MethodsNotNullByDefault @@ -175,7 +174,6 @@ public class UiUtils { public static boolean needsDozeWhitelisting(Context ctx) { if (SDK_INT < 23) return false; - if (BUILD_TYPE.equals("screenshot")) return false; PowerManager pm = (PowerManager) ctx.getSystemService(POWER_SERVICE); String packageName = ctx.getPackageName(); if (pm == null) throw new AssertionError(); From 3ff64628991c2caea085ba61a30ddd53eeb7fb40 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 30 Jul 2018 16:00:13 -0300 Subject: [PATCH 07/10] Refactor Espresso tests to use new AccountManager --- briar-android/fastlane/Screengrabfile | 4 + briar-android/proguard-test.txt | 2 +- ...ava => BriarTestComponentApplication.java} | 2 +- .../briar/android/TestComponent.java | 6 + .../android/login/PasswordActivityTest.java | 50 +++++++ .../android/login/SetupActivityTest.java | 106 +++++++++++++++ .../navdrawer/NavDrawerActivityTest.java | 11 +- .../settings/SettingsActivityTest.java | 42 ++---- .../briar/android/test/BriarTestRunner.java | 4 +- .../briar/android/test/ScreenshotTest.java | 127 +++++------------- .../briar/android/test/ViewActions.java | 91 ++++++------- 11 files changed, 257 insertions(+), 188 deletions(-) rename briar-android/src/androidTest/java/org/briarproject/briar/android/{TestBriarApplication.java => BriarTestComponentApplication.java} (88%) create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java create mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java diff --git a/briar-android/fastlane/Screengrabfile b/briar-android/fastlane/Screengrabfile index f69c2238a..3afd283cd 100644 --- a/briar-android/fastlane/Screengrabfile +++ b/briar-android/fastlane/Screengrabfile @@ -1,5 +1,9 @@ app_package_name "org.briarproject.briar.android.screenshot.debug" locales ['en-US'] +use_tests_in_classes([ + 'org.briarproject.briar.android.login.SetupActivityTest', + 'org.briarproject.briar.android.settings.SettingsActivityTest', +]) app_apk_path "build/outputs/apk/screenshot/debug/briar-android-screenshot-debug.apk" tests_apk_path "build/outputs/apk/androidTest/screenshot/debug/briar-android-screenshot-debug-androidTest.apk" test_instrumentation_runner "org.briarproject.briar.android.test.BriarTestRunner" \ No newline at end of file diff --git a/briar-android/proguard-test.txt b/briar-android/proguard-test.txt index 652f46e58..df4eb272e 100644 --- a/briar-android/proguard-test.txt +++ b/briar-android/proguard-test.txt @@ -12,4 +12,4 @@ -keep class junit.** { *; } -dontwarn junit.** --dontwarn org.briarproject.briar.android.TestBriarApplication \ No newline at end of file +-dontwarn org.briarproject.briar.android.BriarTestComponentApplication \ No newline at end of file diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java similarity index 88% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java index eb6d86057..6634d5bfc 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestBriarApplication.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.briar.BriarCoreModule; -public class TestBriarApplication extends BriarApplicationImpl { +public class BriarTestComponentApplication extends BriarApplicationImpl { @Override protected AndroidComponent createApplicationComponent() { diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java index a42980f10..240eb6f14 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java @@ -2,7 +2,10 @@ package org.briarproject.briar.android; import org.briarproject.bramble.BrambleAndroidModule; import org.briarproject.bramble.BrambleCoreModule; +import org.briarproject.bramble.account.BriarAccountModule; import org.briarproject.briar.BriarCoreModule; +import org.briarproject.briar.android.login.PasswordActivityTest; +import org.briarproject.briar.android.login.SetupActivityTest; import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest; import org.briarproject.briar.android.settings.SettingsActivityTest; @@ -15,10 +18,13 @@ import dagger.Component; AppModule.class, BriarCoreModule.class, BrambleAndroidModule.class, + BriarAccountModule.class, BrambleCoreModule.class }) public interface TestComponent extends AndroidComponent { + void inject(SetupActivityTest test); + void inject(PasswordActivityTest test); void inject(NavDrawerActivityTest test); void inject(SettingsActivityTest test); diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java new file mode 100644 index 000000000..0f7ce89b9 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java @@ -0,0 +1,50 @@ +package org.briarproject.briar.android.login; + +import android.support.test.runner.AndroidJUnit4; + +import org.briarproject.briar.R; +import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.test.ScreenshotTest; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; + + +@RunWith(AndroidJUnit4.class) +public class PasswordActivityTest extends ScreenshotTest { + + @Rule + public CleanAccountTestRule testRule = + new CleanAccountTestRule<>(PasswordActivity.class); + + @Override + protected void inject(TestComponent component) { + component.inject(this); + } + + // FIXME + @Ignore("Need to find a way to sign-out after creating fresh account") + @Test + public void successfulLogin() { + onView(withId(R.id.edit_password)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.btn_sign_in)) + .check(matches(isDisplayed())) + .perform(click()); + onView(withId(R.id.progress)) + .check(matches(isDisplayed())); + intended(hasComponent(OpenDatabaseActivity.class.getName())); + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java new file mode 100644 index 000000000..922cad655 --- /dev/null +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java @@ -0,0 +1,106 @@ +package org.briarproject.briar.android.login; + +import android.support.test.espresso.intent.rule.IntentsTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiSelector; + +import org.briarproject.briar.R; +import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.test.ScreenshotTest; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.InstrumentationRegistry.getTargetContext; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static android.support.test.runner.lifecycle.Stage.PAUSED; +import static junit.framework.Assert.assertTrue; +import static org.briarproject.briar.android.test.ViewActions.waitForActivity; +import static org.briarproject.briar.android.test.ViewActions.waitUntilMatches; +import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; + + +@RunWith(AndroidJUnit4.class) +public class SetupActivityTest extends ScreenshotTest { + + @Rule + public IntentsTestRule testRule = + new IntentsTestRule(SetupActivity.class) { + @Override + protected void beforeActivityLaunched() { + super.beforeActivityLaunched(); + accountManager.deleteAccount(); + } + }; + + @Override + protected void inject(TestComponent component) { + component.inject(this); + } + + @Test + public void createAccount() throws Exception { + // Enter username + onView(withText(R.string.setup_title)) + .check(matches(isDisplayed())); + onView(withId(R.id.nickname_entry)) + .check(matches(isDisplayed())) + .perform(typeText(USERNAME)); + onView(withId(R.id.nickname_entry)) + .perform(waitUntilMatches(withText(USERNAME))); + + screenshot("manual_create_account"); + + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + + // Enter password + onView(withId(R.id.password_entry)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.password_confirm)) + .check(matches(isDisplayed())) + .perform(typeText(PASSWORD)); + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + + // White-list Doze if needed + if (needsDozeWhitelisting(getTargetContext())) { + onView(withText(R.string.setup_doze_button)) + .check(matches(isDisplayed())) + .perform(click()); + UiDevice device = UiDevice.getInstance(getInstrumentation()); + UiObject allowButton = device.findObject( + new UiSelector().className("android.widget.Button") + .index(1)); + allowButton.click(); + onView(withId(R.id.next)) + .check(matches(isDisplayed())) + .perform(click()); + } + + // wait for OpenDatabaseActivity to show up + onView(withId(R.id.progress)) + .check(matches(isDisplayed())); + onView(isRoot()) + .perform(waitForActivity(testRule.getActivity(), PAUSED)); + intended(hasComponent(OpenDatabaseActivity.class.getName())); + + assertTrue(accountManager.hasDatabaseKey()); + } + +} diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java index 4f8b03574..395ed8c48 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java @@ -1,8 +1,6 @@ package org.briarproject.briar.android.navdrawer; -import android.app.Activity; import android.support.test.espresso.contrib.DrawerActions; -import android.support.test.espresso.intent.rule.IntentsTestRule; import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; @@ -28,19 +26,14 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; public class NavDrawerActivityTest extends ScreenshotTest { @Rule - public IntentsTestRule activityRule = - new IntentsTestRule<>(NavDrawerActivity.class); + public CleanAccountTestRule testRule = + new CleanAccountTestRule<>(NavDrawerActivity.class); @Override protected void inject(TestComponent component) { component.inject(this); } - @Override - protected Activity getActivity() { - return activityRule.getActivity(); - } - @Test public void openSettings() { onView(withId(R.id.drawer_layout)) diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java index 5817d732f..b5c32f46f 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java @@ -1,14 +1,10 @@ package org.briarproject.briar.android.settings; -import android.app.Activity; import android.content.Intent; import android.support.test.espresso.contrib.DrawerActions; -import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; -import junit.framework.AssertionFailedError; - import org.briarproject.briar.R; import org.briarproject.briar.android.TestComponent; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; @@ -29,32 +25,22 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; public class SettingsActivityTest extends ScreenshotTest { @Rule - public ActivityTestRule activityRule = - new ActivityTestRule<>(SettingsActivity.class); + public CleanAccountTestRule testRule = + new CleanAccountTestRule<>(SettingsActivity.class); @Override protected void inject(TestComponent component) { component.inject(this); } - @Override - protected Activity getActivity() { - return activityRule.getActivity(); - } - @Test public void changeTheme() { onView(withText(R.string.settings_button)) .check(matches(isDisplayed())); - onView(withText(R.string.pref_theme_title)) - .check(matches(isDisplayed())) - .perform(click()); - onView(withText(R.string.pref_theme_light)) - .check(matches(isDisplayed())) - .perform(click()); screenshot("manual_dark_theme_settings"); + // switch to dark theme onView(withText(R.string.pref_theme_title)) .check(matches(isDisplayed())) .perform(click()); @@ -62,22 +48,20 @@ public class SettingsActivityTest extends ScreenshotTest { .check(matches(isDisplayed())) .perform(click()); + // start main activity Intent i = - new Intent(activityRule.getActivity(), NavDrawerActivity.class); - activityRule.getActivity().startActivity(i); + new Intent(testRule.getActivity(), NavDrawerActivity.class); + testRule.getActivity().startActivity(i); - try { - onView(withId(R.id.expiryWarningClose)) - .check(matches(isDisplayed())); - onView(withId(R.id.expiryWarningClose)) - .perform(click()); - } catch (AssertionFailedError e){ - // TODO remove try block when starting with fresh account - // ignore since we already removed the expiry warning - } + // close expiry warning + onView(withId(R.id.expiryWarningClose)) + .check(matches(isDisplayed())); + onView(withId(R.id.expiryWarningClose)) + .perform(click()); + // open navigation drawer onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) + .check(matches(isClosed(Gravity.START))) .perform(DrawerActions.open()); screenshot("manual_dark_theme_nav_drawer"); diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java index 655582242..bf520102d 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/BriarTestRunner.java @@ -4,7 +4,7 @@ import android.app.Application; import android.content.Context; import android.support.test.runner.AndroidJUnitRunner; -import org.briarproject.briar.android.TestBriarApplication; +import org.briarproject.briar.android.BriarTestComponentApplication; public class BriarTestRunner extends AndroidJUnitRunner { @@ -13,7 +13,7 @@ public class BriarTestRunner extends AndroidJUnitRunner { Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { - return super.newApplication(cl, TestBriarApplication.class.getName(), + return super.newApplication(cl, BriarTestComponentApplication.class.getName(), context); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java index ef11475a9..77ed5faac 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java @@ -1,17 +1,13 @@ package org.briarproject.briar.android.test; import android.app.Activity; -import android.support.test.espresso.NoMatchingViewException; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiSelector; +import android.support.test.espresso.intent.rule.IntentsTestRule; import android.util.Log; +import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.briar.R; -import org.briarproject.briar.android.TestBriarApplication; +import org.briarproject.briar.android.BriarTestComponentApplication; import org.briarproject.briar.android.TestComponent; -import org.junit.Before; import org.junit.ClassRule; import javax.inject.Inject; @@ -20,19 +16,7 @@ import tools.fastlane.screengrab.Screengrab; import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; import tools.fastlane.screengrab.locale.LocaleTestRule; -import static android.support.test.InstrumentationRegistry.getInstrumentation; import static android.support.test.InstrumentationRegistry.getTargetContext; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.typeText; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; -import static org.briarproject.briar.android.test.ViewActions.waitForActivityToResume; -import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; import static tools.fastlane.screengrab.Screengrab.setDefaultScreenshotStrategy; public abstract class ScreenshotTest { @@ -40,86 +24,24 @@ public abstract class ScreenshotTest { @ClassRule public static final LocaleTestRule localeTestRule = new LocaleTestRule(); - private static final String USERNAME = "test"; - private static final String PASSWORD = "123456"; + protected static final String USERNAME = "Alice"; + protected static final String PASSWORD = "123456"; - private final TestBriarApplication app = - (TestBriarApplication) getTargetContext() - .getApplicationContext(); @Inject - LifecycleManager lifecycleManager; + protected AccountManager accountManager; + @Inject + protected LifecycleManager lifecycleManager; + + public ScreenshotTest() { + super(); + setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); + BriarTestComponentApplication app = + (BriarTestComponentApplication) getTargetContext() + .getApplicationContext(); + inject((TestComponent) app.getApplicationComponent()); + } protected abstract void inject(TestComponent component); - protected abstract Activity getActivity(); - - @Before - public void setupScreenshots() { - setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); - } - - @Before - public void signIn() throws Exception { - inject((TestComponent) app.getApplicationComponent()); - if (lifecycleManager.getLifecycleState() == RUNNING) return; - - try { - onView(withId(R.id.edit_password)) - .check(matches(isDisplayed())) - .perform(typeText(PASSWORD)); - onView(withId(R.id.btn_sign_in)) - .check(matches(isDisplayed())) - .perform(click()); - } catch (NoMatchingViewException e) { - // we start from a blank state and have no account, yet - createAccount(); - } - onView(isRoot()) - .perform(waitForActivityToResume(getActivity())); - } - - private void createAccount() throws Exception { - // TODO use AccountManager to start with fresh account - // TODO move this below into a dedicated test for SetupActivity - - // Enter username - onView(withText(R.string.setup_title)) - .check(matches(isDisplayed())); - onView(withId(R.id.nickname_entry)) - .check(matches(isDisplayed())) - .perform(typeText(USERNAME)); - onView(withId(R.id.next)) - .check(matches(isDisplayed())) - .perform(click()); - - // Enter password - onView(withId(R.id.password_entry)) - .check(matches(isDisplayed())) - .perform(typeText(PASSWORD)); - onView(withId(R.id.password_confirm)) - .check(matches(isDisplayed())) - .perform(typeText(PASSWORD)); - onView(withId(R.id.next)) - .check(matches(isDisplayed())) - .perform(click()); - - // White-list Doze if needed - if (needsDozeWhitelisting(getTargetContext())) { - onView(withText(R.string.setup_doze_button)) - .check(matches(isDisplayed())) - .perform(click()); - UiDevice device = UiDevice.getInstance(getInstrumentation()); - UiObject allowButton = device.findObject( - new UiSelector().className("android.widget.Button") - .index(1)); - allowButton.click(); - onView(withId(R.id.next)) - .check(matches(isDisplayed())) - .perform(click()); - } - - onView(withId(R.id.progress)) - .check(matches(isDisplayed())); - } protected void screenshot(String name) { try { @@ -133,4 +55,19 @@ public abstract class ScreenshotTest { } } + protected class CleanAccountTestRule + extends IntentsTestRule { + + public CleanAccountTestRule(Class activityClass) { + super(activityClass); + } + + @Override + protected void beforeActivityLaunched() { + super.beforeActivityLaunched(); + accountManager.deleteAccount(); + accountManager.createAccount(USERNAME, PASSWORD); + } + } + } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java index 1dc07c8c7..0d1aceba5 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ViewActions.java @@ -6,16 +6,16 @@ import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.runner.lifecycle.ActivityLifecycleMonitor; import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; +import android.support.test.runner.lifecycle.Stage; import android.view.View; import org.hamcrest.Matcher; import java.util.concurrent.TimeoutException; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.util.HumanReadables.describe; import static android.support.test.espresso.util.TreeIterables.breadthFirstViewTraversal; -import static android.support.test.runner.lifecycle.Stage.RESUMED; import static java.lang.System.currentTimeMillis; import static java.util.concurrent.TimeUnit.SECONDS; @@ -30,10 +30,13 @@ public class ViewActions { private static ViewAction waitUntilMatches(Matcher viewMatcher, long timeout) { - return new ViewAction() { + return new CustomViewAction() { @Override - public Matcher getConstraints() { - return isRoot(); + protected boolean exitConditionTrue(View view) { + for (View child : breadthFirstViewTraversal(view)) { + if (viewMatcher.matches(child)) return true; + } + return false; } @Override @@ -41,35 +44,16 @@ public class ViewActions { return "Wait for view matcher " + viewMatcher + " to match within " + timeout + " milliseconds."; } - - @Override - public void perform(final UiController uiController, - final View view) { - uiController.loopMainThreadUntilIdle(); - long endTime = currentTimeMillis() + timeout; - - do { - for (View child : breadthFirstViewTraversal(view)) { - if (viewMatcher.matches(child)) return; - } - uiController.loopMainThreadForAtLeast(WAIT_MS); - } - while (currentTimeMillis() < endTime); - - throw new PerformException.Builder() - .withActionDescription(getDescription()) - .withViewDescription(describe(view)) - .withCause(new TimeoutException()) - .build(); - } }; } - public static ViewAction waitForActivityToResume(Activity activity) { - return new ViewAction() { + public static ViewAction waitForActivity(Activity activity, Stage stage) { + return new CustomViewAction() { @Override - public Matcher getConstraints() { - return isRoot(); + protected boolean exitConditionTrue(View view) { + ActivityLifecycleMonitor lifecycleMonitor = + ActivityLifecycleMonitorRegistry.getInstance(); + return lifecycleMonitor.getLifecycleStageOf(activity) == stage; } @Override @@ -77,28 +61,33 @@ public class ViewActions { return "Wait for activity " + activity.getClass().getName() + " to resume within " + TIMEOUT_MS + " milliseconds."; } - - @Override - public void perform(final UiController uiController, - final View view) { - uiController.loopMainThreadUntilIdle(); - long endTime = currentTimeMillis() + TIMEOUT_MS; - ActivityLifecycleMonitor lifecycleMonitor = - ActivityLifecycleMonitorRegistry.getInstance(); - do { - if (lifecycleMonitor.getLifecycleStageOf(activity) == - RESUMED) return; - uiController.loopMainThreadForAtLeast(WAIT_MS); - } - while (currentTimeMillis() < endTime); - - throw new PerformException.Builder() - .withActionDescription(getDescription()) - .withViewDescription(describe(view)) - .withCause(new TimeoutException()) - .build(); - } }; } + private static abstract class CustomViewAction implements ViewAction { + @Override + public Matcher getConstraints() { + return isDisplayed(); + } + + @Override + public void perform(UiController uiController, View view) { + uiController.loopMainThreadUntilIdle(); + long endTime = currentTimeMillis() + TIMEOUT_MS; + do { + if (exitConditionTrue(view)) return; + uiController.loopMainThreadForAtLeast(WAIT_MS); + } + while (currentTimeMillis() < endTime); + + throw new PerformException.Builder() + .withActionDescription(getDescription()) + .withViewDescription(describe(view)) + .withCause(new TimeoutException()) + .build(); + } + + protected abstract boolean exitConditionTrue(View view); + } + } From cc6041e90c16fc83dd3a1ab3f49210a46e007f77 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 3 Aug 2018 11:42:01 -0300 Subject: [PATCH 08/10] Rename Component and Screenshot Tests --- briar-android/fastlane/Screengrabfile | 4 ++-- .../briar/android/BriarTestComponentApplication.java | 2 +- .../{TestComponent.java => BriarUiTestComponent.java} | 10 +++++----- .../briar/android/login/PasswordActivityTest.java | 4 ++-- ...ivityTest.java => SetupActivityScreenshotTest.java} | 6 +++--- .../briar/android/navdrawer/NavDrawerActivityTest.java | 4 ++-- ...tyTest.java => SettingsActivityScreenshotTest.java} | 6 +++--- .../briar/android/test/ScreenshotTest.java | 6 +++--- 8 files changed, 21 insertions(+), 21 deletions(-) rename briar-android/src/androidTest/java/org/briarproject/briar/android/{TestComponent.java => BriarUiTestComponent.java} (68%) rename briar-android/src/androidTest/java/org/briarproject/briar/android/login/{SetupActivityTest.java => SetupActivityScreenshotTest.java} (95%) rename briar-android/src/androidTest/java/org/briarproject/briar/android/settings/{SettingsActivityTest.java => SettingsActivityScreenshotTest.java} (91%) diff --git a/briar-android/fastlane/Screengrabfile b/briar-android/fastlane/Screengrabfile index 3afd283cd..bacf6905b 100644 --- a/briar-android/fastlane/Screengrabfile +++ b/briar-android/fastlane/Screengrabfile @@ -1,8 +1,8 @@ app_package_name "org.briarproject.briar.android.screenshot.debug" locales ['en-US'] use_tests_in_classes([ - 'org.briarproject.briar.android.login.SetupActivityTest', - 'org.briarproject.briar.android.settings.SettingsActivityTest', + 'org.briarproject.briar.android.login.SetupActivityScreenshotTest', + 'org.briarproject.briar.android.settings.SettingsActivityScreenshotTest', ]) app_apk_path "build/outputs/apk/screenshot/debug/briar-android-screenshot-debug.apk" tests_apk_path "build/outputs/apk/androidTest/screenshot/debug/briar-android-screenshot-debug-androidTest.apk" diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java index 6634d5bfc..156620b1d 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarTestComponentApplication.java @@ -7,7 +7,7 @@ public class BriarTestComponentApplication extends BriarApplicationImpl { @Override protected AndroidComponent createApplicationComponent() { - AndroidComponent component = DaggerTestComponent.builder() + AndroidComponent component = DaggerBriarUiTestComponent.builder() .appModule(new AppModule(this)).build(); // We need to load the eager singletons directly after making the // dependency graphs diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarUiTestComponent.java similarity index 68% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/BriarUiTestComponent.java index 240eb6f14..af1cba5f0 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/TestComponent.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/BriarUiTestComponent.java @@ -5,9 +5,9 @@ import org.briarproject.bramble.BrambleCoreModule; import org.briarproject.bramble.account.BriarAccountModule; import org.briarproject.briar.BriarCoreModule; import org.briarproject.briar.android.login.PasswordActivityTest; -import org.briarproject.briar.android.login.SetupActivityTest; +import org.briarproject.briar.android.login.SetupActivityScreenshotTest; import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest; -import org.briarproject.briar.android.settings.SettingsActivityTest; +import org.briarproject.briar.android.settings.SettingsActivityScreenshotTest; import javax.inject.Singleton; @@ -21,11 +21,11 @@ import dagger.Component; BriarAccountModule.class, BrambleCoreModule.class }) -public interface TestComponent extends AndroidComponent { +public interface BriarUiTestComponent extends AndroidComponent { - void inject(SetupActivityTest test); + void inject(SetupActivityScreenshotTest test); void inject(PasswordActivityTest test); void inject(NavDrawerActivityTest test); - void inject(SettingsActivityTest test); + void inject(SettingsActivityScreenshotTest test); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java index 0f7ce89b9..5d9f025d4 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java @@ -3,7 +3,7 @@ package org.briarproject.briar.android.login; import android.support.test.runner.AndroidJUnit4; import org.briarproject.briar.R; -import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.BriarUiTestComponent; import org.briarproject.briar.android.test.ScreenshotTest; import org.junit.Ignore; import org.junit.Rule; @@ -28,7 +28,7 @@ public class PasswordActivityTest extends ScreenshotTest { new CleanAccountTestRule<>(PasswordActivity.class); @Override - protected void inject(TestComponent component) { + protected void inject(BriarUiTestComponent component) { component.inject(this); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityScreenshotTest.java similarity index 95% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityScreenshotTest.java index 922cad655..475ae87a1 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/SetupActivityScreenshotTest.java @@ -7,7 +7,7 @@ import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiSelector; import org.briarproject.briar.R; -import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.BriarUiTestComponent; import org.briarproject.briar.android.test.ScreenshotTest; import org.junit.Rule; import org.junit.Test; @@ -33,7 +33,7 @@ import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; @RunWith(AndroidJUnit4.class) -public class SetupActivityTest extends ScreenshotTest { +public class SetupActivityScreenshotTest extends ScreenshotTest { @Rule public IntentsTestRule testRule = @@ -46,7 +46,7 @@ public class SetupActivityTest extends ScreenshotTest { }; @Override - protected void inject(TestComponent component) { + protected void inject(BriarUiTestComponent component) { component.inject(this); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java index 395ed8c48..e92ae6693 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/navdrawer/NavDrawerActivityTest.java @@ -5,7 +5,7 @@ import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; import org.briarproject.briar.R; -import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.BriarUiTestComponent; import org.briarproject.briar.android.settings.SettingsActivity; import org.briarproject.briar.android.test.ScreenshotTest; import org.junit.Rule; @@ -30,7 +30,7 @@ public class NavDrawerActivityTest extends ScreenshotTest { new CleanAccountTestRule<>(NavDrawerActivity.class); @Override - protected void inject(TestComponent component) { + protected void inject(BriarUiTestComponent component) { component.inject(this); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityScreenshotTest.java similarity index 91% rename from briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java rename to briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityScreenshotTest.java index b5c32f46f..192680bd7 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/settings/SettingsActivityScreenshotTest.java @@ -6,7 +6,7 @@ import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; import org.briarproject.briar.R; -import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.BriarUiTestComponent; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; import org.briarproject.briar.android.test.ScreenshotTest; import org.junit.Rule; @@ -22,14 +22,14 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) -public class SettingsActivityTest extends ScreenshotTest { +public class SettingsActivityScreenshotTest extends ScreenshotTest { @Rule public CleanAccountTestRule testRule = new CleanAccountTestRule<>(SettingsActivity.class); @Override - protected void inject(TestComponent component) { + protected void inject(BriarUiTestComponent component) { component.inject(this); } diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java index 77ed5faac..355dd7763 100644 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java +++ b/briar-android/src/androidTest/java/org/briarproject/briar/android/test/ScreenshotTest.java @@ -7,7 +7,7 @@ import android.util.Log; import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.briar.android.BriarTestComponentApplication; -import org.briarproject.briar.android.TestComponent; +import org.briarproject.briar.android.BriarUiTestComponent; import org.junit.ClassRule; import javax.inject.Inject; @@ -38,10 +38,10 @@ public abstract class ScreenshotTest { BriarTestComponentApplication app = (BriarTestComponentApplication) getTargetContext() .getApplicationContext(); - inject((TestComponent) app.getApplicationComponent()); + inject((BriarUiTestComponent) app.getApplicationComponent()); } - protected abstract void inject(TestComponent component); + protected abstract void inject(BriarUiTestComponent component); protected void screenshot(String name) { try { From edb8e8f9d0783c3e8963b1e2698e8772d4b2d0ea Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 3 Aug 2018 13:08:18 -0300 Subject: [PATCH 09/10] Move res values from build.gradle into strings.xml This fixes an issue where the build type values were overriding the flavor values. --- briar-android/build.gradle | 39 ++++++++----------- .../src/debug/res/values/strings.xml | 5 +++ briar-android/src/main/res/values/strings.xml | 3 ++ .../AndroidManifest.xml | 0 .../screenshotDebug/res/values/strings.xml | 5 +++ 5 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 briar-android/src/debug/res/values/strings.xml rename briar-android/src/{screenshot => screenshotDebug}/AndroidManifest.xml (100%) create mode 100644 briar-android/src/screenshotDebug/res/values/strings.xml diff --git a/briar-android/build.gradle b/briar-android/build.gradle index 1fe8855d9..a39240a65 100644 --- a/briar-android/build.gradle +++ b/briar-android/build.gradle @@ -264,8 +264,6 @@ android { versionCode 10013 versionName "1.0.13" applicationId "org.briarproject.briar.android" - resValue "string", "app_package", "org.briarproject.briar.android" - resValue "string", "app_name", "Briar" buildConfigField "String", "GitHash", "\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\"" def now = (long) (System.currentTimeMillis() / 1000) @@ -274,29 +272,9 @@ android { testInstrumentationRunner 'org.briarproject.briar.android.test.BriarTestRunner' } - flavorDimensions "version" - productFlavors { - screenshot { - dimension "version" - minSdkVersion 18 - applicationIdSuffix ".screenshot" - resValue "string", "app_package", "org.briarproject.briar.android.screenshot.debug" - } - main { - dimension "version" - } - } - variantFilter { variant -> - if (variant.flavors*.name.contains("screenshot") && variant.buildType.name == "release") { - setIgnore(true) - } - } - buildTypes { debug { applicationIdSuffix ".debug" - resValue "string", "app_package", "org.briarproject.briar.android.debug" - resValue "string", "app_name", "Briar Debug" shrinkResources false minifyEnabled true crunchPngs false @@ -311,6 +289,23 @@ android { } } + flavorDimensions "version" + productFlavors { + screenshot { + dimension "version" + minSdkVersion 18 + applicationIdSuffix ".screenshot" // = org.briarproject.briar.android.screenshot.debug + } + main { + dimension "version" + } + } + variantFilter { variant -> + if (variant.flavors*.name.contains("screenshot") && variant.buildType.name == "release") { + setIgnore(true) + } + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 diff --git a/briar-android/src/debug/res/values/strings.xml b/briar-android/src/debug/res/values/strings.xml new file mode 100644 index 000000000..5cbb56beb --- /dev/null +++ b/briar-android/src/debug/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Briar Debug + org.briarproject.briar.android.debug + diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 086ff8c3f..8456ceda1 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -1,6 +1,9 @@ + Briar + org.briarproject.briar.android + Welcome to Briar Your nickname will be shown next to any content you post. You can\'t change it after creating your account. diff --git a/briar-android/src/screenshot/AndroidManifest.xml b/briar-android/src/screenshotDebug/AndroidManifest.xml similarity index 100% rename from briar-android/src/screenshot/AndroidManifest.xml rename to briar-android/src/screenshotDebug/AndroidManifest.xml diff --git a/briar-android/src/screenshotDebug/res/values/strings.xml b/briar-android/src/screenshotDebug/res/values/strings.xml new file mode 100644 index 000000000..6a7574e56 --- /dev/null +++ b/briar-android/src/screenshotDebug/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Briar + org.briarproject.briar.android.screenshot.debug + From b238b28ef9e4dbd4c6dcdc20a31e51a882cf2e85 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 3 Aug 2018 13:09:42 -0300 Subject: [PATCH 10/10] Remove PasswordActivity test since it doesn't work anyway --- .../android/login/PasswordActivityTest.java | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java diff --git a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java b/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java deleted file mode 100644 index 5d9f025d4..000000000 --- a/briar-android/src/androidTest/java/org/briarproject/briar/android/login/PasswordActivityTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.briarproject.briar.android.login; - -import android.support.test.runner.AndroidJUnit4; - -import org.briarproject.briar.R; -import org.briarproject.briar.android.BriarUiTestComponent; -import org.briarproject.briar.android.test.ScreenshotTest; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.typeText; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.intent.Intents.intended; -import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; - - -@RunWith(AndroidJUnit4.class) -public class PasswordActivityTest extends ScreenshotTest { - - @Rule - public CleanAccountTestRule testRule = - new CleanAccountTestRule<>(PasswordActivity.class); - - @Override - protected void inject(BriarUiTestComponent component) { - component.inject(this); - } - - // FIXME - @Ignore("Need to find a way to sign-out after creating fresh account") - @Test - public void successfulLogin() { - onView(withId(R.id.edit_password)) - .check(matches(isDisplayed())) - .perform(typeText(PASSWORD)); - onView(withId(R.id.btn_sign_in)) - .check(matches(isDisplayed())) - .perform(click()); - onView(withId(R.id.progress)) - .check(matches(isDisplayed())); - intended(hasComponent(OpenDatabaseActivity.class.getName())); - } - -}