From 7d0a1f8d8057faa74035de0cee262a46c6fbbe00 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 23 Jan 2023 19:47:56 +0100 Subject: setup fastlane to create screenshots for Bitmask and custom branded clients, refactor Tests accordingly and create a script and environment variables to run fastlane screenshotting without thinking --- .../leap/bitmaskclient/base/ProviderBaseTest.java | 157 ++++++++++++++++++ .../leap/bitmaskclient/base/ProviderSetupTest.java | 68 -------- .../se/leap/bitmaskclient/base/VpnStartTest.java | 176 --------------------- .../leap/bitmaskclient/suite/ScreenshotTest.java | 19 --- .../androidTest/java/utils/CustomInteractions.java | 1 + .../bitmaskclient/base/CustomProviderTest.java | 49 ++++++ .../leap/bitmaskclient/suite/ScreenshotTest.java | 17 ++ .../se/leap/bitmaskclient/base/BitmaskTest.java | 42 +++++ .../leap/bitmaskclient/base/ProviderSetupTest.java | 68 ++++++++ .../leap/bitmaskclient/suite/ScreenshotTest.java | 19 +++ fastlane/.env.custom | 3 + fastlane/.env.default | 3 + fastlane/Fastfile | 46 +++++- fastlane/README.md | 28 +++- fastlane/Screengrabfile | 4 - scripts/fastlane.sh | 34 ++++ 16 files changed, 464 insertions(+), 270 deletions(-) create mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java delete mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderSetupTest.java delete mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/base/VpnStartTest.java delete mode 100644 app/src/androidTest/java/se/leap/bitmaskclient/suite/ScreenshotTest.java create mode 100644 app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java create mode 100644 app/src/androidTestCustom/java/se/leap/bitmaskclient/suite/ScreenshotTest.java create mode 100644 app/src/androidTestNormal/java/se/leap/bitmaskclient/base/BitmaskTest.java create mode 100644 app/src/androidTestNormal/java/se/leap/bitmaskclient/base/ProviderSetupTest.java create mode 100644 app/src/androidTestNormal/java/se/leap/bitmaskclient/suite/ScreenshotTest.java create mode 100644 fastlane/.env.custom create mode 100644 fastlane/.env.default create mode 100755 scripts/fastlane.sh diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java b/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java new file mode 100644 index 00000000..bbfcdc8b --- /dev/null +++ b/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java @@ -0,0 +1,157 @@ +package se.leap.bitmaskclient.base; + +import static android.content.Context.MODE_PRIVATE; +import static androidx.test.core.app.ApplicationProvider.getApplicationContext; +import static androidx.test.espresso.Espresso.onData; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.contrib.DrawerMatchers.isClosed; +import static androidx.test.espresso.matcher.RootMatchers.isDialog; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withTagValue; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anything; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.is; +import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; +import static utils.CustomInteractions.tryResolve; + +import android.content.SharedPreferences; +import android.view.Gravity; + +import androidx.test.espresso.DataInteraction; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.espresso.ViewInteraction; +import androidx.test.espresso.contrib.DrawerActions; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import se.leap.bitmaskclient.R; +import tools.fastlane.screengrab.Screengrab; +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; +import tools.fastlane.screengrab.locale.LocaleTestRule; + +@LargeTest +@RunWith(AndroidJUnit4.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public abstract class ProviderBaseTest { + + @ClassRule + public static final LocaleTestRule localeTestRule = new LocaleTestRule(); + + @Rule + public ActivityScenarioRule mActivityScenarioRule = + new ActivityScenarioRule<>(StartActivity.class); + + @Before + public void setup() { + Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); + SharedPreferences preferences = getApplicationContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + preferences.edit().clear().commit(); + } + + @Test + public void test01_vpnStartTest() throws InterruptedException { + boolean configurationNeeded = configureProviderIfNeeded(); + + ViewInteraction mainButtonStop; + if (!configurationNeeded) { + // click on Main on/off button and start VPN + ViewInteraction mainButton = tryResolve( + onView(withId(R.id.main_button)), + matches(isDisplayed()) + ); + + mainButton.perform(click()); + Thread.sleep(50); + Screengrab.screenshot("VPN_connecting"); + + mainButtonStop = tryResolve( + onView(allOf( + withId(R.id.button), + withTagValue(is("button_circle_stop")))), + matches(isDisplayed()), + 20); + Screengrab.screenshot("VPN_connected"); + } else { + // on new configurations the VPN is automatically started + Screengrab.screenshot("VPN_connecting"); + mainButtonStop = tryResolve( + onView(allOf( + withId(R.id.button), + withTagValue(is("button_circle_stop")))), + matches(isDisplayed()), + 20); + Screengrab.screenshot("VPN_connected"); + } + + mainButtonStop.perform(click()); + Screengrab.screenshot("VPN_ask_disconnect"); + + onView(withText(android.R.string.yes)) + .inRoot(isDialog()) + .check(matches(isDisplayed())) + .perform(click()); + Screengrab.screenshot("VPN_disconnected"); + } + + @Test + public void test02_SettingsFragmentScreenshots() { + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. + .perform(DrawerActions.open()); // Open Drawer + + Screengrab.screenshot("navigationDrawer"); + + // Start the screen of your activity. + onView(withId(R.id.advancedSettings)) + .perform(click()); + + Screengrab.screenshot("settingsFragment"); + } + + @Test + public void test03_LocationSelectionFragmentScreenshots() { + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. + .perform(DrawerActions.open()); // Open Drawer + + onView(withId(R.id.manualGatewaySelection)) + .perform(click()); + + Screengrab.screenshot("GatewaySelectionFragment"); + } + + @Test + public void test04_AppExclusionFragmentScreenshots() { + onView(withId(R.id.drawer_layout)) + .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. + .perform(DrawerActions.open()); // Open Drawer + + onView(withId(R.id.advancedSettings)).perform(click()); + + onView(withId(R.id.exclude_apps)).perform(click()); + + tryResolve( + onData(anything()).inAdapterView(withId(android.R.id.list)).atPosition(2), + matches(isDisplayed()), + 5); + + Screengrab.screenshot("App_Exclusion_Fragment"); + } + + public abstract boolean configureProviderIfNeeded(); +} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderSetupTest.java b/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderSetupTest.java deleted file mode 100644 index 23db8582..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderSetupTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package se.leap.bitmaskclient.base; - - -import static android.content.Context.MODE_PRIVATE; -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -import static androidx.test.espresso.Espresso.onData; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static org.hamcrest.Matchers.anything; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasToString; -import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; -import static utils.CustomInteractions.tryResolve; - -import android.content.SharedPreferences; - -import androidx.test.espresso.DataInteraction; -import androidx.test.espresso.NoMatchingViewException; -import androidx.test.ext.junit.rules.ActivityScenarioRule; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.LargeTest; - -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.providersetup.ProviderListActivity; -import tools.fastlane.screengrab.Screengrab; -import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; -import tools.fastlane.screengrab.locale.LocaleTestRule; - -@LargeTest -@RunWith(AndroidJUnit4.class) -public class ProviderSetupTest { - - @ClassRule - public static final LocaleTestRule localeTestRule = new LocaleTestRule(); - - @Rule - public ActivityScenarioRule mActivityScenarioRule = - new ActivityScenarioRule<>(ProviderListActivity.class); - - @Before - public void setup() { - Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); - SharedPreferences preferences = getApplicationContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - preferences.edit().clear().commit(); - } - - @Test - public void testConfigureRiseupVPNScreenshot() { - DataInteraction linearLayout = tryResolve(onData(hasToString(containsString("riseup.net"))) - .inAdapterView(withId(R.id.provider_list)), - 2); - Screengrab.screenshot("ProviderListActivity"); - linearLayout.perform(click()); - Screengrab.screenshot("ProviderListActivity_configureRiseup"); - } - - @Test - public void testaddManuallyNewProviderScreenshot() { - onData(anything()).inAdapterView(withId(R.id.provider_list)).atPosition(3).perform(click()); - Screengrab.screenshot("ProviderListActivity_addManuallyNewProvider"); - } -} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/base/VpnStartTest.java b/app/src/androidTest/java/se/leap/bitmaskclient/base/VpnStartTest.java deleted file mode 100644 index 6c99b90e..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/base/VpnStartTest.java +++ /dev/null @@ -1,176 +0,0 @@ -package se.leap.bitmaskclient.base; - - -import static android.content.Context.MODE_PRIVATE; -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -import static androidx.test.espresso.Espresso.onData; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.contrib.DrawerMatchers.isClosed; -import static androidx.test.espresso.matcher.RootMatchers.isDialog; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withTagValue; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.anything; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasToString; -import static org.hamcrest.Matchers.is; -import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; -import static utils.CustomInteractions.tryResolve; - -import android.content.SharedPreferences; -import android.view.Gravity; - -import androidx.test.espresso.DataInteraction; -import androidx.test.espresso.NoMatchingViewException; -import androidx.test.espresso.ViewInteraction; -import androidx.test.espresso.contrib.DrawerActions; -import androidx.test.ext.junit.rules.ActivityScenarioRule; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.LargeTest; - -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; - -import se.leap.bitmaskclient.R; -import tools.fastlane.screengrab.Screengrab; -import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; -import tools.fastlane.screengrab.locale.LocaleTestRule; - -@LargeTest -@RunWith(AndroidJUnit4.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class VpnStartTest { - - @ClassRule - public static final LocaleTestRule localeTestRule = new LocaleTestRule(); - - @Rule - public ActivityScenarioRule mActivityScenarioRule = - new ActivityScenarioRule<>(StartActivity.class); - - @Before - public void setup() { - Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); - SharedPreferences preferences = getApplicationContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - preferences.edit().clear().commit(); - } - - @Test - public void test01_vpnStartTest() { - boolean configurationNeeded = configureProviderIfNeeded(); - - ViewInteraction mainButtonStop; - if (!configurationNeeded) { - // click on Main on/off button and start VPN - ViewInteraction mainButton = tryResolve( - onView(withId(R.id.main_button)), - matches(isDisplayed()) - ); - - mainButton.perform(click()); - tryResolve( - onView(allOf( - withId(R.id.button), - withTagValue(is("button_circle_cancel")))), - matches(isDisplayed()), - 2); - Screengrab.screenshot("VPN_connecting"); - - mainButtonStop = tryResolve( - onView(allOf( - withId(R.id.button), - withTagValue(is("button_circle_stop")))), - matches(isDisplayed()), - 20); - Screengrab.screenshot("VPN_connected"); - } else { - // on new configurations the VPN is automatically started - Screengrab.screenshot("VPN_connecting"); - mainButtonStop = tryResolve( - onView(allOf( - withId(R.id.button), - withTagValue(is("button_circle_stop")))), - matches(isDisplayed()), - 20); - Screengrab.screenshot("VPN_connected"); - } - - mainButtonStop.perform(click()); - Screengrab.screenshot("VPN_ask_disconnect"); - - onView(withText(android.R.string.yes)) - .inRoot(isDialog()) - .check(matches(isDisplayed())) - .perform(click()); - Screengrab.screenshot("VPN_disconnected"); - } - - @Test - public void test02_SettingsFragmentScreenshots() { - onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. - .perform(DrawerActions.open()); // Open Drawer - - Screengrab.screenshot("navigationDrawer"); - - // Start the screen of your activity. - onView(withId(R.id.advancedSettings)) - .perform(click()); - - Screengrab.screenshot("settingsFragment"); - } - - @Test - public void test03_LocationSelectionFragmentScreenshots() { - onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. - .perform(DrawerActions.open()); // Open Drawer - - onView(withId(R.id.manualGatewaySelection)) - .perform(click()); - - Screengrab.screenshot("GatewaySelectionFragment"); - } - - @Test - public void test04_AppExclusionFragmentScreenshots() { - onView(withId(R.id.drawer_layout)) - .check(matches(isClosed(Gravity.LEFT))) // Left Drawer should be closed. - .perform(DrawerActions.open()); // Open Drawer - - onView(withId(R.id.advancedSettings)).perform(click()); - - onView(withId(R.id.exclude_apps)).perform(click()); - - tryResolve( - onData(anything()).inAdapterView(withId(android.R.id.list)).atPosition(2), - matches(isDisplayed()), - 5); - - Screengrab.screenshot("App_Exclusion_Fragment"); - } - - public boolean configureProviderIfNeeded() { - try { - DataInteraction linearLayout = tryResolve(onData(hasToString(containsString("riseup.net"))) - .inAdapterView(withId(R.id.provider_list)), - 2); - linearLayout.perform(click()); - return true; - } catch (NoMatchingViewException e) { - // it might be that the provider was already configured, so we print the stack - // trace here and try to continue - e.printStackTrace(); - } - return false; - } -} diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/suite/ScreenshotTest.java b/app/src/androidTest/java/se/leap/bitmaskclient/suite/ScreenshotTest.java deleted file mode 100644 index 186a50d1..00000000 --- a/app/src/androidTest/java/se/leap/bitmaskclient/suite/ScreenshotTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package se.leap.bitmaskclient.suite; - - -import androidx.test.filters.LargeTest; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -import se.leap.bitmaskclient.base.ProviderSetupTest; -import se.leap.bitmaskclient.base.VpnStartTest; - -@LargeTest -@RunWith(Suite.class) -@Suite.SuiteClasses({ - ProviderSetupTest.class, - VpnStartTest.class, -}) -public class ScreenshotTest { -} diff --git a/app/src/androidTest/java/utils/CustomInteractions.java b/app/src/androidTest/java/utils/CustomInteractions.java index 896e8d9b..9e3a8f9d 100644 --- a/app/src/androidTest/java/utils/CustomInteractions.java +++ b/app/src/androidTest/java/utils/CustomInteractions.java @@ -31,6 +31,7 @@ public class CustomInteractions { hasFound = true; } catch (NoMatchingViewException exception) { System.out.println("NoMatchingViewException attempt: " + attempt); + exception.printStackTrace(); attempt++; if (attempt == maxTries) { throw exception; diff --git a/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java b/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java new file mode 100644 index 00000000..1a0814b6 --- /dev/null +++ b/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java @@ -0,0 +1,49 @@ +package se.leap.bitmaskclient.base; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.RootMatchers.isDialog; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static utils.CustomInteractions.tryResolve; + +import androidx.test.espresso.ViewInteraction; + +import org.junit.Test; + +import se.leap.bitmaskclient.R; +import tools.fastlane.screengrab.Screengrab; + +public class CustomProviderTest extends ProviderBaseTest { + + @Test + @Override + public void test01_vpnStartTest() throws InterruptedException { + ViewInteraction mainButtonStop; + mainButtonStop = tryResolve( + onView(withId(R.id.main_button)), + matches(isDisplayed()), + 30); + Screengrab.screenshot("VPN_connected"); + + mainButtonStop.perform(click()); + Screengrab.screenshot("VPN_ask_disconnect"); + + ViewInteraction alertDialogOKbutton = tryResolve(onView(withText(android.R.string.yes)) + .inRoot(isDialog()), + matches(isDisplayed())); + alertDialogOKbutton.perform(click()); + Screengrab.screenshot("VPN_disconnected"); + + mainButtonStop.perform(click()); + Thread.sleep(50); + Screengrab.screenshot("VPN_connecting"); + } + + @Override + public boolean configureProviderIfNeeded() { + return false; + } +} \ No newline at end of file diff --git a/app/src/androidTestCustom/java/se/leap/bitmaskclient/suite/ScreenshotTest.java b/app/src/androidTestCustom/java/se/leap/bitmaskclient/suite/ScreenshotTest.java new file mode 100644 index 00000000..a19b0ffd --- /dev/null +++ b/app/src/androidTestCustom/java/se/leap/bitmaskclient/suite/ScreenshotTest.java @@ -0,0 +1,17 @@ +package se.leap.bitmaskclient.suite; + + +import androidx.test.filters.LargeTest; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import se.leap.bitmaskclient.base.CustomProviderTest; + +@LargeTest +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CustomProviderTest.class +}) +public class ScreenshotTest { +} diff --git a/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/BitmaskTest.java b/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/BitmaskTest.java new file mode 100644 index 00000000..aa437c74 --- /dev/null +++ b/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/BitmaskTest.java @@ -0,0 +1,42 @@ +package se.leap.bitmaskclient.base; + + +import static androidx.test.espresso.Espresso.onData; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasToString; +import static utils.CustomInteractions.tryResolve; + +import androidx.test.espresso.DataInteraction; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; + +import org.junit.FixMethodOrder; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import se.leap.bitmaskclient.R; + +@LargeTest +@RunWith(AndroidJUnit4.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class BitmaskTest extends ProviderBaseTest { + + @Override + public boolean configureProviderIfNeeded() { + try { + DataInteraction linearLayout = tryResolve(onData(hasToString(containsString("riseup.net"))) + .inAdapterView(withId(R.id.provider_list)), + 2); + linearLayout.perform(click()); + return true; + } catch (NoMatchingViewException e) { + // it might be that the provider was already configured, so we print the stack + // trace here and try to continue + e.printStackTrace(); + } + return false; + } +} diff --git a/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/ProviderSetupTest.java b/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/ProviderSetupTest.java new file mode 100644 index 00000000..23db8582 --- /dev/null +++ b/app/src/androidTestNormal/java/se/leap/bitmaskclient/base/ProviderSetupTest.java @@ -0,0 +1,68 @@ +package se.leap.bitmaskclient.base; + + +import static android.content.Context.MODE_PRIVATE; +import static androidx.test.core.app.ApplicationProvider.getApplicationContext; +import static androidx.test.espresso.Espresso.onData; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static org.hamcrest.Matchers.anything; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.hasToString; +import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; +import static utils.CustomInteractions.tryResolve; + +import android.content.SharedPreferences; + +import androidx.test.espresso.DataInteraction; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.LargeTest; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.providersetup.ProviderListActivity; +import tools.fastlane.screengrab.Screengrab; +import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; +import tools.fastlane.screengrab.locale.LocaleTestRule; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class ProviderSetupTest { + + @ClassRule + public static final LocaleTestRule localeTestRule = new LocaleTestRule(); + + @Rule + public ActivityScenarioRule mActivityScenarioRule = + new ActivityScenarioRule<>(ProviderListActivity.class); + + @Before + public void setup() { + Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); + SharedPreferences preferences = getApplicationContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + preferences.edit().clear().commit(); + } + + @Test + public void testConfigureRiseupVPNScreenshot() { + DataInteraction linearLayout = tryResolve(onData(hasToString(containsString("riseup.net"))) + .inAdapterView(withId(R.id.provider_list)), + 2); + Screengrab.screenshot("ProviderListActivity"); + linearLayout.perform(click()); + Screengrab.screenshot("ProviderListActivity_configureRiseup"); + } + + @Test + public void testaddManuallyNewProviderScreenshot() { + onData(anything()).inAdapterView(withId(R.id.provider_list)).atPosition(3).perform(click()); + Screengrab.screenshot("ProviderListActivity_addManuallyNewProvider"); + } +} diff --git a/app/src/androidTestNormal/java/se/leap/bitmaskclient/suite/ScreenshotTest.java b/app/src/androidTestNormal/java/se/leap/bitmaskclient/suite/ScreenshotTest.java new file mode 100644 index 00000000..5fa45a95 --- /dev/null +++ b/app/src/androidTestNormal/java/se/leap/bitmaskclient/suite/ScreenshotTest.java @@ -0,0 +1,19 @@ +package se.leap.bitmaskclient.suite; + + +import androidx.test.filters.LargeTest; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import se.leap.bitmaskclient.base.ProviderSetupTest; +import se.leap.bitmaskclient.base.BitmaskTest; + +@LargeTest +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ProviderSetupTest.class, + BitmaskTest.class, +}) +public class ScreenshotTest { +} diff --git a/fastlane/.env.custom b/fastlane/.env.custom new file mode 100644 index 00000000..9b65f5d4 --- /dev/null +++ b/fastlane/.env.custom @@ -0,0 +1,3 @@ +SCREENGRAB_APP_PACKAGE_NAME="se.leap.riseupvpn" +SCREENGRAB_APP_APK_PATH="app/build/outputs/apk/customProductionFat/debug/RiseupVPN_debug.apk" +SCREENGRAB_TESTS_APK_PATH="app/build/outputs/apk/androidTest/customProductionFat/debug/app-custom-production-fat-debug-androidTest.apk" diff --git a/fastlane/.env.default b/fastlane/.env.default new file mode 100644 index 00000000..bdb771ce --- /dev/null +++ b/fastlane/.env.default @@ -0,0 +1,3 @@ +SCREENGRAB_APP_PACKAGE_NAME="se.leap.bitmaskclient" +SCREENGRAB_APP_APK_PATH="app/build/outputs/apk/normalProductionFat/debug/Bitmask_debug.apk" +SCREENGRAB_TESTS_APK_PATH="app/build/outputs/apk/androidTest/normalProductionFat/debug/app-normal-production-fat-debug-androidTest.apk" diff --git a/fastlane/Fastfile b/fastlane/Fastfile index d985984d..a0e25930 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -21,12 +21,56 @@ platform :android do gradle(task: "test") end - lane :screenshots do + desc "Build debug and test APK for screenshots" + lane :build_bitmask_for_screengrab do + gradle( + task: 'clean' + ) + gradle( + task: 'assemble', + build_type: 'Debug', + flavor: 'NormalProductionFat' + ) + gradle( + task: 'assemble', + build_type: 'DebugAndroidTest', + flavor: 'NormalProductionFat' + ) + end + + desc "Build debug and test APK for screenshots" + lane :build_custom_for_screengrab do + gradle( + task: 'clean' + ) + gradle( + task: 'assemble', + build_type: 'Debug', + flavor: 'CustomProductionFat' + ) + gradle( + task: 'assemble', + build_type: 'DebugAndroidTest', + flavor: 'CustomProductionFat' + ) + end + + lane :bitmask_screenshots do + # Prepare builds for Automatic UI Tests + build_bitmask_for_screengrab capture_android_screenshots frameit(white: true) # deliver end + lane :custom_build_screenshots do + # Prepare builds for Automatic UI Tests + build_custom_for_screengrab + capture_android_screenshots + frameit(white: true) + # deliver + end + desc "Submit a new Beta Build to Crashlytics Beta" lane :beta do gradle(task: "clean assembleRelease") diff --git a/fastlane/README.md b/fastlane/README.md index 96002ac1..a41fc4c9 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -23,10 +23,34 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do Runs all the tests -### android screenshots +### android build_bitmask_for_screengrab ```sh -[bundle exec] fastlane android screenshots +[bundle exec] fastlane android build_bitmask_for_screengrab +``` + +Build debug and test APK for screenshots + +### android build_custom_for_screengrab + +```sh +[bundle exec] fastlane android build_custom_for_screengrab +``` + +Build debug and test APK for screenshots + +### android bitmask_screenshots + +```sh +[bundle exec] fastlane android bitmask_screenshots +``` + + + +### android custom_build_screenshots + +```sh +[bundle exec] fastlane android custom_build_screenshots ``` diff --git a/fastlane/Screengrabfile b/fastlane/Screengrabfile index 8a149163..8534db2a 100644 --- a/fastlane/Screengrabfile +++ b/fastlane/Screengrabfile @@ -1,11 +1,7 @@ # remove the leading '#' to uncomment lines -# app_package_name('your.app.package') use_tests_in_packages(['se.leap.bitmaskclient.suite']) -app_apk_path('app/build/intermediates/apk/normalProductionFat/debug/Bitmask_debug.apk') -tests_apk_path('app/build/intermediates/apk/androidTest/normalProductionFat/debug/app-normal-production-fat-debug-androidTest.apk') - # all locales # locales(['ar', 'az', 'bg', 'bn', 'br', 'ca', 'cs', 'de', 'el', 'es', 'es-AR', 'et', 'eu', 'fa-IR', 'fi', 'fr', 'gl', 'he', 'hr', 'hu', 'id', 'it', 'ja', 'my', 'nl', 'no', 'pl', 'pt-BR', 'pt-PT', 'ro', 'ru', 'tr', 'ug', 'uk', 'vi', 'zh-CN', 'zh-TW']) # prioritized locales diff --git a/scripts/fastlane.sh b/scripts/fastlane.sh new file mode 100755 index 00000000..f039cd24 --- /dev/null +++ b/scripts/fastlane.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +GREEN='\033[0;32m' +RED='\033[0;31m' +NC='\033[0m' + +# init parameters +if [[ ${1} = "custom" ]]; then + BUILD_CUSTOM=true +elif [[ ! -z ${1} ]]; then + echo -e """${RED}Failed due to wrong arguments.${NC} + Usage: + ====== + ${GREEN}create screenshots for Bitmask:${NC} + ./fastlane.sh + + ${GREEN}create screenshots for your custom build${NC} (please adopt the environment variables in './fastlane/.env.custom'): + ./fastlane.sh custom + """ + exit 1 +fi; + +#screengrab related environment variables can be found in ./fastlane/.env.* +SCRIPT_DIR=$(dirname "$0") +BASE_DIR="$SCRIPT_DIR/.." + +cd $BASE_DIR +if [[ -z $BUILD_CUSTOM ]]; then + fastlane android bitmask_screenshots +else + fastlane android custom_build_screenshots --env custom +fi; +cd - + -- cgit v1.2.3