From 2e45244b6c61e27e7365404f8dbc58acf86900c4 Mon Sep 17 00:00:00 2001 From: TejaswiKarasani Date: Thu, 7 May 2020 20:15:48 +0530 Subject: [PATCH] no issue: Added settings_privacy_items_test (#10474) --- .../mozilla/fenix/ui/SettingsPrivacyTest.kt | 134 ++++++++---- .../mozilla/fenix/ui/robots/SettingsRobot.kt | 73 ++++++- .../SettingsSubMenuDataCollectionRobot.kt | 89 ++++++++ ...ngsSubMenuDeleteBrowsingDataOnQuitRobot.kt | 107 +++++++++ .../SettingsSubMenuDeleteBrowsingDataRobot.kt | 161 ++++++++++++++ ...hancedTrackingProtectionExceptionsRobot.kt | 39 +++- ...sSubMenuEnhancedTrackingProtectionRobot.kt | 118 +++++++--- .../SettingsSubMenuPrivateBrowsingRobot.kt | 33 ++- ...ttingsSubMenuSitePermissionsCommonRobot.kt | 144 +++++++++++++ ...gsSubMenuSitePermissionsExceptionsRobot.kt | 53 +++++ .../SettingsSubMenuSitePermissionsRobot.kt | 203 ++++++++++++++++++ 11 files changed, 1060 insertions(+), 94 deletions(-) create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsExceptionsRobot.kt create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsRobot.kt diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt index 8acb98431..ff0cfd9af 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsPrivacyTest.kt @@ -54,63 +54,105 @@ class SettingsPrivacyTest { @Test // Walks through settings privacy menu and sub-menus to ensure all items are present fun settingsPrivacyItemsTest() { - // Open 3dot (main) menu - // Select settings - // Verify header: "Privacy" - - // Verify item: "Tracking Protection" and default value: "On" - // Verify item: "Tracking Protection" and default value: "On" - - // Verify item: "Logins" - - // Verify item: "Site Permissions" - // Click on: "Site permissions" - // Verify sub-menu items... - // Verify item: Exceptions - // Verify item: header: "Permissions" - // Verify item: "Camera" and default value: "ask to allow" - // Verify item: "Location" and default value: "ask to allow" - // Verify item: "Microphone" and default value: "ask to allow" - // Verify item: "Notification" and default value: "ask to allow" - - // Verify item: "Delete browsing data" - // Click on: "Delete browsing data" - // Verify sub-menu items... - // Verify item: "Open tabs" - // Verify item" tabs - // Verify item: "Browsing history and site data" - // Verify item"
addresses - // Verify item: "Collections - // Verify item" collections - // Verify item button: "Delete browsing data" - - // Verify item: "Data collection" - // Click on: "Data collection" - // Verify sub-menu items... - // Verify header: "Usage and technical data" - // Verify description: "Shares performance, usage, hardware and customization data about your browser with Mozilla to help us make Firefox Preview better" - // Verify item: toggle default value: 'on' - - // Verify item: "Privacy notice" - // Verify item: "Leak Canary" and default toggle value: "Off" - homeScreen { }.openThreeDotMenu { }.openSettings { - // PRIVACY verifyPrivacyHeading() + + // PRIVATE BROWSING + verifyPrivateBrowsingButton() + }.openPrivateBrowsingSubMenu { + verifyNavigationToolBarHeader() + }.goBack { + + // ENHANCED TRACKING PROTECTION verifyEnhancedTrackingProtectionButton() verifyEnhancedTrackingProtectionValue("On") - // Logins - verifyLoginsButton() - // drill down to submenu - verifyPrivateBrowsingButton() + }.openEnhancedTrackingProtectionSubMenu { + verifyNavigationToolBarHeader() + verifyEnhancedTrackingProtectionProtectionSubMenuItems() + + // ENHANCED TRACKING PROTECTION EXCEPTION + }.openExceptions { + verifyNavigationToolBarHeader() + verifyEnhancedTrackingProtectionProtectionExceptionsSubMenuItems() + }.goBack { + }.goBack { + + // SITE PERMISSIONS verifySitePermissionsButton() - // drill down on search + }.openSettingsSubMenuSitePermissions { + verifyNavigationToolBarHeader() + verifySitePermissionsSubMenuItems() + + // SITE PERMISSIONS AUTOPLAY + }.openAutoPlay { + verifyNavigationToolBarHeader("Autoplay") + verifySitePermissionsAutoPlaySubMenuItems() + }.goBack { + + // SITE PERMISSIONS CAMERA + }.openCamera { + verifyNavigationToolBarHeader("Camera") + verifySitePermissionsCommonSubMenuItems() + verifyToggleNameToON("3. Toggle Camera to ON") + }.goBack { + + // SITE PERMISSIONS LOCATION + }.openLocation { + verifyNavigationToolBarHeader("Location") + verifySitePermissionsCommonSubMenuItems() + verifyToggleNameToON("3. Toggle Location to ON") + }.goBack { + + // SITE PERMISSIONS MICROPHONE + }.openMicrophone { + verifyNavigationToolBarHeader("Microphone") + verifySitePermissionsCommonSubMenuItems() + verifyToggleNameToON("3. Toggle Microphone to ON") + }.goBack { + + // SITE PERMISSIONS NOTIFICATION + }.openNotification { + verifyNavigationToolBarHeader("Notification") + verifySitePermissionsNotificationSubMenuItems() + }.goBack { + + // SITE PERMISSIONS EXCEPTIONS + }.openExceptions { + verifyNavigationToolBarHeader() + verifySitePermissionsExceptionSubMenuItems() + }.goBack { + }.goBack { + + // DELETE BROWSING DATA verifyDeleteBrowsingDataButton() + }.openSettingsSubMenuDeleteBrowsingData { + verifyNavigationToolBarHeader() + verifyDeleteBrowsingDataSubMenuItems() + }.goBack { + + // DELETE BROWSING DATA ON QUIT verifyDeleteBrowsingDataOnQuitButton() + verifyDeleteBrowsingDataOnQuitValue("Off") + }.openSettingsSubMenuDeleteBrowsingDataOnQuit { + verifyNavigationToolBarHeader() + verifyDeleteBrowsingDataOnQuitSubMenuItems() + }.goBack { + + // DATA COLLECTION verifyDataCollectionButton() + }.openSettingsSubMenuDataCollection { + verifyNavigationToolBarHeader() + verifyDataCollectionSubMenuItems() + }.goBack { + + // OPEN LINKS IN APPS + verifyOpenLinksInAppsButton() + verifyOpenLinksInAppsSwitchDefault() + }.goBack { + verifyHomeComponent() } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt index 7db88955a..7db6e059f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsRobot.kt @@ -32,6 +32,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.helpers.Constants.PackageName.GOOGLE_PLAY_SERVICES import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText +import org.mozilla.fenix.helpers.assertIsEnabled import org.mozilla.fenix.helpers.click /** @@ -55,19 +56,22 @@ class SettingsRobot { fun verifyLoginsButton() = assertLoginsButton() fun verifyEnhancedTrackingProtectionValue(state: String) = assertEnhancedTrackingProtectionValue(state) - fun verifyPrivateBrowsingButton() = assertPrivateBrowsingButton() fun verifySitePermissionsButton() = assertSitePermissionsButton() fun verifyDeleteBrowsingDataButton() = assertDeleteBrowsingDataButton() fun verifyDeleteBrowsingDataOnQuitButton() = assertDeleteBrowsingDataOnQuitButton() + fun verifyDeleteBrowsingDataOnQuitValue(state: String) = + assertDeleteBrowsingDataValue(state) fun verifyDataCollectionButton() = assertDataCollectionButton() - fun verifyLeakCanaryButton() = assertLeakCanaryButton() + fun verifyOpenLinksInAppsButton() = assertOpenLinksInAppsButton() + fun verifyOpenLinksInAppsSwitchDefault() = assertOpenLinksInAppsValue() fun verifySettingsView() = assertSettingsView() // ADVANCED SECTION fun verifyAdvancedHeading() = assertAdvancedHeading() fun verifyAddons() = assertAddons() fun verifyRemoteDebug() = assertRemoteDebug() + fun verifyLeakCanaryButton() = assertLeakCanaryButton() // ABOUT SECTION fun verifyAboutHeading() = assertAboutHeading() @@ -167,6 +171,42 @@ class SettingsRobot { SettingsSubMenuPrivateBrowsingRobot().interact() return SettingsSubMenuPrivateBrowsingRobot.Transition() } + + fun openSettingsSubMenuSitePermissions(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition { + scrollToElementByText("Site permissions") + fun sitePermissionButton() = mDevice.findObject(textContains("Site permissions")) + sitePermissionButton().click() + + SettingsSubMenuSitePermissionsRobot().interact() + return SettingsSubMenuSitePermissionsRobot.Transition() + } + + fun openSettingsSubMenuDeleteBrowsingData(interact: SettingsSubMenuDeleteBrowsingDataRobot.() -> Unit): SettingsSubMenuDeleteBrowsingDataRobot.Transition { + scrollToElementByText("Delete browsing data") + fun deleteBrowsingDataButton() = mDevice.findObject(textContains("Delete browsing data")) + deleteBrowsingDataButton().click() + + SettingsSubMenuDeleteBrowsingDataRobot().interact() + return SettingsSubMenuDeleteBrowsingDataRobot.Transition() + } + + fun openSettingsSubMenuDeleteBrowsingDataOnQuit(interact: SettingsSubMenuDeleteBrowsingDataOnQuitRobot.() -> Unit): SettingsSubMenuDeleteBrowsingDataOnQuitRobot.Transition { + scrollToElementByText("Delete browsing data on quit") + fun deleteBrowsingDataOnQuitButton() = mDevice.findObject(textContains("Delete browsing data on quit")) + deleteBrowsingDataOnQuitButton().click() + + SettingsSubMenuDeleteBrowsingDataOnQuitRobot().interact() + return SettingsSubMenuDeleteBrowsingDataOnQuitRobot.Transition() + } + + fun openSettingsSubMenuDataCollection(interact: SettingsSubMenuDataCollectionRobot.() -> Unit): SettingsSubMenuDataCollectionRobot.Transition { + scrollToElementByText("Data collection") + fun dataCollectionButton() = mDevice.findObject(textContains("Data collection")) + dataCollectionButton().click() + + SettingsSubMenuDataCollectionRobot().interact() + return SettingsSubMenuDataCollectionRobot.Transition() + } } } @@ -252,13 +292,26 @@ private fun assertDeleteBrowsingDataOnQuitButton() { .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } +private fun assertDeleteBrowsingDataValue(state: String) { + mDevice.wait(Until.findObject(By.text("Delete browsing data on quit")), waitingTime) + onView(withText(state)).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + private fun assertDataCollectionButton() = onView(withText("Data collection")) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun assertLeakCanaryButton() { - scrollToElementByText("LeakCanary") - onView(withText("LeakCanary")) - .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +private fun openLinksInAppsButton() = onView(withText("Open links in apps")) + +private fun assertOpenLinksInAppsButton() = openLinksInAppsButton() + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertOpenLinksInAppsValue() = openLinksInAppsButton() + .assertIsEnabled(isEnabled = true) + +// DEVELOPER TOOLS SECTION +private fun assertDeveloperToolsHeading() { + scrollToElementByText("Developer tools") + onView(withText("Developer tools")) } // ADVANCED SECTION @@ -280,6 +333,12 @@ private fun assertRemoteDebug() { .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } +private fun assertLeakCanaryButton() { + scrollToElementByText("LeakCanary") + onView(withText("LeakCanary")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + // ABOUT SECTION private fun assertAboutHeading(): ViewInteraction { scrollToElementByText("About") @@ -299,7 +358,7 @@ private fun assertAboutFirefoxPreview(): ViewInteraction { .check(matches(isCompletelyDisplayed())) } -fun swipeToBottom() = onView(ViewMatchers.withId(R.id.recycler_view)).perform(ViewActions.swipeUp()) +fun swipeToBottom() = onView(withId(R.id.recycler_view)).perform(ViewActions.swipeUp()) fun clickRateButtonGooglePlay() { assertRateOnGooglePlay().click() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt new file mode 100644 index 000000000..8fd2d9259 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDataCollectionRobot.kt @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withParent +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.assertIsEnabled +import org.mozilla.fenix.helpers.click + +/** + * Implementation of Robot Pattern for the settings Data Collection sub menu. + */ +class SettingsSubMenuDataCollectionRobot { + + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + + fun verifyDataCollectionOptions() = assertDataCollectionOptions() + + fun verifyUsageAndTechnicalDataSwitchDefault() = assertUsageAndTechnicalDataSwitchDefault() + + fun verifyMarketingDataSwitchDefault() = assertMarketingDataValueSwitchDefault() + + fun verifyDataCollectionSubMenuItems() { + verifyDataCollectionOptions() + verifyUsageAndTechnicalDataSwitchDefault() + verifyMarketingDataSwitchDefault() + } + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + goBackButton().click() + + SettingsRobot().interact() + return SettingsRobot.Transition() + } + } +} + +private fun goBackButton() = + onView(withContentDescription("Navigate up")) + +private fun assertNavigationToolBarHeader() = onView( + allOf(withParent(withId(R.id.navigationToolbar)), + withText(R.string.preferences_data_collection))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertDataCollectionOptions() { + + onView(withText(R.string.preference_usage_data)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val usageAndTechnicalDataText = + "Shares performance, usage, hardware and customization data about your browser with Mozilla to help us make Firefox Preview better" + + onView(withText(usageAndTechnicalDataText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_marketing_data)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val marketingDataText = + "Shares data about what features you use in Firefox Preview with Leanplum, our mobile marketing vendor." + + onView(withText(marketingDataText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun usageAndTechnicalDataButton() = onView(withText(R.string.preference_usage_data)) + +private fun assertUsageAndTechnicalDataSwitchDefault() = usageAndTechnicalDataButton() + .assertIsEnabled(isEnabled = true) + +private fun marketingDataButton() = onView(withText(R.string.preferences_marketing_data)) + +private fun assertMarketingDataValueSwitchDefault() = marketingDataButton() + .assertIsEnabled(isEnabled = true) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt new file mode 100644 index 000000000..ddc265b00 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataOnQuitRobot.kt @@ -0,0 +1,107 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withChild +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withParentIndex +import androidx.test.espresso.matcher.ViewMatchers.withResourceName +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.isChecked + +/** + * Implementation of Robot Pattern for the settings Delete Browsing Data On Quit sub menu. + */ +class SettingsSubMenuDeleteBrowsingDataOnQuitRobot { + + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + + fun verifyDeleteBrowsingOnQuitButton() = assertDeleteBrowsingOnQuitButton() + + fun verifyDeleteBrowsingOnQuitButtonSummary() = assertDeleteBrowsingOnQuitButtonSummary() + + fun verifyDeleteBrowsingOnQuitButtonSwitchDefault() = assertDeleteBrowsingOnQuitButtonSwitchDefault() + + fun clickDeleteBrowsingOnQuitButtonSwitchDefaultChange() = verifyDeleteBrowsingOnQuitButtonSwitchDefault().click() + + fun verifyAllTheCheckBoxesText() = assertAllTheCheckBoxesText() + + fun verifyAllTheCheckBoxesChecked() = assertAllTheCheckBoxesChecked() + + fun verifyDeleteBrowsingDataOnQuitSubMenuItems() { + verifyDeleteBrowsingOnQuitButton() + verifyDeleteBrowsingOnQuitButtonSummary() + verifyDeleteBrowsingOnQuitButtonSwitchDefault() + clickDeleteBrowsingOnQuitButtonSwitchDefaultChange() + verifyAllTheCheckBoxesText() + verifyAllTheCheckBoxesChecked() + } + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + goBackButton().click() + + SettingsRobot().interact() + return SettingsRobot.Transition() + } + } +} + +private fun goBackButton() = onView(withContentDescription("Navigate up")) + +private fun assertNavigationToolBarHeader() = onView(allOf(withId(R.id.navigationToolbar), + withChild(withText(R.string.preferences_delete_browsing_data_on_quit)))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun deleteBrowsingOnQuitButton() = onView(allOf(withParentIndex(0), + withChild(withText(R.string.preferences_delete_browsing_data_on_quit)))) + +private fun assertDeleteBrowsingOnQuitButton() = deleteBrowsingOnQuitButton() + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertDeleteBrowsingOnQuitButtonSummary() = onView( + withText(R.string.preference_summary_delete_browsing_data_on_quit_2)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertDeleteBrowsingOnQuitButtonSwitchDefault() = onView(withResourceName("switch_widget")) + .check(matches(isChecked(false))) + +private fun assertAllTheCheckBoxesText() { + onView(withText(R.string.preferences_delete_browsing_data_tabs_title)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_on_quit_browsing_history)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cookies)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cookies_subtitle)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cached_files)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cached_files_subtitle)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_site_permissions)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun assertAllTheCheckBoxesChecked() { + // Only verifying the options, checkboxes default value can't be verified due to issue #9471 +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt new file mode 100644 index 000000000..645ea2da7 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuDeleteBrowsingDataRobot.kt @@ -0,0 +1,161 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.RootMatchers.isDialog +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.hasSibling +import androidx.test.espresso.matcher.ViewMatchers.withChild +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.assertIsChecked +import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.TestAssetHelper + +/** + * Implementation of Robot Pattern for the settings Delete Browsing Data sub menu. + */ +class SettingsSubMenuDeleteBrowsingDataRobot { + + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + + fun verifyDeleteBrowsingDataButton() = assertDeleteBrowsingDataButton() + + fun verifyClickDeleteBrowsingDataButton() = assertClickDeleteBrowsingDataButton() + + fun verifyMessageInDialogBox() = assertMessageInDialogBox() + + fun verifyDeleteButtonInDialogBox() = assertDeleteButtonInDialogBox() + + fun verifyCancelButtonInDialogBox() = assertCancelButtonInDialogBox() + + fun verifyAllTheCheckBoxesText() = assertAllTheCheckBoxesText() + + fun verifyAllTheCheckBoxesChecked() = assertAllTheCheckBoxesChecked() + + fun verifyContentsInDialogBox() { + verifyMessageInDialogBox() + verifyDeleteButtonInDialogBox() + verifyCancelButtonInDialogBox() + } + + fun clickCancelButtonInDialogBoxAndVerifyContentsInDialogBox() { + mDevice.wait( + Until.findObject(By.text("Delete browsing data")), + TestAssetHelper.waitingTime + ) + verifyClickDeleteBrowsingDataButton() + verifyContentsInDialogBox() + cancelButton().click() + } + + fun verifyDeleteBrowsingDataSubMenuItems() { + verifyDeleteBrowsingDataButton() + clickCancelButtonInDialogBoxAndVerifyContentsInDialogBox() + verifyAllTheCheckBoxesText() + verifyAllTheCheckBoxesChecked() + } + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + + fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + goBackButton().click() + + SettingsRobot().interact() + return SettingsRobot.Transition() + } + } +} + +private fun goBackButton() = + onView(allOf(withContentDescription("Navigate up"))) + +private fun assertNavigationToolBarHeader() { + onView(allOf(withId(R.id.navigationToolbar), + withChild(withText(R.string.preferences_delete_browsing_data)))) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} + +private fun assertDeleteBrowsingDataButton() { + onView(withId(R.id.delete_data)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} + +private fun assertClickDeleteBrowsingDataButton() { + onView(withId(R.id.delete_data)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))).click() +} + +private fun cancelButton() = + mDevice.findObject(UiSelector().textStartsWith("CANCEL")) + +private fun assertMessageInDialogBox() = + onView(withText("Firefox Preview will delete the selected browsing data.")) + .inRoot(isDialog()) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertDeleteButtonInDialogBox() = + onView(withText("Delete")) + .inRoot(isDialog()) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertCancelButtonInDialogBox() = + onView(withText("Cancel")) + .inRoot(isDialog()) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertAllTheCheckBoxesText() { + + onView(withText(R.string.preferences_delete_browsing_data_tabs_title)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText("0 tabs")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_browsing_data_title)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText("0 addresses")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cookies)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cookies_subtitle)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cached_files)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_cached_files_subtitle)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText(R.string.preferences_delete_browsing_data_site_permissions)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun assertAllTheCheckBoxesChecked() { + onView(allOf(withId(R.id.checkbox), hasSibling(withText("Open Tabs")))).assertIsChecked(true) + + onView(allOf(withId(R.id.checkbox), hasSibling(withText("Browsing history and site data")))).assertIsChecked(true) + + onView(allOf(withId(R.id.checkbox), hasSibling(withText("Cookies")))).assertIsChecked(true) + + onView(allOf(withId(R.id.checkbox), hasSibling(withText("Cached images and files")))).assertIsChecked(true) + + onView(allOf(withId(R.id.checkbox), hasSibling(withText("Site permissions")))).assertIsChecked(true) +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.kt index a293ccde9..1a70e45d9 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.kt @@ -2,15 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -@file:Suppress("TooManyFunctions") - package org.mozilla.fenix.ui.robots -import androidx.test.espresso.Espresso -import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice -import org.hamcrest.CoreMatchers +import org.hamcrest.CoreMatchers.allOf import org.mozilla.fenix.helpers.click import org.mozilla.fenix.R @@ -19,15 +22,23 @@ import org.mozilla.fenix.R */ class SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot { + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + fun verifyDefault() = assertExceptionDefault()!! + fun verifyExceptionLearnMoreText() = assertExceptionLearnMoreText()!! + fun verifyListedURL(url: String) = assertExceptionURL(url)!! + fun verifyEnhancedTrackingProtectionProtectionExceptionsSubMenuItems() { + verifyDefault() + verifyExceptionLearnMoreText() + } + class Transition { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! fun goBack(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition { - mDevice.waitForIdle() goBackButton().click() SettingsSubMenuEnhancedTrackingProtectionRobot().interact() @@ -44,13 +55,21 @@ class SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot { } private fun goBackButton() = - Espresso.onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up"))) + onView(allOf(withContentDescription("Navigate up"))) + +private fun assertNavigationToolBarHeader() { + onView(withText(R.string.preferences_tracking_protection_exceptions)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} private fun assertExceptionDefault() = - Espresso.onView(CoreMatchers.allOf(ViewMatchers.withText("Exceptions let you disable tracking protection for selected sites."))) + onView(allOf(withText(R.string.exceptions_empty_message_description))) + +private fun assertExceptionLearnMoreText() = + onView(allOf(withText(R.string.exceptions_empty_message_learn_more_link))) private fun assertExceptionURL(url: String) = - Espresso.onView(CoreMatchers.allOf(ViewMatchers.withText(url))) + onView(allOf(withText(url))) private fun disableExceptionsButton() = - Espresso.onView(CoreMatchers.allOf(ViewMatchers.withId(R.id.removeAllExceptions))) + onView(allOf(withId(R.id.removeAllExceptions))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt index 47339578d..ad4ac835d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -@file:Suppress("TooManyFunctions") - package org.mozilla.fenix.ui.robots import androidx.preference.R @@ -11,11 +9,21 @@ import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions -import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.hasDescendant +import androidx.test.espresso.matcher.ViewMatchers.hasSibling +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withChild +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withParent +import androidx.test.espresso.matcher.ViewMatchers.withParentIndex import androidx.test.espresso.matcher.ViewMatchers.withResourceName +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice -import org.hamcrest.CoreMatchers +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.helpers.assertIsChecked import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.isChecked @@ -24,17 +32,36 @@ import org.mozilla.fenix.helpers.isChecked */ class SettingsSubMenuEnhancedTrackingProtectionRobot { + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + fun verifyEnhancedTrackingProtectionHeader() = assertEnhancedTrackingProtectionHeader() + fun verifyEnhancedTrackingProtectionHeaderDescription() = assertEnhancedTrackingProtectionHeaderDescription() + + fun verifyLearnMoreText() = assertLearnMoreText() + + fun verifyEnhancedTrackingProtectionTextWithSwitchWidget() = assertEnhancedTrackingProtectionTextWithSwitchWidget() + fun verifyEnhancedTrackingProtectionOptions() = assertEnhancedTrackingProtectionOptions() fun verifyEnhancedTrackingProtectionDefaults() = assertEnhancedTrackingProtectionDefaults() + fun verifyRadioButtonDefaults() = assertRadioButtonDefaults() + + fun verifyEnhancedTrackingProtectionProtectionSubMenuItems() { + verifyEnhancedTrackingProtectionHeader() + verifyEnhancedTrackingProtectionHeaderDescription() + verifyLearnMoreText() + verifyEnhancedTrackingProtectionTextWithSwitchWidget() + verifyEnhancedTrackingProtectionDefaults() + verifyRadioButtonDefaults() + verifyEnhancedTrackingProtectionOptions() + } + class Transition { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { - mDevice.waitForIdle() goBackButton().click() SettingsRobot().interact() @@ -45,9 +72,9 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { interact: SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.() -> Unit ): SettingsSubMenuEnhancedTrackingProtectionExceptionsRobot.Transition { - onView(ViewMatchers.withId(R.id.recycler_view)).perform( + onView(withId(R.id.recycler_view)).perform( RecyclerViewActions.scrollTo( - ViewMatchers.hasDescendant(ViewMatchers.withText("Exceptions")) + hasDescendant(withText("Exceptions")) ) ) @@ -59,31 +86,59 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { } } +private fun assertNavigationToolBarHeader() { + onView(allOf(withParent(withId(org.mozilla.fenix.R.id.navigationToolbar)), + withText("Enhanced Tracking Protection"))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + private fun assertEnhancedTrackingProtectionHeader() { - onView(ViewMatchers.withText("Browse without being followed")) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + onView(withText("Browse without being followed")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun assertEnhancedTrackingProtectionHeaderDescription() { + onView(allOf(withParent(withParentIndex(0)), + withText("Keep your data to yourself. Firefox Preview protects you from many of the most common trackers that follow what you do online."))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun assertLearnMoreText() { + onView(allOf(withParent(withParentIndex(0)), + withText("Learn more"))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} + +private fun assertEnhancedTrackingProtectionTextWithSwitchWidget() { + onView(allOf( + withParentIndex(1), + withChild(withText("Enhanced Tracking Protection")))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } private fun assertEnhancedTrackingProtectionOptions() { - onView(ViewMatchers.withText("Standard")) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - val stdText = "Pages will load normally, but block fewer trackers." - onView(ViewMatchers.withText(stdText)) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + onView(withText("Standard")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val stdText = "Pages will load normally, but block fewer trackers." + onView(withText(stdText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText("Strict (Default)")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - onView(ViewMatchers.withText("Strict (Default)")) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) val strictText = "Stronger tracking protection and faster performance, but some sites may not work properly." - onView(ViewMatchers.withText(strictText)) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + onView(withText(strictText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText("Custom")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - onView(ViewMatchers.withText("Custom")) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) val customText = "Choose which trackers and scripts to block" - onView(ViewMatchers.withText(customText)) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + onView(withText(customText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } private fun assertEnhancedTrackingProtectionDefaults() { @@ -96,13 +151,28 @@ private fun assertEnhancedTrackingProtectionDefaults() { ) } +private fun assertRadioButtonDefaults() { + onView(withText("Standard") + ).assertIsChecked(false) + + onView( + allOf( + withId(org.mozilla.fenix.R.id.radio_button), + hasSibling(withText("Strict (Default)")) + ) + ).assertIsChecked(true) + + onView(withText("Custom") + ).assertIsChecked(false) +} + fun settingsSubMenuEnhancedTrackingProtection(interact: SettingsSubMenuEnhancedTrackingProtectionRobot.() -> Unit): SettingsSubMenuEnhancedTrackingProtectionRobot.Transition { SettingsSubMenuEnhancedTrackingProtectionRobot().interact() return SettingsSubMenuEnhancedTrackingProtectionRobot.Transition() } private fun goBackButton() = - onView(CoreMatchers.allOf(ViewMatchers.withContentDescription("Navigate up"))) + onView(allOf(withContentDescription("Navigate up"))) private fun openExceptions() = - onView(CoreMatchers.allOf(ViewMatchers.withText("Exceptions"))) + onView(allOf(withText("Exceptions"))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt index dfd0d9959..624f6b453 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt @@ -1,13 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + package org.mozilla.fenix.ui.robots import android.os.Build import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers -import androidx.test.espresso.matcher.ViewMatchers.isEnabled +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withChild import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By @@ -15,10 +20,13 @@ import androidx.test.uiautomator.By.text import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until +import org.hamcrest.CoreMatchers import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue +import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.isEnabled /** * Implementation of Robot Pattern for the settings PrivateBrowsing sub menu. @@ -26,6 +34,8 @@ import org.mozilla.fenix.helpers.click class SettingsSubMenuPrivateBrowsingRobot { + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + fun verifyOpenLinksInPrivateTab() = assertOpenLinksInPrivateTab() fun verifyAddPrivateBrowsingShortcutButton() = assertAddPrivateBrowsingShortcutButton() @@ -54,7 +64,6 @@ class SettingsSubMenuPrivateBrowsingRobot { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { - mDevice.waitForIdle() goBackButton().perform(ViewActions.click()) SettingsRobot().interact() @@ -70,6 +79,16 @@ class SettingsSubMenuPrivateBrowsingRobot { } } +private fun assertNavigationToolBarHeader() { + onView( + CoreMatchers.allOf( + withId(R.id.navigationToolbar), + withChild(withText(R.string.preferences_private_browsing_options)) + ) + ) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} + private fun openLinksInPrivateTabSwitch() = onView(withText("Open links in a private tab")) @@ -88,21 +107,21 @@ private fun assertAddPrivateBrowsingShortcutButton() { waitingTime ) addPrivateBrowsingShortcutButton() - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } private fun assertOpenLinksInPrivateTab() { openLinksInPrivateTabSwitch() - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } private fun assertOpenLinksInPrivateTabEnabled() = - openLinksInPrivateTabSwitch().check(matches(isEnabled())) + openLinksInPrivateTabSwitch().check(matches(isEnabled(true))) private fun assertOpenLinksInPrivateTabOff() { assertFalse(mDevice.findObject(UiSelector().resourceId("android:id/switch_widget")).isChecked()) openLinksInPrivateTabSwitch() - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) } private fun assertPrivateBrowsingShortcutIcon() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt new file mode 100644 index 000000000..c6f6d039f --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt @@ -0,0 +1,144 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.assertIsChecked +import org.mozilla.fenix.helpers.click + +/** + * Implementation of Robot Pattern for the settings Site Permissions sub menu. + */ +class SettingsSubMenuSitePermissionsCommonRobot { + + fun verifyNavigationToolBarHeader(header: String) = assertNavigationToolBarHeader(header) + + fun verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() = assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() + + fun verifyBlockAudioOnly() = assertBlockAudioOnly() + + fun verifyVideoAndAudioBlockedRecommended() = assertVideoAndAudioBlockedRecommended() + + fun verifyCheckAutoPlayRadioButtonDefault() = assertCheckAutoPayRadioButtonDefault() + + fun verifyassertAskToAllowRecommended() = assertAskToAllowRecommended() + + fun verifyassertBlocked() = assertBlocked() + + fun verifyCheckCommonRadioButtonDefault() = assertCheckCommonRadioButtonDefault() + + fun verifyBlockedByAndroid() = assertBlockedByAndroid() + + fun verifyToAllowIt() = assertToAllowIt() + + fun verifyGotoAndroidSettings() = assertGotoAndroidSettings() + + fun verifyTapPermissions() = assertTapPermissions() + + fun verifyToggleNameToON(name: String) = assertToggleNameToON(name) + + fun verifyGoToSettingsButton() = assertGoToSettingsButton() + + fun verifySitePermissionsAutoPlaySubMenuItems() { + verifyBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() + verifyBlockAudioOnly() + verifyVideoAndAudioBlockedRecommended() + verifyCheckAutoPlayRadioButtonDefault() + } + + fun verifySitePermissionsCommonSubMenuItems() { + verifyassertAskToAllowRecommended() + verifyassertBlocked() + verifyCheckCommonRadioButtonDefault() + verifyBlockedByAndroid() + verifyToAllowIt() + verifyGotoAndroidSettings() + verifyTapPermissions() + verifyGoToSettingsButton() + } + + fun verifySitePermissionsNotificationSubMenuItems() { + verifyassertAskToAllowRecommended() + verifyassertBlocked() + verifyCheckCommonRadioButtonDefault() + } + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + + fun goBack(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition { + goBackButton().click() + + SettingsSubMenuSitePermissionsRobot().interact() + return SettingsSubMenuSitePermissionsRobot.Transition() + } + } +} + +private fun assertNavigationToolBarHeader(header: String) = onView(allOf(withContentDescription(header))) + +private fun assertBlockAudioAndVideoOnMobileDataOnlyAudioAndVideoWillPlayOnWiFi() = + onView(withId(R.id.block_radio)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) + +private fun assertBlockAudioOnly() = onView(withId(R.id.third_radio)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) + +private fun assertVideoAndAudioBlockedRecommended() = onView(withId(R.id.fourth_radio)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) + +private fun assertCheckAutoPayRadioButtonDefault() { + + onView(withId(R.id.block_radio)) + .assertIsChecked(isChecked = false) + + onView(withId(R.id.third_radio)) + .assertIsChecked(isChecked = false) + + onView(withId(R.id.fourth_radio)) + .assertIsChecked(isChecked = true) +} + +private fun assertAskToAllowRecommended() = onView(withId(R.id.ask_to_allow_radio)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) + +private fun assertBlocked() = onView(withId(R.id.block_radio)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) + +private fun assertCheckCommonRadioButtonDefault() { + onView(withId(R.id.ask_to_allow_radio)).assertIsChecked(isChecked = true) + onView(withId(R.id.block_radio)).assertIsChecked(isChecked = false) +} + +private fun assertBlockedByAndroid() = onView(withText(R.string.phone_feature_blocked_by_android)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertToAllowIt() = onView(withText(R.string.phone_feature_blocked_intro)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertGotoAndroidSettings() = onView(withText(R.string.phone_feature_blocked_step_settings)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertTapPermissions() = onView(withText("2. Tap Permissions")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertToggleNameToON(name: String) = onView(withText(name)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun assertGoToSettingsButton() = onView(withId(R.id.settings_button)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + +private fun goBackButton() = + onView(allOf(withContentDescription("Navigate up"))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsExceptionsRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsExceptionsRobot.kt new file mode 100644 index 000000000..bac8a0c91 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsExceptionsRobot.kt @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.click + +/** + * Implementation of Robot Pattern for the settings Site Permissions Notification sub menu. + */ +class SettingsSubMenuSitePermissionsExceptionsRobot { + + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + + fun verifyExceptionDefault() = assertExceptionDefault()!! + + fun verifySitePermissionsExceptionSubMenuItems() { + verifyExceptionDefault() + } + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + + fun goBack(interact: SettingsSubMenuSitePermissionsRobot.() -> Unit): SettingsSubMenuSitePermissionsRobot.Transition { + goBackButton().click() + + SettingsSubMenuSitePermissionsRobot().interact() + return SettingsSubMenuSitePermissionsRobot.Transition() + } + } +} + +private fun goBackButton() = + onView(allOf(withContentDescription("Navigate up"))) + +private fun assertNavigationToolBarHeader() { + onView(withText(R.string.preference_exceptions)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} + +private fun assertExceptionDefault() = + onView(allOf(withText(R.string.no_site_exceptions))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsRobot.kt new file mode 100644 index 000000000..da14f4c99 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsRobot.kt @@ -0,0 +1,203 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ui.robots + +import androidx.preference.R +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.contrib.RecyclerViewActions +import androidx.test.espresso.matcher.ViewMatchers.hasDescendant +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.helpers.click + +/** + * Implementation of Robot Pattern for the settings Site Permissions sub menu. + */ +class SettingsSubMenuSitePermissionsRobot { + + fun verifyNavigationToolBarHeader() = assertNavigationToolBarHeader() + + fun verifySitePermissionsSubMenuItems() = assertSitePermissionsSubMenuItems() + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + fun goBack(interact: SettingsRobot.() -> Unit): SettingsRobot.Transition { + goBackButton().click() + + SettingsRobot().interact() + return SettingsRobot.Transition() + } + + fun openAutoPlay( + interact: SettingsSubMenuSitePermissionsCommonRobot.() -> Unit + ): SettingsSubMenuSitePermissionsCommonRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Autoplay")) + ) + ) + + openAutoPlay().click() + + SettingsSubMenuSitePermissionsCommonRobot().interact() + return SettingsSubMenuSitePermissionsCommonRobot.Transition() + } + + fun openCamera( + interact: SettingsSubMenuSitePermissionsCommonRobot.() -> Unit + ): SettingsSubMenuSitePermissionsCommonRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Camera")) + ) + ) + + openCamera().click() + + SettingsSubMenuSitePermissionsCommonRobot().interact() + return SettingsSubMenuSitePermissionsCommonRobot.Transition() + } + + fun openLocation( + interact: SettingsSubMenuSitePermissionsCommonRobot.() -> Unit + ): SettingsSubMenuSitePermissionsCommonRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Location")) + ) + ) + + openLocation().click() + + SettingsSubMenuSitePermissionsCommonRobot().interact() + return SettingsSubMenuSitePermissionsCommonRobot.Transition() + } + + fun openMicrophone( + interact: SettingsSubMenuSitePermissionsCommonRobot.() -> Unit + ): SettingsSubMenuSitePermissionsCommonRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Microphone")) + ) + ) + + openMicrophone().click() + + SettingsSubMenuSitePermissionsCommonRobot().interact() + return SettingsSubMenuSitePermissionsCommonRobot.Transition() + } + + fun openNotification( + interact: SettingsSubMenuSitePermissionsCommonRobot.() -> Unit + ): SettingsSubMenuSitePermissionsCommonRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Notification")) + ) + ) + + openNotification().click() + + SettingsSubMenuSitePermissionsCommonRobot().interact() + return SettingsSubMenuSitePermissionsCommonRobot.Transition() + } + + fun openExceptions( + interact: SettingsSubMenuSitePermissionsExceptionsRobot.() -> Unit + ): SettingsSubMenuSitePermissionsExceptionsRobot.Transition { + + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + hasDescendant(withText("Exceptions")) + ) + ) + + openExceptions().click() + + SettingsSubMenuSitePermissionsExceptionsRobot().interact() + return SettingsSubMenuSitePermissionsExceptionsRobot.Transition() + } + } + + private fun assertNavigationToolBarHeader() = onView(withText("Site permissions")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + private fun assertSitePermissionsSubMenuItems() { + + onView(withText("Autoplay")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val autoplayText = "Block audio and video" + onView(withText(autoplayText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val cameraText = + "Blocked by Android" + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + allOf(hasDescendant(withText("Camera")), hasDescendant(withText(cameraText))) + ) + ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val locationText = + "Blocked by Android" + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + allOf(hasDescendant(withText("Location")), hasDescendant(withText(locationText))) + ) + ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val microphoneText = + "Blocked by Android" + onView(withId(R.id.recycler_view)).perform( + RecyclerViewActions.scrollTo( + allOf(hasDescendant(withText("Microphone")), hasDescendant(withText(microphoneText))) + ) + ).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + onView(withText("Notification")) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + + val notificationText = + "Ask to allow" + onView(withText(notificationText)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + } +} + +private fun goBackButton() = + onView(withContentDescription("Navigate up")) + +private fun openAutoPlay() = + onView(allOf(withText("Autoplay"))) + +private fun openCamera() = + onView(allOf(withText("Camera"))) + +private fun openLocation() = + onView(allOf(withText("Location"))) + +private fun openMicrophone() = + onView(allOf(withText("Microphone"))) + +private fun openNotification() = + onView(allOf(withText("Notification"))) + +private fun openExceptions() = + onView(allOf(withText("Exceptions")))