From f8001b40d78d07fa2c57f3f09839e01bb251f6fc Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Fri, 11 Feb 2022 10:53:15 +0200 Subject: [PATCH] For #21002: Adds UI test for Addons in private mode --- .../mozilla/fenix/helpers/TestAssetHelper.kt | 3 +- .../mozilla/fenix/ui/SettingsAddonsTest.kt | 102 +++++++++++++----- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 51 ++++----- .../SettingsSubMenuAddonsManagerRobot.kt | 53 +++++---- .../fenix/ui/robots/ThreeDotMenuMainRobot.kt | 14 ++- 5 files changed, 143 insertions(+), 80 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt index 562c3ef1d611..32f380e7b731 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestAssetHelper.kt @@ -69,8 +69,9 @@ object TestAssetHelper { fun getEnhancedTrackingProtectionAsset(server: MockWebServer): TestAsset { val url = server.url("pages/trackingPage.html").toString().toUri()!! + val content = "Level 1 (Basic) List" - return TestAsset(url, "", "") + return TestAsset(url, content, "") } fun getImageAsset(server: MockWebServer): TestAsset { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt index ae112c488ebe..0d1d5796511d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt @@ -12,11 +12,14 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R +import org.mozilla.fenix.customannotations.SmokeTest +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.RecyclerViewIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource +import org.mozilla.fenix.ui.robots.addonsMenu import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar @@ -24,10 +27,7 @@ import org.mozilla.fenix.ui.robots.navigationToolbar * Tests for verifying the functionality of installing or removing addons * */ - class SettingsAddonsTest { - /* ktlint-disable no-blank-line-before-rbrace */ // This imposes unreadable grouping. - private lateinit var mockWebServer: MockWebServer private var addonsListIdlingResource: RecyclerViewIdlingResource? = null private var addonContainerIdlingResource: ViewVisibilityIdlingResource? = null @@ -72,14 +72,12 @@ class SettingsAddonsTest { } } - // Opens a webpage and installs an add-on from the three-dot menu + // Installs an add-on from the Add-ons menu and verifies the prompts @Test - fun installAddonFromThreeDotMenu() { - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + fun installAddonTest() { val addonName = "uBlock Origin" - navigationToolbar {} - .enterURLAndEnterToBrowser(defaultWebPage.url) {} + homeScreen {} .openThreeDotMenu {} .openAddonsManagerMenu { addonsListIdlingResource = @@ -89,32 +87,24 @@ class SettingsAddonsTest { ) IdlingRegistry.getInstance().register(addonsListIdlingResource!!) clickInstallAddon(addonName) - verifyAddonPrompt(addonName) + verifyAddonPermissionPrompt(addonName) cancelInstallAddon() clickInstallAddon(addonName) - acceptInstallAddon() - - verifyDownloadAddonPrompt(addonName, activityTestRule) + acceptPermissionToInstallAddon() + closeAddonInstallCompletePrompt(addonName, activityTestRule) + verifyAddonIsInstalled(addonName) + verifyEnabledTitleDisplayed() } } - // Opens the addons settings menu, installs an addon, then uninstalls + // Installs an addon, then uninstalls it @Test fun verifyAddonsCanBeUninstalled() { val addonName = "uBlock Origin" - homeScreen { - }.openThreeDotMenu { - }.openSettings { - verifyAdvancedHeading() - verifyAddons() - }.openAddonsManagerMenu { - addonsListIdlingResource = - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1) - IdlingRegistry.getInstance().register(addonsListIdlingResource!!) - clickInstallAddon(addonName) - acceptInstallAddon() - verifyDownloadAddonPrompt(addonName, activityTestRule) + addonsMenu { + installAddon(addonName) + closeAddonInstallCompletePrompt(addonName, activityTestRule) IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!) }.openDetailedMenuForAddon(addonName) { addonContainerIdlingResource = ViewVisibilityIdlingResource( @@ -123,6 +113,68 @@ class SettingsAddonsTest { ) IdlingRegistry.getInstance().register(addonContainerIdlingResource!!) }.removeAddon { + verifyAddonCanBeInstalled(addonName) + } + } + + @SmokeTest + @Test + // Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers + fun noCrashWithAddonInstalledTest() { + // setting ETP to Strict mode to test it works with add-ons + activityTestRule.activity.settings().setStrictETP() + + val addonName = "uBlock Origin" + val trackingProtectionPage = + TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer) + + addonsMenu { + installAddon(addonName) + closeAddonInstallCompletePrompt(addonName, activityTestRule) + IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!) + }.goBack { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(trackingProtectionPage.url) { + verifyPageContent(trackingProtectionPage.content) + } + } + + @SmokeTest + @Test + fun useAddonsInPrivateModeTest() { + val addonName = "uBlock Origin" + val trackingPage = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer) + + homeScreen { + }.togglePrivateBrowsingMode() + addonsMenu { + installAddon(addonName) + selectAllowInPrivateBrowsing(activityTestRule) + closeAddonInstallCompletePrompt(addonName, activityTestRule) + IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!) + }.goBack {} + navigationToolbar { + }.enterURLAndEnterToBrowser(trackingPage.url) { + verifyPageContent(trackingPage.content) + }.openThreeDotMenu { + openAddonsSubList() + verifyAddonAvailableInMainMenu(addonName) + } + } + + private fun installAddon(addonName: String) { + homeScreen { + }.openThreeDotMenu { + }.openAddonsManagerMenu { + addonsListIdlingResource = + RecyclerViewIdlingResource( + activityTestRule.activity.findViewById(R.id.add_ons_list), + 1 + ) + IdlingRegistry.getInstance().register(addonsListIdlingResource!!) + clickInstallAddon(addonName) + verifyAddonPermissionPrompt(addonName) + acceptPermissionToInstallAddon() } } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index ee84f84ed913..0e8de5e36b9a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -24,7 +24,6 @@ import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.R import org.mozilla.fenix.customannotations.SmokeTest import org.mozilla.fenix.ext.components -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.Constants import org.mozilla.fenix.helpers.FeatureSettingsHelper @@ -262,6 +261,26 @@ class SmokeTest { } } + @Test + // Verifies the Add-ons menu opens from a tab's 3 dot menu + fun openMainMenuAddonsTest() { + val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + navigationToolbar { + }.enterURLAndEnterToBrowser(defaultWebPage.url) { + }.openThreeDotMenu { + }.openAddonsManagerMenu { + addonsListIdlingResource = + RecyclerViewIdlingResource( + activityTestRule.activity.findViewById(R.id.add_ons_list), + 1 + ) + IdlingRegistry.getInstance().register(addonsListIdlingResource!!) + verifyAddonsItems() + IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!) + } + } + @Test // Verifies the Synced tabs menu or Sync Sign In menu opens from a tab's 3 dot menu. // The test is assuming we are NOT signed in. @@ -565,36 +584,6 @@ class SmokeTest { } } - @Test - // Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers - fun noCrashWithAddonInstalledTest() { - // setting ETP to Strict mode to test it works with add-ons - activityTestRule.activity.settings().setStrictETP() - - val addonName = "uBlock Origin" - val trackingProtectionPage = - TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer) - - homeScreen { - }.openThreeDotMenu { - }.openAddonsManagerMenu { - addonsListIdlingResource = - RecyclerViewIdlingResource( - activityTestRule.activity.findViewById(R.id.add_ons_list), - 1 - ) - IdlingRegistry.getInstance().register(addonsListIdlingResource!!) - clickInstallAddon(addonName) - acceptInstallAddon() - verifyDownloadAddonPrompt(addonName, activityTestRule.activityRule) - IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!) - }.goBack { - }.openNavigationToolbar { - }.enterURLAndEnterToBrowser(trackingProtectionPage.url) { - verifyPageContent(trackingProtectionPage.content) - } - } - @Test // Verifies that a recently closed item is properly opened fun openRecentlyClosedItemTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt index d8c61b5a0455..b3ec5b076e25 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuAddonsManagerRobot.kt @@ -33,8 +33,8 @@ import org.mozilla.fenix.R import org.mozilla.fenix.helpers.IdlingResourceHelper.registerAddonInstallingIdlingResource import org.mozilla.fenix.helpers.IdlingResourceHelper.unregisterAddonInstallingIdlingResource import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime -import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.appName +import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull @@ -43,30 +43,46 @@ import org.mozilla.fenix.helpers.ext.waitNotNull */ class SettingsSubMenuAddonsManagerRobot { - fun verifyAddonPrompt(addonName: String) = assertAddonPrompt(addonName) + fun verifyAddonPermissionPrompt(addonName: String) = assertAddonPermissionPrompt(addonName) fun clickInstallAddon(addonName: String) = selectInstallAddon(addonName) - fun verifyDownloadAddonPrompt( + fun closeAddonInstallCompletePrompt( addonName: String, activityTestRule: ActivityTestRule ) { try { - assertDownloadingAddonPrompt(addonName, activityTestRule) + assertAddonInstallCompletePrompt(addonName, activityTestRule) } catch (e: IdlingResourceTimeoutException) { if (mDevice.findObject(UiSelector().text("Failed to install $addonName")).exists()) { clickInstallAddon(addonName) - acceptInstallAddon() - assertDownloadingAddonPrompt(addonName, activityTestRule) + acceptPermissionToInstallAddon() + assertAddonInstallCompletePrompt(addonName, activityTestRule) } } } + fun verifyAddonIsInstalled(addonName: String) { + scrollToElementByText(addonName) + assertAddonIsInstalled(addonName) + } + + fun verifyEnabledTitleDisplayed() { + onView(withText("Enabled")) + .check(matches(isCompletelyDisplayed())) + } + fun cancelInstallAddon() = cancelInstall() - fun acceptInstallAddon() = allowInstall() + fun acceptPermissionToInstallAddon() = allowPermissionToInstall() fun verifyAddonsItems() = assertAddonsItems() fun verifyAddonCanBeInstalled(addonName: String) = assertAddonCanBeInstalled(addonName) + fun selectAllowInPrivateBrowsing(activityTestRule: ActivityTestRule) { + registerAddonInstallingIdlingResource(activityTestRule) + onView(withId(R.id.allow_in_private_browsing)).click() + unregisterAddonInstallingIdlingResource(activityTestRule) + } + class Transition { fun goBack(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { fun goBackButton() = onView(allOf(withContentDescription("Navigate up"))) @@ -80,7 +96,7 @@ class SettingsSubMenuAddonsManagerRobot { addonName: String, interact: SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.() -> Unit ): SettingsSubMenuAddonsManagerAddonDetailedMenuRobot.Transition { - addonName.chars() + scrollToElementByText(addonName) onView( allOf( @@ -125,7 +141,7 @@ class SettingsSubMenuAddonsManagerRobot { .check(matches(not(isCompletelyDisplayed()))) } - private fun assertAddonPrompt(addonName: String) { + private fun assertAddonPermissionPrompt(addonName: String) { onView(allOf(withId(R.id.title), withText("Add $addonName?"))) .check(matches(isCompletelyDisplayed())) @@ -144,7 +160,7 @@ class SettingsSubMenuAddonsManagerRobot { .check(matches(isCompletelyDisplayed())) } - private fun assertDownloadingAddonPrompt( + private fun assertAddonInstallCompletePrompt( addonName: String, activityTestRule: ActivityTestRule ) { @@ -163,10 +179,6 @@ class SettingsSubMenuAddonsManagerRobot { .perform(click()) unregisterAddonInstallingIdlingResource(activityTestRule) - - TestHelper.scrollToElementByText(addonName) - - assertAddonIsInstalled(addonName) } private fun assertAddonIsInstalled(addonName: String) { @@ -185,7 +197,7 @@ class SettingsSubMenuAddonsManagerRobot { .perform(click()) } - private fun allowInstall() { + private fun allowPermissionToInstall() { onView(allOf(withId(R.id.allow_button), withText("Add"))) .check(matches(isCompletelyDisplayed())) .perform(click()) @@ -201,11 +213,6 @@ class SettingsSubMenuAddonsManagerRobot { .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } - private fun assertEnabledTitleDisplayed() { - onView(withText("Enabled")) - .check(matches(isCompletelyDisplayed())) - } - private fun assertAddons() { assertAddonUblock() } @@ -231,6 +238,7 @@ class SettingsSubMenuAddonsManagerRobot { } private fun assertAddonCanBeInstalled(addonName: String) { + scrollToElementByText(addonName) device.waitNotNull(Until.findObject(By.text(addonName)), waitingTime) onView( @@ -248,3 +256,8 @@ class SettingsSubMenuAddonsManagerRobot { ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } } + +fun addonsMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { + SettingsSubMenuAddonsManagerRobot().interact() + return SettingsSubMenuAddonsManagerRobot.Transition() +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index de29fc5c658a..3d59d07081e8 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -114,6 +114,17 @@ class ThreeDotMenuMainRobot { onView(withId(R.id.share_tab_url)).check(matches(isDisplayed())) } + fun openAddonsSubList() { + // when there are add-ons installed, there is an overflow Add-ons sub-menu + // in that case we use this method instead or before openAddonsManagerMenu() + clickAddonsManagerButton() + } + + fun verifyAddonAvailableInMainMenu(addonName: String) { + onView(withText(addonName)) + .check(matches(isDisplayed())) + } + class Transition { private val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) @@ -329,9 +340,6 @@ class ThreeDotMenuMainRobot { fun openAddonsManagerMenu(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition { clickAddonsManagerButton() - mDevice.findObject( - UiSelector().text("Recommended") - ).waitForExists(waitingTime) SettingsSubMenuAddonsManagerRobot().interact() return SettingsSubMenuAddonsManagerRobot.Transition()